如何独立启动EXE后获取另一进程的目标对象?
能否在两个进程中使用同一对象?
核心结论
不能直接在两个独立进程中使用同一个对象实例——每个进程都有自己独立的内存空间,对象实例仅存在于所属进程的内存中,跨进程无法直接访问或共享。
你的场景分析
当前你是在特定应用的进程内通过DLL加载EXE程序集并创建Form实例(相当于把EXE的UI运行在当前进程里),所以能直接传递对象;但如果要让EXE作为独立进程单独启动,这种方式就失效了,需要针对性调整。
解决方案分两种情况
情况1:允许EXE在特定应用进程内运行(保持现有程序集加载方式)
这种情况下可以继续复用进程内对象传递的逻辑,只需修改EXE和DLL的代码,实现“EXE先启动(对象为null),等特定应用启动后再注入对象”:
- 修改EXE的Form1代码,添加一个设置对象的方法:
public class Form1 : Form { public object serverModule { get; set; } // 新增方法用于后续设置对象 public void InitializeServerModule(object module) { serverModule = module; // 这里可以添加对象初始化后的业务逻辑,比如绑定数据、启动服务等 } }
- 修改DLL代码,在特定应用启动完成后,找到已打开的Form实例并调用设置方法:
// 保存Form实例的引用(需要确保全局可访问,比如作为类成员) Form newForm; static BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance; // 原启动EXE的逻辑(先打开Form,此时serverModule为null) myClassSample classSample = new myClassSample(); classSample.module = module; Assembly assembly = Assembly.LoadFrom("mySample.exe"); Type formType = assembly.GetType("mySample.Form1"); Form resultForm = assembly.CreateInstance(formType.FullName) as Form; newForm = resultForm; newForm.Show(); // 特定应用启动完成后,执行以下代码注入对象 if (newForm != null) { MethodInfo initMethod = newForm.GetType().GetMethod("InitializeServerModule", flags); initMethod?.Invoke(newForm, new object[] { module }); }
情况2:必须让EXE作为独立进程运行
此时需要通过**进程间通信(IPC)**实现对象信息的传递,因为独立进程内存完全隔离。推荐几种常用方案:
- 命名管道:适合本地进程间的高效通信,支持序列化对象传递。
- JSON/文本通信:通过本地文件、套接字传递序列化后的对象文本,兼容性好。
- WCF:适合复杂的跨进程/跨机器通信,支持多种协议。
以命名管道为例,给出简单实现:
- 特定应用端(发送对象):
// 特定应用启动完成后,发送对象到EXE using (var pipeClient = new NamedPipeClientStream(".", "SampleAppPipe", PipeDirection.Out)) { pipeClient.Connect(5000); // 超时时间5秒 // 推荐用Newtonsoft.Json或System.Text.Json序列化,替代BinaryFormatter(有安全风险) var json = JsonConvert.SerializeObject(module); var writer = new StreamWriter(pipeClient); writer.Write(json); writer.Flush(); }
- EXE端(接收对象):
public class Form1 : Form { public object serverModule { get; set; } public Form1() { InitializeComponent(); // 启动后台线程监听管道 Task.Run(() => ListenForModule()); } private void ListenForModule() { while (true) { try { using (var pipeServer = new NamedPipeServerStream("SampleAppPipe", PipeDirection.In)) { pipeServer.WaitForConnection(); var reader = new StreamReader(pipeServer); var json = reader.ReadToEnd(); // 反序列化对象 serverModule = JsonConvert.DeserializeObject(json); // 回到主线程更新UI或执行逻辑 this.Invoke((Action)(() => { // 这里写对象初始化后的操作 })); } } catch (Exception ex) { // 处理异常,比如管道断开后重试 Thread.Sleep(1000); } } } }
总结
如果不需要EXE作为独立进程,用进程内方法调用的方式最简单;如果必须独立运行,就选适合的IPC方案实现对象信息的跨进程传递。
内容的提问来源于stack exchange,提问作者Parker Shiung
相关产品推荐
相关产品推荐

