3

CreateProcess または CreateProcessW のいずれかを取得して、名前が MAX_PATH 文字未満のプロセスを実行しようとしていますが、パスは MAX_PATH 文字を超えています。ドキュメントによると:http://msdn.microsoft.com/en-us/library/ms682425.aspx、lpApplicationName が NULL でないことを確認する必要があり、lpCommandLine は最大 32,768 文字です。

試してみましたが、ERROR_PATH_NOT_FOUND が発生します。

CreateProcessW に変更しましたが、それでも同じエラーが発生します。で説明されているように、lpApplicationName の前に \\?\ を付けると、http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx CreateProcessW を呼び出すと、別のエラーが表示され、もう少し近づいたと思われます: ERROR_SXS_CANT_GEN_ACTCTX。

CreateProcessW への私の呼び出しは次のとおりです。

CreateProcessW(w_argv0,arg_string,NULL,NULL,0,NULL,NULL,&si,&ipi);

w_argv0 はどこにありますか\\?\<long absolute path>\foo.exe.

arg_string には、"<長い絶対パス>\foo.exe" foo が含まれています

si は次のように設定されます。

    memset(&si,0,sizeof(si));
    si.cb = sizeof(si);
    si.dwFlags = STARTF_USESHOWWINDOW;
    si.wShowWindow = SW_HIDE;>

次のように、pi は空です。

    memset(&pi,0,sizeof(pi));

システム イベント ログを調べたところ、イベント ID 59、ソース SideBySide: Generate Activation Context failed for .Manifest でこれを試行するたびに新しいエントリがあります。参照エラー メッセージ: 操作は正常に完了しました。

実行しようとしているファイルは、パス < MAX_PATH 文字で正常に実行されます。

明確にするために、<長い絶対パス> の 1 つのコンポーネントが MAX_PATH 文字を超えることはありません。最後に .manifest があっても、実行可能ファイル自体の名前は確かにそうではありません。ただし、パス全体を合わせると、長さが MAX_PATH 文字を超えています。

マニフェストを埋め込むかどうかに関係なく、同じエラーが発生します。マニフェストは foo.exe.manifest という名前で、埋め込まれていない場合は実行可能ファイルと同じディレクトリに存在します。を含む:

<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
  <依存関係>
    <依存アセンブリ>
      <assemblyIdentity type='win32' name='Microsoft.VC80.DebugCRT' version='8.0.50727.762' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' />
    </dependentAssembly>
  </依存>
</アセンブリ>

これを機能させる方法を知っている人はいますか?おそらく:

  • CreateProcess または CreateProcessW を呼び出してパス > MAX_PATH 文字でプロセスを実行する別の方法

  • マニフェスト ファイルでできること

XP SP2 で Visual Studio 2005 を使用してビルドし、ネイティブで実行しています。

ご協力いただきありがとうございます。

4

2 に答える 2

2

マニフェストを埋め込んでGetShortPathNameWを使用すると、それができました。どちらか一方だけでは不十分でした。

最初の引数として実行するプロセスの\\?-接頭辞付き絶対パス名を使用してCreateProcessWを呼び出す前に、次のことを確認します。

wchar_t * w_argv0;
wchar_t * w_short_argv0;

..。

if(wcslen(w_argv0)> = MAX_PATH)
{{
    num_chars = GetShortPathNameW(w_argv0、NULL、0);
    if(num_chars == 0){
        syslog(LOG_ERR、 "GetShortPathName(%S)to get size failed(%d)"、
w_argv0、GetLastError()); / * **続けて、長い名前で試してみてください * / } そうしないと { w_short_argv0 = malloc(num_chars * sizeof(wchar_t)); memset(w_short_argv0,0、num_chars * sizeof(wchar_t)); if(GetShortPathNameW(w_argv0、w_short_argv0、num_chars)== 0){ syslog(LOG_ERR、 "GetShortPathName(%S)failed(%d)"、w_argv0、
GetLastError()); free(w_short_argv0); w_short_argv0 = NULL; } そうしないと { syslog(LOG_DEBUG、 "%Sに短縮名%Sを使用"、w_short_argv0、
w_argv0); } } }

次に、CreateProcessW(w_short_argv0?w_short_argv0:w_argv0 ...);を呼び出します。

解放することを忘れないでください(w_short_argv0); その後。

これですべてのケースが解決するわけではありませんが、以前よりも多くの子プロセスを生成できます。

于 2008-09-28T01:16:33.150 に答える
1

'\\?\' 構文がモジュール名に有効であると言っている CreateProcess ドキュメントの参照はありません。「ファイルまたはディレクトリの名前付け」のページにも、CreateProcess がそれをサポートしているとは記載されていませんが、CreateFile などの関数は「ファイルの名前付け」ページにリンクしています。

より長いモジュール名を使用できないことがわかりましMAX_PATHlpCommandLineこれは、CreateProcess が非常に長いファイル名をサポートしていないことを示唆しています。このエラー メッセージは、「.manifest」をアプリケーション パスに追加しようとしたときにエラーが発生したことも示しています (つまり、長さが MAX_PATH を超えています)。

GetShortPathName() はここで役立つかもしれませんが、MAX_PATH より小さい名前を返すことは保証されていません (ただし、'\\?\' 構文が有効であると明示的に述べています)。それ以外の場合は、環境変数を調整して、PATHそれを の CreateProcess() に渡すことができますlpEnvironment。または、SetCurrentDirectory() を使用して、実行可能ファイル名のみを渡すこともできます。

于 2008-09-27T10:54:29.417 に答える