所以,我在Windows机器上运行了一小段C代码,内容如下:
/* invoke command */
impl->procHandle = _spawnve(_P_NOWAIT, command, vargs, env);
if (impl->procHandle == -1) {
printf("Failed to invoke command: %s\n", strerror(errno));
impl->busy = false;
}
printf("VICTORY\n");
我在这附近编写了一些单元测试,我的“命令”是C:\ windows \ system32 \ ipconfig.exe,它运行正常,没问题。
尝试将它用于应用程序启动器... doo doo。失败时出现有用的错误:
The application failed to initialize properly (0xc0150004).
Click on OK to terminate the application.
好的...搜索我发现错误代码是STATUS_SXS_ASSEMBLY_NOT_FOUND,当我尝试启动notepad.exe时也会发生错误代码。缺少装配?
为什么会这样?
我该如何解决它?
我只是在这里猜测,但我怀疑它与需要在_spawnve()中设置PATH变量有关,但我不知道它应该是什么。我尝试过路径,但这似乎没有帮助。运行此代码:
int offset = 0;
while (vargs[offset] != NULL) {
printf("vargs %d: %s\n", offset, vargs[offset]);
++offset;
}
offset = 0;
while (env[offset] != NULL) {
printf("env %d: %s\n", offset, env[offset]);
++offset;
}
Yeilds:
vargs 0: C:\windows\system32\notepad.exe
env 0: PATH=c:\WINDOWS\system32
即。我传入argv [0]和路径值;不是其他env变量或参数。
有什么想法吗?
-
编辑:
因此,似乎发生了此错误,因为在使用_spawnve()调用命令时未正确设置PATH。
通过调用_spawnv()或_spawnvpe()显而易见,这两者似乎都能正常工作。
然而,这对我没有帮助,因为我需要在运行时为应用程序指定一个额外的PATH组件。将PATH = ...传递给_spawnvpe()会导致相同的错误,显然没有使用_spawnv,因为它不允许您指定PATH。
实际上,这个问题的答案是:因为PATH变量是错误的。
...但我仍然不知道应该是什么。似乎没有任何可以在任何地方找到的工作示例。我将接受任何链接到使用_spawnve()或_spawnvpe()编码的示例并将PATH变量传递给它(并且正在工作)的答案。
编辑#2:
真。不,实际上,这不起作用。这是示例,它不起作用。忘记链接到一个有效的例子;只修改我的例子并发布一个差异,1)传入PATH,2)运行没有错误。
的Nb。想看看它有用吗?更改为_spawnv()或使env值为NULL并且运行正常。
#include <stdio.h>
#include <windows.h>
#include <process.h>
#include <errno.h>
int main(int argc, char *argv[]) {
char *path_value;
char buffer[4000];
const char *env[2];
const char *args[1];
char *command;
int result;
intptr_t procHandle;
path_value = getenv("PATH");
sprintf(buffer, "PATH=%s", path_value);
env[0] = buffer;
env[1] = NULL;
args[0] = NULL;
int offset = 0;
while (env[offset] != NULL) {
printf("env %d: %s\n", offset, env[offset]);
++offset;
}
offset = 0;
while (args[offset] != NULL) {
printf("arg %d: %s\n", offset, args[offset]);
++offset;
}
command = "C:\\windows\\system32\\notepad.exe";
procHandle = _spawnvpe(_P_NOWAIT, command, args, NULL);
if (procHandle == -1) {
printf("Failed to invoke command: %s\n", strerror(errno));
exit(1);
}
_cwait(&result, procHandle, 0);
if (result != 0)
printf("Command exited with error code %d\n", result);
}
输出:
env 0: PATH=.;c:\Program Files\Common Files\Microsoft Shared\Windows Live;c:\WINDOWS\system32;c:\WINDOWS;c:\WINDOWS\System32\Wbem;c:\Program Files\Microsoft SQL Server\100\Tools\Binn\;c:\Program Files\Microsoft SQL Server\100\DTS\Binn\;c:\Program Files\CMake 2.8\bin;c:\Program Files\Microsoft ASP.NET\ASP.NET Web Pages\v1.0\;c:\Program Files\Common Files\Microsoft Shared\Windows Live
Command exited with error code -1072365564
答案 0 :(得分:2)
这是错误的:
const char *args[1];
args[0] = NULL;
你需要
const char *args[2];
args[0] = "notepad";
args[1] = NULL;
除此之外,您的示例代码至少在使用Visual Studio 2010进行编译时可以正常工作。我已经在Windows 7和Windows XP上进行了测试,并且它可以正常工作。记事本运行。
您使用的是哪种编译器?
答案 1 :(得分:0)
你是对的,_ spawnev()
的第二个参数是要执行的应用名称包含其完整路径。
要了解可以调用命令处理程序cmd.exe
的路径,并使用cmd.exe
的选项{{1}将其作为参数执行传递给应用程序名称}。
这适用于您可以从/C
的一个命令行窗口启动应用程序的所有情况。
cmd.exe
知道环境变量cmd.exe
的值,并用它来搜索应用程序的启动路径。
可以从环境变量PATH
中读取cmd.exe
本身的路径。
更新:有关此问题的更多信息(包括示例),请阅读here。
答案 2 :(得分:-1)
如此处_spawn, _wspawn Functions所指定的,只有名称中带有'p'字母的函数才会隐含地使用PATH环境变量。其他人没有。
所以你需要这样做:
char *args[] = {"notepad.exe", NULL };
_spawnvpe(_P_NOWAIT, args[0], args, NULL);