Вопрос по windows, c, spawn – Почему процесс появления Windows иногда вызывает ошибку STATUS_SXS_ASSEMBLY_NOT_FOUND?

0

Итак, у меня есть небольшой фрагмент кода на C, работающий в окне Windows, который гласит:

/* 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");

Я написал несколько модульных тестов, где моя & quot; команда & quot; был 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. Недостающие сборки?

Почему это происходит?

Как я могу обойти это?

Я простоguessing здесь, но я подозреваю, что это как-то связано с необходимостью установки переменной PATH в _spawnve (), но я не знаю, какой она должна быть. Я пытался пройти по пути, но это, похоже, не помогло. Запуск этого кода:

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 или аргументы.

Есть идеи?

--

Редактировать:

Таким образом, кажется, что эта ошибка происходит, потому что PATH не установлен правильно, когда я вызываю команду с помощью _spawnve ().

Это становится очевидным, вызывая либо _spawnv () или _spawnvpe (), оба из которых, кажется, работают правильно.

Howeverэто мне не очень помогает, потому что мне нужно указать дополнительный компонент PATH для приложения при его запуске. Передача PATH = ... в _spawnvpe () вызывает ту же ошибку, и, очевидно, _spawnv не используется, поскольку она не позволяет вам указывать PATH.

На самом деле ответ на этот вопрос таков: потому что переменная PATH неверна.

... но я до сих пор понятия не имею, что этоshould быть. Кажется, нет никаких рабочих примеров этого, которые я могу найти где-либо. Я приму любой ответ, который ссылается на пример кодирования с использованием _spawnve () или _spawnvpe () и передачи в него переменной PATH (и работает).

Изменить № 2:

В самом деле. Нет, на самом деле, это не работает. Вот этоexample это не работает. Забудьте ссылку на пример, который работает; просто измените мой пример и опубликуйте diff, который 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
Что с windows.0 в vargs [0]? У вас есть c: \ windows и c: \ windows.0? Если да, то какой из них является настоящим каталогом Windows? Кроме того, на какой версии Windows вы это тестируете? Harry Johnston
Если вы говорите о «Заявке» войдите в систему просмотра событий, тогда там ничего нет. Я запускал ошибочный код дюжину раз, и новые записи в журнале не появлялись. Если вы говорите о чем-то другом, будьте более конкретны. Doug
Работал на машине с установленными окнами в windows.0; Я перенес код на новую свежую машину под управлением XP со стандартным путем C: \ Windows \ path, и она все еще имеет ту же проблему; Я "удалил нечетные" .0 " из вопроса. Это на XP SP 3 Doug
Это может просто означать, что вашему приложению нужна некоторая DLL, которой там нет. Смотрите это на SO:stackoverflow.com/questions/1582844/… Simon Mourier
Документируйте, что вы нашли в журнале событий приложений Windows. Hans Passant

Ваш Ответ

2   ответа
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, и он работает. Блокнот работает.

Какой компилятор вы используете?

Error: User Rate Limit Exceeded Doug
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
0

spawnev() принимает имя приложения, которое будет выполненоinlcuding its full path.

Чтобы узнать путь, вы можете вызвать обработчик командcmd.exe и передать его вместе с именем приложения для выполнения в качестве параметра, используяcmd.exeопция/C.

Это работает во всех случаях, когда вы могли запустить приложение из одного изcmd.exeокна командной строки.

cmd.exe знает значение переменной средыPATH и использовал его для поиска пути запуска приложения.

Путь кcmd.exe сам может быть прочитан из переменной средыCOMSPEC.

Update: Подробнее об этом (включая примеры) читайтеВот.

Error: User Rate Limit Exceeded Doug
Error: User Rate Limit Exceeded"cmd.exe"Error: User Rate Limit ExceededCOMSPECError: User Rate Limit Exceededgetenv()Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded Doug
Error: User Rate Limit Exceededint main( int argc, char *argv[], char *env[] )Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded Doug

Похожие вопросы