在单独的控制台和Windows应用程序之间传递信息

时间:2014-07-14 07:31:28

标签: c# winforms progress-bar console-application ipc

我有两个独立的程序,一个是控制台应用程序,另一个是Windows应用程序。

我的Windows应用程序:

  • 具有图形界面,按钮和其他功能。
  • 其中一个名为" research"的按钮:当我点击它时,我用这行代码启动控制台应用程序:

    string strResult = ProcessHelper.LaunchProcessWaitForPipedResult("MyExecFile.exe", strArguments, 10 * 60 * 1000, true);   // 10 mins max
    

我的控制台应用程序:

  • 对目录中的所有现有文件进行查询。

我的问题:

我想在Windows应用程序上创建一个进度条,以显示控制台应用程序的进度。问题是我不知道如何在这两个进程之间传递这些信息。唯一的限制是不使用数据库或文件。

1 个答案:

答案 0 :(得分:2)

鉴于同一用户会话中有两个进程,并且希望避免在该会话之外进行任何通信,我会看三个选项:

1。使用命名管道。

父进程使用随机名称创建命名管道(并通过打开它来确认该名称未被使用)。它将该名称传递给子进程。使用一个简单的协议,允许孩子发送更新。

要克服许多挑战:

  • 获取逻辑以确保名称是唯一的(命名管道名称是全局的)。
  • 确保没有其他进程可以连接(默认命名管道ACL限制与会话的连接:此可能就足够了。)
  • 处理不同父进程不支持进度更新的情况。
  • 处理儿童或父母崩溃。
  • 避免过于聪明的通信协议,但允许增长的空间(当需要的不仅仅是简单的进度条时会发生什么?)

2。使用共享内存

在这种情况下,对象的名称默认情况下是会话的本地名称。默认情况下,这更安全。

父进程创建了足够大量的共享内存(用于简单的进度更新:不多),互斥锁和事件。

然后,当GUI进入互斥锁并读取共享内存的内容时,父进程与GUI同时等待事件发出信号。然后它取消设置事件并离开互斥锁。

与此同时,为了发送更新,孩子会在离开互斥锁之前进入互斥锁,更新和内存并设置事件。

这里的挑战包括:

  • 定义共享内存的布局。如果没有共享程序集,则可能容易出错。
  • 使用共享内存和同步对象避免其他人。 .NET让事情变得更难:在Win32中我会使句柄继承,因此不需要命名对象(调试除外)并直接传递给子。
  • 获取共享内存,互斥和事件正确的排序至关重要。内存损坏和更微妙的错误等待任何错误。
  • 使用共享内存进行可变长度数据更难,不是简单进度计数的问题,但客户总是想要更多。

摘要

我可能会首先查看命名管道(或者如果我想要更大的灵活性,可能是自定义WMI类型)。 但是 我会在尝试所有内容后首先避免需要多个进程。一个共享库以及其他人的控制台包装器,而我直接使用该库将是一个更容易的选择。