0

だから、私は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() に渡すと同じエラーが発生し、PATH を指定できないため、明らかに _spawnv は使用されません。

つまり、この質問に対する答えは次のとおりです。PATH 変数が間違っているからです。

...しかし、私はまだそれがどうあるべきか分かりません。私がどこでも見つけることができるこれの実例はないようです。_spawnve() または _spawnvpe() を使用して PATH 変数を渡す (そして動作する) コーディングの例にリンクする回答を受け入れます。

編集#2:

本当。いいえ、実際には、これは機能しません。これが機能しない例です。機能する例へのリンクを忘れてください。私の例を変更して、1) PATH で渡され、2) エラーなしで実行される diff を投稿するだけです。

注意 それが機能するのを見たいですか?_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
4

3 に答える 3

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 の両方でテストしましたが、動作します。メモ帳が実行されます。

どのコンパイラを使用していますか?

于 2012-06-19T00:54:17.297 に答える
0

そうです、_ の 2 番目のパラメーターspawnev()は、実行するアプリの名前 (フル パスを含む) を取ります。

パスを知るには、コマンド プロセッサを呼び出し、それをアプリケーションの名前に渡して、オプションcmd.exeを使用してパラメータとして実行します。cmd.exe/C

cmd.exeこれは、のコマンド ライン ウィンドウのいずれかからアプリケーションを起動できたすべてのケースで機能します。

cmd.exe環境変数の値を認識し、PATHそれを使用して、開始するアプリのパスを検索しました。

それ自体へのパスcmd.exeは、環境変数から読み取ることができますCOMSPEC

更新: この問題の詳細 (例を含む) については、こちらをお読みください

于 2012-06-10T14:54:19.163 に答える
-1

ここで指定されているように、_spawn、_wspawn関数、名前に「p」文字が含まれる関数のみが、PATH環境変数を暗黙的に使用します。他の人はしません。

したがって、これを行う必要があります。

char *args[] =  {"notepad.exe", NULL };
_spawnvpe(_P_NOWAIT, args[0], args, NULL);
于 2012-06-18T07:28:22.413 に答える