2015-02-18 2 views
1

У меня есть приложение, которое запускается и непрерывно находится в значке в системном трее. Он гарантирует, что это единственный исполняемый экземпляр моего приложения, запустив некоторый код, который использует мьютекс @Global.Могу ли я выполнить код в существующем процессе?

Из-за ограничений сторонних поставщиков единственный (разумный) способ, который я могу интегрировать с одной частью приложения-поставщика, - указать в файле конфигурации, который вызывается произвольным исполняемым файлом командной строки. Параметры, которые меня волнуют, автоматически добавляются в исполняемый файл, который я указываю.

Таким образом, я думаю, что большинство людей, которые интегрировали это, запускают отдельную программу, которая подключается к серверному сокету в основной программе и отправляет пакет, позволяя основной программе знать, что запущена командная строка.

Я интересно, если есть способ, которым я мог бы сделать это псевдо-код ..

static void Main(string[] args) 
    { 
     if (isrunningcommandLine) 
     { 
      ConnectToAlreadyRunningProcessAndPassInfo(args); // find already running process by its process name and somehow pass the command line params 
      KillProgram(); 
     } 
     else 
     { 
      CheckGlobalMutexAndStart(); 
     } 
    } 

По существу, если я бег через командную строку подключение к уже запущенному глобальному процессу и передать ему некоторые данные.

Я управляю кодом, который будет как клиентом, так и сервером, они на самом деле являются одним и тем же проектом.

+0

Инъекционное поведение в другой процесс/окна в основном запрещены, но не невозможно, так как мы делаем это все время, используя пространство имен UITesting найти здесь: https://msdn.microsoft.com/en-us/library/microsoft .visualstudio.testtools.uitesting.aspx Есть и другие способы, но, поскольку вы упомянули все, что я знаю, требуют, чтобы процесс работал, чтобы каким-то образом узнать о чем-то, что изменяет его поведение. В частности, существует набор классов в C++, известный как класс IPC (Inter-Process-Communications), который делает именно то, что вы хотите. Проблема заключается как в клиентском, так и в другом pgm. должен быть готов для сообщений. –

+1

Вы написали приложение для значка в трее, которое должно связываться с другим вашим приложением через командную строку? Что такое серверный сокет? В чем именно проблема? –

+1

Да, это возможно. Все, что вам нужно, это хорошо известная конечная точка для вашего исполняемого экземпляра, к которому может подключиться вызов из командной строки. Существует несколько подходов к этому; вы можете, например, открыть WCF с именем конечной точки с фиксированным именем и передать это имя конечной точки в качестве аргумента в консольное приложение. –

ответ

1

Вы можете использовать глобальный мьютекст mutex, чтобы определить, запущено ли ваше приложение.

  • Если нет не запускать сервер, который будет получать и управлять командами.
  • Если да запустите клиента и просто отправьте команды на сервер.

Затем используйте TCP-соединение на локальном хосте для обмена сообщениями.

using System; 
    using System.Net; 
    using System.Net.Sockets; 
    using System.Text; 
    using System.Threading; 

    namespace Test42 
    { 
     internal static class Program 
     { 
      private static int PORT = 1337; 

      private static void Main() 
      { 
       bool ok; 

       // Try to build a mutex. 
       var mutex = new Mutex(true, @"Test42", out ok); 

       // If build is ok, we run as a server. 
       // Otherwise, the server is already running, so we run as a client. 
       if (ok) 
       { 
        var server = new MyServer(PORT); 
        server.Start(); 
       } 
       else 
       { 
        var r = new Random(); 
        var message = "Ho Hey : " + r.Next(50); 

        var client = new MyClient(); 
        client.Send(PORT, message); 
       } 
      } 
     } 

     internal class MyClient 
     { 
      /// <summary> 
      /// Send a message to localhost. 
      /// </summary> 
      /// <param name="port">The port to connect.</param> 
      /// <param name="message">The message to send.</param> 
      public void Send(int port, string message) 
      { 
       var client = new TcpClient(); 
       var serverEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), port); 

       client.Connect(serverEndPoint); 

       using (var stream = client.GetStream()) 
       { 
        var messageBuffer = Encoding.Unicode.GetBytes(message); 
        var lengthBuffer = BitConverter.GetBytes(messageBuffer.Length); 

        // Send message length. 
        stream.Write(lengthBuffer, 0, lengthBuffer.Length); 

        // Send message. 
        stream.Write(messageBuffer, 0, messageBuffer.Length); 

        stream.Flush(); 
       } 

       client.Close(); 
      } 
     } 

     internal class MyServer 
     { 
      private readonly int _port; 

      public MyServer(int port) 
      { 
       _port = port; 
      } 

      public void Start() 
      { 
       Console.WriteLine("wait for messages"); 
       var thread = new Thread(ThreadStart); 
       thread.Start(); 
      } 

      private void ThreadStart() 
      { 
       var listener = new TcpListener(IPAddress.Any, _port); 
       listener.Start(); 
       while (true) 
       { 
        var client = listener.AcceptTcpClient(); 
        var clientThread = new Thread(ClientThreadStart); 
        clientThread.Start(client); 
       } 
      } 

      private void ClientThreadStart(object obj) 
      { 
       var client = obj as TcpClient; 
       if (client == null) return; 

       using (var stream = client.GetStream()) 
       { 
        const int lengthLength = sizeof(int)/sizeof(byte); 

        // Read the message length. 
        var lengthBuffer = new byte[lengthLength]; 
        stream.ReadAsync(lengthBuffer, 0, lengthLength).Wait(); 
        var messageLength = BitConverter.ToInt32(lengthBuffer, 0); 

        // Read the message. 
        var messageBuffer = new byte[messageLength]; 
        stream.ReadAsync(messageBuffer, 0, messageLength).Wait(); 
        var message = Encoding.Unicode.GetString(messageBuffer); 

        Console.WriteLine("Client says: " + message); 
       } 

       client.Close(); 
      } 
     } 
    } 
Смежные вопросы