c - WinAPI - 当 C :\Program file exists 时 CreateProcessW 失败

标签 c winapi createprocess

我运行以下 C 代码来创建一个进程。 exe文件位于C:\Program Files\Exes\Start\process1.exe

CreateProcessW(NULL, (char*) exePath, 
                           NULL, NULL, TRUE, 
                           flags, 
                           NULL, NULL, &startupInfo, &processInformation);

现在,某些计算机随机有一个名为 Program 的文件位于 C:\Program ,这会导致创建过程失败并出现错误:

%1 is not a valid Win32 application.

除了重命名文件之外,还有其他方法可以解决此问题吗?因为有几十个 Windows 虚拟机在其上执行此 C 代码。此错误随机发生在几台机器上。

最佳答案

这段代码是如何编译的?第二个参数为CreateProcessW被定义为LPWSTR,这意味着它应该只接受宽字符串。

下一个问题:由于转换的结果,无法确定 exePath 的源是什么。造成这种情况的原因是,第二个参数被定义为 LPWSTR,而不是 LPCWSTR(即 const 宽字符串)。原因:CreateProcessW可能会写入缓冲区。

然后第三个问题 - 你的exe路径中有一个空格。当作为第二个参数 (lpCommandLine) 传递时,CreateProcess 有一些 derpy 逻辑来猜测 exe 名称结束和命令行开始的位置。这需要对命令行的 exe 路径部分进行引用编码。

当您拥有 exe 的完整路径且没有参数时,最简单/最安全的做法是将其作为 lpApplicationName 参数传递。这是一个 const 参数,它避免了如果命令行源是常量字符串文字等可能导致的任何潜在的未定义行为。并且仅用作要执行的 exe 的路径,因此没有(也不能)有任何引用要求。

    CreateProcess(exePath,NULL,...);
<小时/>

旁白:使用 CreateProcess 的两个参数本质上可以让您将启动的应用程序的 argv[0] 设置为您想要的任何内容。因此,您可以从特定路径/exe 名称运行应用程序,但使 argv[0] 指向其他路径或 exe 名称。

要将参数传递给 exe,而不是传递完整(带引号的)路径,您可以执行以下简单操作:

    WCHAR cmdLine[] = TEXT("console1.exe --version");
    CreateProcessW(exePath,cmdLine,...);
<小时/>

编辑 感谢 Paul Sanders 和其他评论指出了未引用的 exe 路径,也使我完全打破了我原来的答案,该答案在我没有意识到的情况下解决了这个问题。 感谢 RbMm 发现我破坏了我的答案,感谢 eryksun 向我表明近 20 年来我一直在错误地阅读文档。

关于c - WinAPI - 当 C :\Program file exists 时 CreateProcessW 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51237567/

相关文章:

c - Gstreamer:无法同时从 alsasrc 收听音频和录音?

c - 重新声明全局变量与局部变量

c - pow(1,0) 返回 0?

c++ - 在提取 SFX 存档时显示进度条

performance - CreateProcess 的快速替代方案

c++ - 如何从用户应用程序向 SYSTEM 应用程序发送自定义消息?

c - 如何在静态库中存储版本号?

C++ winapi ListView NM_CUSTOMDRAW : not getting CDDS_ITEMPREPAINT

c++ - Win32 C++ 在运行时为 MenuItem 分配/更改快捷键

c - 获取由 CreateProcess() 启动的进程的 PID