C++调用外部exe时CreateProcess无法传递参数的问题排查
问题核心原因
你遇到的参数传递失败是CreateProcess接口的两个特性导致的:
lpCommandLine参数要求传入可写的字符串缓冲区,你直接传入的_T("172.30.4.1:diskspace:c")是只读的字符串字面量,CreateProcess内部会修改这个字符串完成参数解析,写入只读内存会触发未定义行为,直接导致参数解析失败。- 如果你同时指定了
lpApplicationName(第一个参数)和lpCommandLine(第二个参数),系统不会自动把程序路径作为argv[0]填充到命令行中。常规C/C++程序读取参数是从argv[1]开始取用户参数,你当前的命令行内容没有预留argv[0]的位置,子进程读取到的argc为1,自然拿不到有效参数。
修复方案
方案1:构造完整可写命令行
把程序路径作为第一个参数加入命令行,并存放到可写的数组缓冲区中:
STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); ZeroMemory(&pi, sizeof(pi)); // 构造完整命令行,第一个参数为程序自身路径,第二个为业务参数 TCHAR cmdLine[] = _T("C:\\Stats-Server.exe 172.30.4.1:diskspace:c"); if (!CreateProcess(_T("C:\\Stats-Server.exe"), cmdLine, // 传入可写缓冲区,不要直接用字符串字面量 NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi) ) { printf("CreateProcess failed (%d).\n", GetLastError()); return 0; } WaitForSingleObject(pi.hProcess, INFINITE); CloseHandle(pi.hProcess); CloseHandle(pi.hThread);
方案2:简化写法(更推荐)
把lpApplicationName设为NULL,直接把完整命令行传入第二个参数,系统会自动解析第一个参数作为启动路径,不容易出错:
TCHAR cmdLine[] = _T("C:\\Stats-Server.exe 172.30.4.1:diskspace:c"); // 第一个参数留空,让系统从命令行解析程序路径 if (!CreateProcess(NULL, cmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
注意事项
如果程序路径包含空格,需要用引号把路径包裹起来,避免参数解析错误:
TCHAR cmdLine[] = _T("\"C:\\Program Files\\Stats-Server.exe\" 172.30.4.1:diskspace:c");
内容的提问来源于stack exchange,提问作者chris-p-tech
相关产品推荐
相关产品推荐

