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

C#中如何向已启动运行的EXE程序传入参数?

如何向已运行的EXE程序动态传入参数

嘿,我来帮你理清这个问题——你之前用的Process.StartInfo.Arguments其实只能在启动程序的时候传递命令行参数,完全没法给已经跑起来的进程发新参数哦!要给运行中的EXE传参,得用进程间通信(IPC)的办法,我给你整理几种实用的方案:

1. 给GUI程序发Windows消息

如果你的目标EXE是带界面的GUI程序,发送自定义Windows消息是个靠谱的思路:

  • 先找到目标进程的主窗口句柄(可以用Process.MainWindowHandle,或者通过窗口标题去搜)
  • 调用Windows API SendMessage,把参数打包成消息的附加数据发过去

举个C#的例子:

using System;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;

class Program
{
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

    // 自定义消息ID(得避开系统自带的消息,随便选个不冲突的就行)
    private const uint WM_MY_PARAM = 0x0400 + 100;

    static void Main()
    {
        // 找到目标进程(这里假设进程名是cmbs_tcx.exe)
        var targetProcess = Process.GetProcessesByName("cmbs_tcx").FirstOrDefault();
        if (targetProcess != null && targetProcess.MainWindowHandle != IntPtr.Zero)
        {
            // 把要传的参数转成可传递的指针
            var paramPtr = Marshal.StringToHGlobalAuto("要传递的新参数");
            SendMessage(targetProcess.MainWindowHandle, WM_MY_PARAM, IntPtr.Zero, paramPtr);
            Marshal.FreeHGlobal(paramPtr);
        }
    }
}

⚠️ 注意:这种方法要求目标程序有对应的消息处理逻辑,能接收到你发的消息并解析参数。如果是第三方程序,你可能得确认它支持这种方式,或者通过逆向找到它能响应的消息。

2. 给控制台程序用标准输入传参

如果目标程序是控制台程序,而且支持从标准输入读取内容,那你可以直接通过Process.StandardInput给它发参数:
不过要注意,启动进程的时候得改几个设置——UseShellExecute要设为false,还要开启RedirectStandardInput,不然拿不到输入流。比如你可以把启动代码改成这样:

var P1 = new Process();
P1.StartInfo.WorkingDirectory = @"D:\try";
P1.StartInfo.FileName = "cmbs_tcx.exe"; // 直接启动EXE,不用绕CMD
P1.StartInfo.Arguments = "-han"; // 启动时的初始参数
P1.StartInfo.UseShellExecute = false;
P1.StartInfo.CreateNoWindow = true;
P1.StartInfo.RedirectStandardInput = true; // 必须开启这个才能用StandardInput
P1.Start();

// 等程序跑起来后,动态传参
P1.StandardInput.WriteLine("你的新参数内容");
P1.StandardInput.Flush();

3. 通用方案:命名管道或套接字

如果上面两种方法都不适用,命名管道或者TCP/UDP套接字是更通用的选择。这种方式的好处是不管目标程序是GUI还是控制台都能用,但前提是目标程序得支持对应的通信协议,或者你能修改目标程序的代码来实现接收逻辑。

举个命名管道的简单例子:

  • 发送参数的客户端代码:
using System.IO.Pipes;
using System.IO;

class PipeClient
{
    static void Main()
    {
        using (var pipeClient = new NamedPipeClientStream(".", "MyCustomPipe", PipeDirection.Out))
        {
            pipeClient.Connect();
            using (var sw = new StreamWriter(pipeClient))
            {
                sw.WriteLine("要传递的参数");
                sw.Flush();
            }
        }
    }
}
  • 接收参数的目标程序(服务端)代码:
using System.IO.Pipes;
using System.IO;

class PipeServer
{
    static void Main()
    {
        using (var pipeServer = new NamedPipeServerStream("MyCustomPipe", PipeDirection.In))
        {
            pipeServer.WaitForConnection();
            using (var sr = new StreamReader(pipeServer))
            {
                var receivedParam = sr.ReadLine();
                // 这里写处理参数的逻辑
                Console.WriteLine($"收到新参数:{receivedParam}");
            }
        }
    }
}

对你现有代码的小建议

你之前通过CMD来启动EXE,还用到了&(应该是&的转义?),其实如果只是启动时传参数,直接启动EXE会更靠谱,参数传递也不容易出问题。另外UseShellExecute = true的时候,系统shell会处理参数,有时候可能会有解析错误,改成UseShellExecute = false能让参数传递更稳定。


内容的提问来源于stack exchange,提问作者Sasha777

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:43:26