c - 为什么 Windows 生成进程有时会触发错误 STATUS_SXS_ASSEMBLY_NOT_FOUND?

标签 c windows spawn

所以,我在 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;
}

产量:

vargs 0: C:\windows\system32\notepad.exe
env 0: PATH=c:\WINDOWS\system32

即。我传入 argv[0] 和一个路径值;不是其他环境变量或参数。

有什么想法吗?

--

编辑:

因此,似乎发生此错误是因为当我使用 _spawnve() 调用命令时未正确设置 PATH。

通过调用 _spawnv() 或 _spawnvpe() 可以明显看出这一点,这两个函数似乎都能正常工作。

但是,这并没有真正帮助我,因为我需要在应用程序运行时为其指定一个额外的 PATH 组件。将 PATH=... 传递到 _spawnvpe() 会导致相同的错误,并且显然 _spawnv 没有被使用,因为它不允许您指定 PATH。

实际上,这个问题的答案是:因为 PATH 变量是错误的。

...但我仍然不知道它应该是什么。我似乎在任何地方都找不到这方面的有效示例。我会接受任何链接到使用 _spawnve() 或 _spawnvpe() 进行编码并将 PATH 变量传递到其中(并工作)的示例的答案。

编辑#2:

真的。不,实际上,这不起作用。这是一个无法正常工作的示例。忘记链接到有效的示例;只需修改我的示例并发布一个差异,1)传入 PATH 并 2)运行没有错误。

铌。想看看它的效果吗?更改为 _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

最佳答案

这是错误的:

const char *args[1];
args[0] = NULL;

你需要

const char *args[2];
args[0] = "notepad";
args[1] = NULL;

除此之外,您的示例代码可以工作,至少在使用 Visual Studio 2010 编译时是这样。我已经在 Windows 7 和 Windows XP 上对其进行了测试,并且它可以工作。记事本运行。

你使用什么编译器?

关于c - 为什么 Windows 生成进程有时会触发错误 STATUS_SXS_ASSEMBLY_NOT_FOUND?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10969488/

相关文章:

c - 排序链表递归

windows - 如何处理从 Python 中的子进程返回的负数?

c++ - 如何将鼠标点击事件发送到游戏应用程序?

node.js - 将多个参数传递给从 node.js 生成的 python 脚本

c - strpbrk 函数 - C

c - 如何在 C 中使用相同的变量来表示不同的值

c - 在图形中查找线性

python : is it ok to threads read/write simultaneously to same TCP socket?

node.js - 通过 spawn 从 NodeJS 调用 python 脚本时出现段错误(核心已转储)

perl - 为什么 Perl 的 "system (' 某些命令')"与 c :\> some command? 的行为不同