【问题标题】:Sending arguments to an app-instance that resides in another process向驻留在另一个进程中的应用程序实例发送参数
【发布时间】:2011-04-02 12:36:54
【问题描述】:

我有一个单实例应用程序(c#、WPF、.net3.51)。检查应用程序是否已经实例化是通过互斥锁完成的。如果应用程序已经在运行,我会从已经打开的应用程序实例中打开一个新窗口。到目前为止,这工作正常。

但是由于应用程序扩展,我现在必须将 e.Args(或至少它的第一个字符串)发送到驻留在另一个进程中的已运行实例。如何做到最好?

其他信息
目前我使用一个全局注册的窗口消息,我通过 PostMessage (HWND_BROADCAST) 发送给所有打开的应用程序。如果收到此消息,我的应用程序会查找此消息并打开一个新窗口。一个想法是设置 PostMessage 的参数。但是我发现了很多关于这个话题的令人眼花缭乱的信息,因此我没有勇气走这条路。除此之外,我还想通过另一个激活逻辑来替换全局 PostMessage 调用,因为全局调用似乎有一些令人讨厌的副作用。

【问题讨论】:

    标签: c# .net wpf winapi ipc


    【解决方案1】:

    您可以使用在 .NET 3.5 中添加到 BCL 的命名管道。

    在已经运行的实例中创建命名管道服务器(参数接收器),并在副本应用程序中创建命名管道客户端(参数发送器)。然后,将参数从客户端发送到服务器。

    如果需要,可以在 C/C++ 中创建命名管道的任一端。请参阅 Win32 CreateNamedPipe 函数。

    下面是一个简单的例子,客户端和服务器都在一个程序中运行(下面的“FD1AF2B4...”GUID 只是一个唯一标识符,以避免与系统上已经存在的命名管道发生冲突)。

    class Program
    {
        static void Main(string[] args)
        {
            Thread writerThread = new Thread(new ThreadStart(WriterThread));
            writerThread.Start();
    
            Thread readerThread = new Thread(new ThreadStart(ReaderThread));
            readerThread.Start();
        }
    
        static void ReaderThread()
        {
            NamedPipeServerStream server = new NamedPipeServerStream("FD1AF2B4-575A-46E0-8DF5-8AB368CF6645");
            server.WaitForConnection();
    
            using (var reader = new BinaryReader(server))
            {
                string arguments = reader.ReadString();
                Console.WriteLine("Received: {0}", arguments);
            }
        }
    
        static void WriterThread()
        {
            NamedPipeClientStream client = new NamedPipeClientStream("FD1AF2B4-575A-46E0-8DF5-8AB368CF6645");
            client.Connect(Timeout.Infinite);
    
            using (var writer = new BinaryWriter(client))
            {
                writer.Write("/foo /bar:33 /baz:quux");
            }
        }
    }
    

    【讨论】:

    • 获得[assembly: Guid] 属性值比硬编码某人更好
    • 我猜命名管道和套接字只是两个可靠的解决方案,但是,我更喜欢命名管道,你能告诉我你为什么说“矫枉过正”,命名管道有什么问题吗?我只是出于好奇而问,否则你的答案是完美的。
    • @Akash:我想“矫枉过正”是矫枉过正 :) 是的,它会可靠地工作。我想我想说的是,这似乎是很多代码,只是为了将字符串从一个应用程序发送到另一个应用程序。不过,它肯定比使用原始 Win32 API 更好!我更新了我的回复以删除“矫枉过正”。
    • 感谢您的回复,我觉得 Win32 发送消息在不同的工作站和不同的登录以及非 UI 环境中都不起作用,但是名称管道在任何地方都可以工作,所以我更喜欢这样,但是如果我们想限制它只发送给一个用户,然后发送消息是更好的选择,但是两者都有相同的问题和优势。
    猜你喜欢
    • 2019-01-16
    • 2018-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多