【问题标题】:Passing Information Between Applications in C#在 C# 中的应用程序之间传递信息
【发布时间】:2012-11-24 10:10:57
【问题描述】:

全部。首先,我知道Send data back to .exe from dll 的问题,但是那里的答案给我留下了太多的开放式结局,因为我对我正在尝试的东西没有经验,所以我觉得有必要提出一个新问题。

我有一个严重依赖 SQL 的现有 C# [All WinForms] 应用程序。 (客户)要求我们提供一个 SQL 编辑器和库,可用于开发和测试 SQL,但也可用于直接粘贴回主应用程序。新的 SQLEditor 是一个解析和执行 TSQL 的多线程应用程序。我现在有一些事情要考虑;从主应用程序启动第二个应用程序的最佳方式是什么::

  1. 将第二个应用程序制作成 DLL 并加载到主项目中,将第二个应用程序作为新表单调用(SqlEditor sqlEd = new SqlEditor() 等)?线程轰炸的含义是什么,我需要[STAThread] - 因为我希望两个多线程应用程序同时可用和活动。

  2. 要作为独立于主应用程序的 .exe 启动?

取决于您的建议;在上述任何一种情况下 - 我可以将信息从第二个应用程序中的点击事件传递回主应用程序的最佳方式是什么,而它们仍然在运行和处于活动状态 [WCF,ApplicationDomains 等]? Observer design pattern会进来玩吗?

为了让这个问题更有吸引力,这里是 SQL 编辑器:

我打算有一个按钮,将选定的 SQL 粘贴回主应用程序。

我也知道这里有多个问题 - 对此我深表歉意。非常感谢您的宝贵时间。

【问题讨论】:

  • @slugster 感谢您的编辑。万事如意...
  • 没有问题,这是一个很小的编辑。查看named pipes,看看是否符合您的需求。这不是一种解耦的方法,但它非常灵活。
  • namedpipes 方法(对我而言)看起来是解决此问题的更好方法,而不是 WindowsMessages 和 Interop。但是,从我目前所读的内容来看 - 当您不知道何时发送数据时,我看不到读取发送数据的清晰方法。显然没有要听的事件——你能在这方面提供和建议吗?再次感谢...

标签: c# winforms dll communication


【解决方案1】:

如果您需要一种简单的方法来执行两个 WinForms 应用程序的 outproc 通信,那么为什么不使用自定义格式的 Clipboard

在源应用程序中:

    // copy the data to the clipboard in a custom format
    Clipboard.SetData( "custom", "foo" );

在目标应用程序中,创建一个用于查看剪贴板的计时器:

    private void timer1_Tick( object sender, EventArgs e )
    {
        // peek the data of a custom type
        object o = Clipboard.GetData( "custom" );
        if ( o != null )
        {
            // do whatever you want with the data
            textBox1.Text = o.ToString();
            // clear the clipboard
            Clipboard.Clear();
        }
    }

这应该符合您的需求,而且它仍然非常简单,因为它不需要任何重量级的 outproc 通信机制。

【讨论】:

  • 感谢您的回复。在最好的情况下,我使用剪贴板的经验一直很糟糕,所以我不愿意采用这种方法。我也不确定是否需要,因为必须有执行此类操作的标准方法。再次感谢您的宝贵时间...
【解决方案2】:

实现应用内通信的另一种方法是使用 Windows 消息。您定义一个全局 Windows 消息 ID 并使用 Windows API 调用,例如 SendMessage 和 PostMessage。

这是一篇简单的文章,解释了如何: Ryan Farley's article "Communication between applications via Windows Messages"

这实际上是观察者模式,接收所有指向当前窗口的 Windows 消息并挑选出您正在监听的消息。

根据我的经验,这绝对没有剪贴板方法那么不稳定。

【讨论】:

    【解决方案3】:

    对于 IPC(进程间通信),您有多种选择,例如: Mailslot、NamedPipe、内存映射文件、套接字、Windows 消息、COM 对象、远程处理、WCF... http://msdn.microsoft.com/en-us/library/windows/desktop/aa365574(v=vs.85).aspx http://en.wikipedia.org/wiki/Inter-process_communication

    其中一些提供双向通信,一些需要考虑系统安全性(防病毒和防火墙限制,您需要在其设置中将应用程序添加为例外)。

    通过WM_COPYDATA发送消息只能通过SendMessage来完成,不支持PostMessage,表示通信是同步的。

    使用 outproc 单例 COM 对象是另一种方式,它不像其他方式和应用程序那么简单。必须在相同的安全上下文中运行才能访问相同的 COM 对象。

    启动一个单独的应用程序可能会限制您可以传递的通信方式或数据类型,但将它们分开也可以保护它们免受故障(应用程序崩溃不会关闭另一个应用程序)。

    如果这两个部分总是在同一台 PC 上运行,使用其中一个作为 dll[inproc] 会更简单。使用其他技术,如 Socket、Remoting、WCF 将为您提供更大的通信灵活性,即这两个部分只需稍作修改即可在不同的 PC 上运行...

    【讨论】:

    • 感谢您的回复。 “其中一些提供双向通信”您能否在答案中说明哪些是因为这正是我所需要的。感谢您的宝贵时间...
    • 没问题。文件映射、管道和套接字以老式方式提供 2way 通信(大多数事情都是你自己的,你需要在它们周围实现多个包装器以获得高级编程 API)。 COM & Remoting 提供了更现代的方法(包装器已实现!),传递对象更简单,您可以注册对象以通知更改(观察者模式)等等。使用 windows 消息传递不是一个好的选择,虽然它很简单并且你可以将它用作 2way 通信。
    • 根据您的回答,我尝试使用 WCF 的基本实现。但是,我遇到了一些困难。我发布了一个新问题stackoverflow.com/q/13765722/626442,你能解释一下this吗?再次感谢...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 2015-09-17
    • 1970-01-01
    相关资源
    最近更新 更多