如何从另一个 .NET 进程获取对象的句柄?
Posted
技术标签:
【中文标题】如何从另一个 .NET 进程获取对象的句柄?【英文标题】:How do I obtain a handle on an object from another .NET process? 【发布时间】:2009-10-14 20:26:11 【问题描述】:在 C# 中,我知道如何从代码中运行 .NET 可执行文件,并且还知道该可执行文件的实例是否已经在运行。我想要做的是,如果一个实例 is 已经在运行,请在另一个可执行文件的 C# 代码中获取 Foo
对象的实例。
我有一个 Windows 应用程序(例如 Outlook 的 .NET 版本)。用户可以正常使用该应用程序,但在后台运行的还有一个进程正在监视来自第三方系统的 XML 文件。
我需要的是让观察者进程启动.NET程序(如果它没有运行,或者获取一个句柄),然后在新/现有进程中的对象实例上调用方法CreateEmail
.
【问题讨论】:
您想获取已经运行的 foo.exe 进程的句柄,还是想获取 foo.exe 使用的对象的实例?你能澄清一下你想对现有流程做什么吗? 理想情况下,我想要传递给 Application.Run 的对象的句柄... 那是什么东西?您是否只想在已经运行的进程中执行一些操作?读取一些数据?如果不了解更多细节,很难提供帮助。您能否描述一下您的应用程序应该做什么? 我有一个 Windows 应用程序,对于本示例,假设它是 Outlook 的 .NET 版本。用户可以正常使用该应用程序,但在后台运行的还有一个进程正在监视来自第三方系统的 xml 文件。我需要的是 Watcher 进程在 .NET Outlook 未运行时启动它(或在运行时获取句柄),然后在新/现有进程中的对象实例上调用方法 CreateEmail。 【参考方案1】:您可以使用 .NET Remoting 在已运行的应用程序中激活对象。
查看以下示例:About .NET Remoting: Three concepts Compared and Simplified
【讨论】:
远程处理已被弃用,因为它允许进程摆弄彼此的内部结构。这很脆弱,可能会导致令人讨厌的意外(因为您无法控制外部过程对您的对象所做的事情)。更好的方法是让目标进程托管 WCF 服务:因为这是一个基于消息的接口,它将调用进程与目标进程的实现隔离(允许更改)并允许目标进程控制所做的事情到它的对象和时间(防止意外)。【参考方案2】:您为什么不直接将 FileSystemWatcher 添加到主应用程序中?那就是后台进程除了监视 XML 文件之外什么都不做。
如果这不可行,您可以使用NamedPipeServerStream
和NamedPipeClientStream
将“命令”从后台进程发送到主应用程序。当主应用程序收到此命令时,它将运行CreateEmail
方法。
【讨论】:
或者在命名管道通道上使用 WCF -- 节省在字节流级别编写您自己的协议。 从 .Net 3.5 开始,.Net 现在支持命名管道。无需编写自己的协议。 NamedPipeServerStream 和 NamedPipeClientStream 非常容易用于 IPC。几周前我写了一篇关于它的博客文章。 eclipsed4utoo.com/blog/… 认为主应用程序已签名并盖章。观察者是一个客户特定的工具,所以我不希望它集成到主源代码中。 经过一些快速测试后,似乎在命名管道通道上使用 WCF 可以满足我的需求。感谢 Eclipsed4utoo 和 itowlson 的建议!【参考方案3】:使用System.Diagnostics.Process
类。
要运行,您可以Process.Start("string path");
并列出当前正在运行的进程来执行检查。
【讨论】:
感谢您的回复,但正如我所说:“我知道如何从代码中运行 .NET 可执行文件 (foo.exe),还可以查看可执行文件的实例是否已经在运行” 您的标题是“如何启动 .NET 进程...”,所以也许应该删除它。【参考方案4】:好吧,你可以使用:
Process.GetProcessesByName(<process Name here>);
返回 Process[]。
查看 Process 类的静态方法,它们非常直观且有用。
【讨论】:
感谢您的回复,但正如我所说:“我知道如何从代码中运行 .NET 可执行文件 (foo.exe),还可以查看可执行文件的实例是否已经在运行”以上是关于如何从另一个 .NET 进程获取对象的句柄?的主要内容,如果未能解决你的问题,请参考以下文章
从没有GetWindowThreadProcessId的窗口句柄中获取进程ID(c#.net 4.0)