1

以下を使用して、C で 3 つの子プロセスを作成しています。

    typedef struct{
        STARTUPINFO si;
        PROCESS_INFORMATION pi;
    }PROCESS_PARAMS;

    PROCESS_PARAMS pChildren[3];

    wchar_t *szCmdline[3] = {L"nmtest -s \"TS\" -r \"Test DMR\" -tLD -d \" /child1/tclient\"",
 L"nmtest -s \"TS\" -r \"Test DMR\" -tLD -d \" /child2/tclient\"", 
L"nmtest -s \"TS\" -r \"Test DMR\" -tLD -d \" /child3/tclient\""};


    for (i=0; i<3; i++)
                {
                    pChildren[i].si.cb = sizeof(pChildren[i].si);
                    GetStartupInfo(&pChildren[i].si);
                    ZeroMemory(&pChildren[i].pi, sizeof(pChildren[i].pi));

                    // Start the child processes.
                    CreateProcess(NULL,   // No module name (use command line)
                                  szCmdline[i],          // Command line
                                  NULL,           // Process handle not inheritable
                                  NULL,           // Thread handle not inheritable
                                  FALSE,          // Set handle inheritance to FALSE
                                  0,              // No creation flags
                                  NULL,           // Use parent's environment block
                                  NULL,           // Use parent's starting directory
                                  &pChildren[i].si,            // Pointer to STARTUPINFO structure
                                  &pChildren[i].pi);         // Pointer to PROCESS_INFORMATION structure
                }

しかし、新しいプロセスの作成中にコードがクラッシュし、コマンドライン引数に何か問題があると思われます。しかし、何が悪いのかわかりません。誰かがこれで私を助けてくれますか? ありがとう。

PS:次の方法でそれを与えると、1つのインスタンスで機能します:

wchar_t szCmdline[] = L"nmctest -s \"TwonkyServer[julka]\" -r \"NMC Test DMR [julka960]\" -tLDMR -d \" /child1/twonkyclient\""; 

そして、私は:

CreateProcess(NULL,   // No module name (use command line)
                                  szCmdline,          // Command line
                                  NULL,           // Process handle not inheritable
                                  NULL,           // Thread handle not inheritable
                                  FALSE,          // Set handle inheritance to FALSE
                                  0,              // No creation flags
                                  NULL,           // Use parent's environment block
                                  NULL,           // Use parent's starting directory
                                  &pChildren[i].si,            // Pointer to STARTUPINFO structure
                                  &pChildren[i].pi); 

szCmdline[i] の代わりに szCmdline を与えることに注意してください。それは機能しますが、最上位のコードでいつ問題が発生するのかわかりません。

4

1 に答える 1

2

ドキュメントからCreateProcess()

この関数の Unicode バージョンである CreateProcessW は、この文字列の内容を変更できます。したがって、このパラメーターを読み取り専用メモリー (const 変数やリテラル文字列など) へのポインターにすることはできません。このパラメーターが定数文字列の場合、関数はアクセス違反を引き起こす可能性があります。

また、Unicode バージョンを使用していて、文字列リテラル (変更不可) へのポインターを渡しているようです。

これは、関数のバージョンの問題ではありません。これは、CreateProcessA()内部的に ANSI コマンド ラインを Unicode に変換し、変換された文字列が変更可能なメモリに格納されるためです。

動作するバージョンでは、文字列を変更可能な配列に初期化し、文字列リテラルへのポインターを渡す代わりに、その配列のアドレスを渡します。

この状況の歴史については、Raymond Chen の「CreateProcess 関数が入力コマンド ラインを変更する理由」を参照してください。.

もう少しヘルプが必要な場合のコード例:

// a helper function to duplicate a unicode string
wchar_t* xwcsdup( wchar_t const* s)
{
    wchar_t* p = _wcsdup(s);

    if (!p) {
        abort();    // or however you want to fail miserably
    }

    return p;
}



// and your loop to create the processes...

for (i=0; i<3; i++)
{
    wchar_t* cmdline = xwcsdup(szCmdline[i]);

    pChildren[i].si.cb = sizeof(pChildren[i].si);
    GetStartupInfo(&pChildren[i].si);
    ZeroMemory(&pChildren[i].pi, sizeof(pChildren[i].pi));

    // Start the child processes.
    CreateProcess(NULL,   // No module name (use command line)
                  cmdline,        // Command line
                  NULL,           // Process handle not inheritable
                  NULL,           // Thread handle not inheritable
                  FALSE,          // Set handle inheritance to FALSE
                  0,              // No creation flags
                  NULL,           // Use parent's environment block
                  NULL,           // Use parent's starting directory
                  &pChildren[i].si,            // Pointer to STARTUPINFO structure
                  &pChildren[i].pi);         // Pointer to PROCESS_INFORMATION structure

    free(cmdline);
}
于 2012-12-20T08:03:15.437 に答える