WinAPI-当C:\ Program文件存在时,CreateProcessW失败

时间:2018-07-09 02:28:05

标签: c winapi createprocess

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

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

现在,某些计算机在C:\ Program中随机拥有一个名为Program的文件,这会导致创建过程失败并显示以下错误:

  

%1不是有效的Win32应用程序。

除了重命名文件之外,还有一种方法可以解决此问题,因为有几十个Windows Vms可以在其上执行C代码。此错误在几台计算机上随机发生。

2 个答案:

答案 0 :(得分:5)

此代码甚至如何编译? CreateProcessW的第二个参数定义为LPWSTR,这意味着它只能接受宽字符串。

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

然后是第三个问题-您的exe路径中有空格。当作为第二个参数(lpCommandLine)传递时,CreateProcessW具有一些令人毛骨悚然的逻辑,可以猜测exe名称在哪里结束并且命令行开始。这需要用引号对命令行的exe路径部分进行编码。

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

CreateProcess

此外:将两个参数都用于 CreateProcess(exePath,NULL,...); ,实际上可以将启动的应用程序的argv [0]设置为所需的任何值。因此,您可以从特定路径/ exe名称运行应用程序,但使argv [0]指向其他路径或exe名称。

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

CreateProcess

编辑归功于Paul Sanders和其他评论,他们指出了未引用的exe路径,这也使我完全打破了原来的答案,但我没有意识到却解决了这个问题。 感谢RbMm发现了我的答案,并感谢eryksun向我展示了我将近20年来一直在阅读错误的文档。

答案 1 :(得分:3)

Chris在这里提出了很多要点,您应该加以考虑,但是正如immibis所说,真正的问题是您错误地使用了CreateProcess API。完成此操作的方式要求exepath被引号(如果它包含任何空格)。

因此,相反,在解决了Chris提出的所有问题之后,请执行以下操作:

CreateProcessW (exePath, NULL,
                NULL, NULL, TRUE, 
                creation_flags, 
                NULL, NULL, &startupInfo, &processInformation);

即只需交换第一个和第二个参数即可(也许像我在这里所做的那样,对flags使用更具描述性的名称)。

您可以在第二个参数中传递您可能需要的任何命令行参数(如果有必要的话)。并且,请read the docs


编辑(找回我的代表:)

此外,正如克里斯所说,exepath在这里必须是一个宽字符串,因此我取出了您的(多余的)强制类型转换,实际上这会生成编译器错误(C ++)或警告(C)(因此,警告,请猜,由于您的帖子被标记为C,谢谢@Barmak。

无论如何,如果您现在一无所获,那么exepath实际上必须已经很宽了,所以一切都很好。如果不是,那么您显然需要解决此问题,但是我想这整个问题只是您帖子中的一个错字,因为您清楚地 did 使您的代码正常工作以报告您所观察到的行为。< / p>