На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
  
> Выбор способа обмена сообщениями , Между процессами на сервере терминалов и службой
    Есть терминальный сервер Windows >= 2003.
    На нем работают н-ное кол-во пользователей, запуская каждый по одному экземпляру exe-шника.
    Это работает.
    Нужно реализовать следующее:
    -- создать службу реализующую отслеживание появление файлов в расшаренной по ftp-директории,
    изменение некоторых файлов на других ftp-серверах;
    -- все экземпляры приложения при запуске должны регистрироваться в динамическом списке службы;
    -- служба в зависимости от анализа окружающей остановки (см.выше) посылает, либо конкретному процессу, либо всем сразу
    -- в зависимости от содержания сообщения, приложение должно выполнить определенное действие, не исключенно, что должно отдать ответ службе.


    Погуглив, почитав форум, возникло мнение, что нужно смотреть в сторону .Net.Remoting.
    Но, примера переделываемого под свои нужды не нашел.

    Вводные же статьи в вышеуказанную тему, уж слишком сильно погружают во все вкусности и необозримые возможности технологии. К сожалению не обладаю, пока временным ресурсом для подробного изучения данного направления.
    Принимаю любую помощь в данном вопросе. Спасибо за беспокойство.
      Вам может подойти WCF. По-сути, таже обертка на Remoting...

      Если ни с чем этим возиться не хочется, то Socket's + Serialization. Описанную вами схему коммуникации реализовать не сложно, даже оперируя такими объектами как Socket и методы сериалиации.
        Спасибо.
        Правда, я решил сначала через WinAPI SendMessage.
        Но
        ExpandedWrap disabled
           Process[] allprocs = Process.GetProcessesByName("MyApp");
           if (allprocs.Length > 0)
           {                    
              bool finded = false;
              foreach (Process p in allprocs)
              {      
                 // почему-то p.MainWindowHandle == 0                
                 // соответственно следубщая строка, ничего не делала
                 SendMessage(p.MainWindowHandle, RF_RSERVICEMESSAGE,
                             (IntPtr)(byte)'\0', IntPtr.Zero);
           
              }                      
           }


        Я так и не понял, почему p.MainWindowHandle == 0, и перешел к сокетам.


        передача сообщения в приложение
        ExpandedWrap disabled
           private void callMyApp(string user, string commander, string localFile, string options)
                  {
                      
                      //get all running instances
                      try
                      {
                          //#((MyService)Program.ServicesToRun[0]).AddLog(String.Format("Отладка. Сообщение [{0}]. Получаем список процессов", msgfile));
                          Process[] allprocs = Process.GetProcessesByName("MyApp");
                          if (allprocs.Length > 0)
                          {
                              //#((MyService)Program.ServicesToRun[0]).AddLog(String.Format("Отладка. Сообщение [{0}]. Найденно {1} процессов", msgfile, Convert.ToString(allprocs.Length)));
                              bool finded = false;
                              foreach (Process p in allprocs)
                              {
                                  //#((MyService)Program.ServicesToRun[0]).AddLog(String.Format("Отладка. Сообщение [{0}]. Перебираем процессы. Очередной {1}", msgfile, Convert.ToString(p.Id)));
           
                                  if (NTTools.GetProcessUserName(p).Trim().ToLower() ==
                                       user.Trim().ToLower())
                                  {
                                      finded = true;
           
                                      //#((MyService)Program.ServicesToRun[0]).AddLog(String.Format("Отладка. Сообщение [{0}]. Нашли", msgfile));
                                      
           
                                      Hashtable htable = new Hashtable();
                                      htable.Add("commander", commander);
                                      htable.Add("localfile", localFile);
                                      htable.Add("options", options);
                                      string mess = Text.TagTable(htable);
           
                                      //#((MyService)Program.ServicesToRun[0]).AddLog(String.Format("Отладка. Сообщение [{0}]. Собрали строку {1}", msgfile,mess));
                                      
                                      //=============================
                                      //
                                      // Неудачный опыт с WinAPI-собщениями
                                      //
                                      //string status;
                                      /*
                                      ((MyService)Program.ServicesToRun[0]).AddLog(String.Format("Отладка. Сообщение [{0}]. Текст сообщения приложению: [{1}]", msgfile, mess));
                                      ((MyService)Program.ServicesToRun[0]).AddLog(String.Format("Отладка. Сообщение [{0}]. MW_HADLE: [{1}] HANDLE: [{2}]", new string[] { msgfile, Convert.ToString(p.MainWindowHandle), Convert.ToString(p.Handle) }));
                                      foreach (char ch in mess)
                                      {
                                          SendMessage(p.MainWindowHandle, RF_MyServiceMESSAGE,
                                          (IntPtr)(byte)ch, IntPtr.Zero);
                    
                                          //#((MyService)Program.ServicesToRun[0]).AddLog(String.Format("Отладка. Сообщение [{0}]. Результат отпрваки сообщения приложению [{1}] ", status));
                                      }
                                      SendMessage(p.MainWindowHandle, RF_MyServiceMESSAGE,
                                          (IntPtr)(byte)'\0', IntPtr.Zero);
                
                                      ((MyService)Program.ServicesToRun[0]).AddLog(String.Format("Отладка. Сообщение [{0}]. Сообщения приложению отправленно ", msgfile));
                                      //#((MyService)Program.ServicesToRun[0]).AddLog(String.Format("Отладка. Сообщение [{0}]. Результат отпрваки сообщения приложению [{1}] ", status));
                                      */
                                      //=============================
           
                                      IPEndPoint me = new IPEndPoint(IPAddress.Loopback, 0);
                                      IPEndPoint app = new IPEndPoint(IPAddress.Loopback, 37000 + p.Id);
                                      TcpClient tcp = new TcpClient(me);
                                      //#((MyService)Program.ServicesToRun[0]).AddLog(String.Format("Отладка. Сообщение [{0}].  Клиент объявлен", msgfile));
                                      Socket sock = tcp.Client;
                                      //#((MyService)Program.ServicesToRun[0]).AddLog(String.Format("Отладка. Сообщение [{0}].  Клиент создан", msgfile));
                                      sock.Connect(app);
                                      //#((MyService)Program.ServicesToRun[0]).AddLog(String.Format("Отладка. Сообщение [{0}].  соединились", msgfile));
                                      sock.Send(Encoding.ASCII.GetBytes(mess));
                                      //#((MyService)Program.ServicesToRun[0]).AddLog(String.Format("Отладка. Сообщение [{0}].  отправили", msgfile));
                                      byte[] buf = new byte[1];
                                      sock.Receive(buf);
                                      //#((MyService)Program.ServicesToRun[0]).AddLog(String.Format("Отладка. Сообщение [{0}].  приняли", msgfile));
                                      sock.Shutdown(SocketShutdown.Both);
                                      sock.Close();
                                      tcp.Close();
                                      //#((MyService)Program.ServicesToRun[0]).AddLog(String.Format("Отладка. Сообщение [{0}].  позакрывали", msgfile));
           
           
                                      //=============================
                                  }
                              }
                              if (!finded)
                                  ((MyService)Program.ServicesToRun[0]).AddLog(String.Format("При обработке сообщения [{0}], не удалось найти процесс приложения запущенный пользователем {1} ", msgfile, user), System.Diagnostics.EventLogEntryType.Error);
                          }
                          else
                          {
                              ((MyService)Program.ServicesToRun[0]).AddLog(String.Format("При обработке сообщения [{0}], не удалось найти ни одного процесса приложения", msgfile), System.Diagnostics.EventLogEntryType.Error);
                          }
                      }
                      catch (Exception ex)
                      {
                          ((MyService)Program.ServicesToRun[0]).AddLog(String.Format("При обработке сообщения [{0}], ошибка [{1}] при отправке сообщения пользователю {2}", new string[]{msgfile, ex.Message
                              + ex.StackTrace,user }), System.Diagnostics.EventLogEntryType.Error);
                      }
                      
                      
                  }


        В приложение создал класс-оболочку потока прослушивающего сокет

        ExpandedWrap disabled
           class MainBack
              {
                  /// <summary>
                  /// Основной поток
                  /// </summary>
                  private Thread thread;
           
                  /// <summary>
                  /// Слушатель tcp
                  /// </summary>
                  TcpListener tcp;
                  /// <summary>
                  /// Сокет
                  /// </summary>
                  Socket sock;
           
                  /// <summary>
                  /// Остановка основного потока
                  /// </summary>
                  public void Abort()
                  {
                      try
                      {
                          tcp.Stop();
                          sock.Shutdown(SocketShutdown.Both);
                          sock.Close();
                          tcp.Stop();
                      }
                      catch
                      {
                          //#MessageBox.Show("ой, как поломалось-то");
                      }
                      thread.Abort();
                  }
           
                  public MainBack()
                  {
                      thread = new Thread(main);
           
                      thread.IsBackground = true;
                      thread.Start();
                  }
           
                  private void main()
                  {
           
           
                      IPEndPoint me = new IPEndPoint(IPAddress.Loopback, 37000 + Process.GetCurrentProcess().Id);
                      tcp = new TcpListener(me);
                      sock = tcp.Server;
                      //#MessageBox.Show("установки сделаны");
                      try
                      {
                          sock.Bind(me);
                          sock.Listen(1);
                          //#MessageBox.Show("начали слушать");
                          while (true)
                          {
                              Socket curr = sock.Accept();
                              //#MessageBox.Show("кто к нам долбится");
                              IList<ArraySegment<byte>> rec = new List<ArraySegment<byte>>();
           
                              do
                              {
                                  byte[] ar = new byte[1024];
                                  ArraySegment<byte> seg = new ArraySegment<byte>(ar);
                                  rec.Add(seg);
                              } while (curr.Receive(rec) >= 1024);
           
                              //#MessageBox.Show("мы что-то при приняли");
                              string buf = null;
                              foreach (ArraySegment<byte> n in rec)
                              {
                                  buf += Encoding.ASCII.GetString((byte[])n.Array);
                              }
                              //#MessageBox.Show("собрали строку");
                              curr.Send(new byte[] { (byte)'\0' });
                              //#MessageBox.Show("ответили черт знает что");
                              curr.Shutdown(SocketShutdown.Both);
                              curr.Close();
                              //#MessageBox.Show("отключили сокет");
           
                              if (buf != null)
                              {
                                  //#MessageBox.Show("начнем обработку");
                                  Hashtable htable = new Hashtable();
                                  if (Rating.Text.ParseTag(buf, htable) == null)
                                  {
                                      //#MessageBox.Show("распарсили нормально");
                                      if (htable.ContainsKey("commander") &&
                                          (((string)htable["commander"]).ToUpper() == "ACCESS"))
                                      {
                                          //#MessageBox.Show("Акцес, кто бы сомневался");
                                          if (htable.ContainsKey("localfile"))
                                          {
                                              //#MessageBox.Show("ну файло название имеется");
                                              Process p = null;
                                              string arg = htable.ContainsKey("options") ?
                                                  "\"" + clsUser.UserPath + @"\WRC\REPORTS\" +  
                                                  (string)htable["localfile"] + "\"  " +
                                                  (string)htable["options"] : String.Empty;
           
                                              fmain f = Application.OpenForms.OfType<fmain>().First();
                                              //#MessageBox.Show("запускаем");
                                              f.RunAccess(@"WRC\REPORTS\"+(string)htable["localfile"], ref p, arg, fmain.RefreshTypes.AllwaysRefresh);
                                              //#MessageBox.Show("запустили");
                                          }
                                      }
                                  }
                              }
           
                          }
           
           
                      }
                      catch (Exception ex)
                      {
                          MessageBox.Show(ex.Message);
                          //#MessageBox.Show("что-то поломалось");
                          try
                          {
                              tcp.Stop();
                              sock.Shutdown(SocketShutdown.Both);
                              sock.Close();
                              tcp.Stop();
                          }
                          catch
                          {
                              //#MessageBox.Show("ой, как поломалось-то");
                          }
                          Thread.Sleep(1000);
                          main();
                      }
           
                  }
              }
        0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
        0 пользователей:


        Рейтинг@Mail.ru
        [ Script execution time: 0,0266 ]   [ 17 queries used ]   [ Generated: 25.04.24, 12:27 GMT ]