You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何独立启动EXE后获取另一进程的目标对象?

能否在两个进程中使用同一对象?

核心结论

不能直接在两个独立进程中使用同一个对象实例——每个进程都有自己独立的内存空间,对象实例仅存在于所属进程的内存中,跨进程无法直接访问或共享。

你的场景分析

当前你是在特定应用的进程内通过DLL加载EXE程序集并创建Form实例(相当于把EXE的UI运行在当前进程里),所以能直接传递对象;但如果要让EXE作为独立进程单独启动,这种方式就失效了,需要针对性调整。

解决方案分两种情况

情况1:允许EXE在特定应用进程内运行(保持现有程序集加载方式)

这种情况下可以继续复用进程内对象传递的逻辑,只需修改EXE和DLL的代码,实现“EXE先启动(对象为null),等特定应用启动后再注入对象”:

  1. 修改EXE的Form1代码,添加一个设置对象的方法:
public class Form1 : Form
{
    public object serverModule { get; set; }

    // 新增方法用于后续设置对象
    public void InitializeServerModule(object module)
    {
        serverModule = module;
        // 这里可以添加对象初始化后的业务逻辑,比如绑定数据、启动服务等
    }
}
  1. 修改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:适合复杂的跨进程/跨机器通信,支持多种协议。

以命名管道为例,给出简单实现:

  1. 特定应用端(发送对象):
// 特定应用启动完成后,发送对象到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();
}
  1. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 01:01:23