关于创建进程函数CreateProcess()字符串参数的说明

参考:http://blog.csdn.net/a32132100/article/details/6412386

void main()
{
    STARTUPINFO si = { sizeof(STARTUPINFO) };
    PROCESS_INFORMATION pi;

    TCHAR szCmd[] = TEXT("cmd");
    //LPWSTR szCmd = L"cmd";// 会导致运行时问题
    //WCHAR szCmd[] = L"cmd";// 正确

//     LPWSTR szCmd = new WCHAR[4];
//     szCmd[0] = 'c';
//     szCmd[1] = 'm';
//     szCmd[2] = 'd';
//     szCmd[3] = '\0';    //正确

    //进行以下测试时请将
    //STARTUPINFO si = { sizeof(STARTUPINFO) }; 改为
    //STARTUPINFOA si = { sizeof(STARTUPINFOA) };
    //且创建进程函数 CreateProcess 改为 CreateProcessA

    //LPSTR szCmd = "cmd";            //正确
    //LPCSTR szCmd = "cmd";        //错误,CreateProcessA 参数2类型为 LPSTR,编译不通过

    si.dwFlags = STARTF_USESHOWWINDOW;
    si.wShowWindow = true;

    BOOL bResult = CreateProcess( NULL, 
                             szCmd,
                             NULL, 
                             NULL, 
                             FALSE, 
                             //CREATE_NEW_CONSOLE,
                             CREATE_SUSPENDED,
                             NULL,
                             NULL,
                             &si,
                             &pi );
    if (bResult)
    {
        CloseHandle(pi.hThread);
        CloseHandle(pi.hProcess);
    }
}

总结:对于参数2来说

1.首先它不支持const参数传递。

2.对于char和wchar_t型数组来说总是可以的,他们都是位于栈上的局部可修改的内存。(这也是参数的要求)

3.对于使用“一个指针指向“字符串字面值”作为参数的情况,在ANSI版本CreateProcessA()下是可以正常运行的,而Unicode下的CreateProcessW()无法正常运行

原因:

CreateProcessW()中的字符串参数之所以要求是非const,是因为函数在内部执行过程中对字符串参数进行了修改(在函数返回前,这个字符串会被还原为原来的形式)。

而采用一个“可读写指针”指向“字符串字面值常量”作为参数,虽然编译可以通过,但是实际上我们是不能对“字符串字面值”进行修改的,如:

char* multiChar = "multichar";

wchar_t* wideChar = "widechar";

编译器识别类型时将它们认作非const形式,但是实际上任何对它们内容的修改,都会导致访问冲突。

那么,为CreateProcessA()传递这种参数为什么能正常运行呢?

CreateProcessA()的执行过程,是在内部将ANSI字符转存到一个Unicode字符数组副本中去,然后直接调用它的Unicode版本CreateProcessW(),其中没有对参数直接做修改,

所有操作都是由参数转存的Unicode副本完成的。而Unicode副本在函数内部是新在堆上分配的内存(参考《Windows via C/C++》2.8.1节的例子)

作者原话:(4.2.1节)

 “目前,Microsoft 最应该做的一件事,就是修正 CreateProcess,使它自己能创建字符串的一个临时副本,从而使我们得到解放。Windows 未来的版本或许会对此进行修复。”

所以我们要做的就是避免采用这种方式传递字符串参数,取而代之的是使用数组方式。

原文地址:https://www.cnblogs.com/sunrisezhang/p/3050008.html