1

我正在使用以下命令在 C 中创建三个子进程:

    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:当我以以下方式给出它时,它会起作用:

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 而不是 szCmdline[i]。然后它可以工作,但我不确定最顶层代码中的问题何时出现。

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 回答