【问题标题】:Can I execute code on an existing process?我可以在现有进程上执行代码吗?
【发布时间】:2015-02-18 16:52:07
【问题描述】:

我有一个应用程序在系统托盘图标中持续运行。它通过运行一些使用@Global 互斥锁的代码来确保它是我的应用程序的唯一运行实例。

由于第 3 方供应商的限制,我可以与供应商应用程序的一部分集成的唯一(理智)方法是在配置文件中指定调用任意命令行可执行文件。我关心的参数会自动添加到我指定的可执行文件中。

所以我认为大多数与此集成的人运行一个单独的程序,该程序连接到主程序上的服务器套接字并发送一个数据包让主程序知道命令行已被触发。

我想知道是否有办法可以做这个伪代码..

    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();
        }
    }

基本上,如果我通过命令行运行连接到已经运行的全局进程并传递一些数据。

我控制将成为客户端和服务器的代码,它们实际上是同一个项目。

【问题讨论】:

  • 大多数情况下禁止将行为注入另一个进程/窗口,但并非不可能,因为我们一直使用此处找到的 UITesting 命名空间:msdn.microsoft.com/en-us/library/… 还有其他方法,但正如你提到的我所知道的一切需要对过程进行处理以某种方式了解改变其行为的某些事情。特别是在 C++ 中有一组称为 IPC(进程间通信)类的类,它们完全可以满足您的需求。问题是客户端和其他 pgm。必须准备好接收消息。
  • 您编写了一个托盘图标应用程序,该应用程序需要通过命令行与您的另一个应用程序进行通信?服务器套接字与它有什么关系?究竟是什么问题?
  • 是的,这是可能的。您所需要的只是运行实例的一个众所周知的端点,它的命令行调用可以连接到该端点。有多种方法可以解决此问题;例如,您可以打开一个具有固定名称的 WCF 命名管道端点,并将此端点名称作为参数传递给您的控制台应用程序。
  • 托盘图标通过 REST api 与我们的 web 应用程序以及 COM 的第 3 方供应商解决方案进行通信。在一个地方,供应商应用程序不使用 COM,而是在单击按钮时调用预先配置的命令行语句。在一个旧程序中,这是一个糟糕的设计选择,我只需要在供应商软件中解决......我能说 90 年代是一个疯狂的时代......

标签: c# .net windows mutex interprocess


【解决方案1】:

您可以使用全局命名的互斥锁来检测您的应用是否已经在运行。

  • 如果运行将接收和管理命令的服务器。
  • 如果运行客户端并将命令发送到服务器。

然后在 localhost 上使用 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();
            }
        }
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-29
    • 2012-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多