如何在 C++ 中调用 unicode 函数 CreateProcessW 来启动 Windows 可执行文件?

Blu*_*ue7 -1 c++ unicode createprocess

这里有一个如何在堆栈交换上调用 CreateProcess 的示例,但是 Windows 10 似乎不再支持此功能,并且您必须使用 unicode 版本 CreateProcessW。

与 ASCI 版本类似,我正在寻找一个示例:

  1. 启动一个 EXE
  2. 等待 EXE 完成。
  3. 可执行文件完成时正确关闭所有句柄。

Bar*_*ani 5

Windows 10 在这方面并没有什么新鲜事。您的问题实际上是关于 Unicode 与 ANSI,以及 Visual Studio 使用 Unicode 的新默认设置。

CreateProcess是一个宏,它的定义为

#ifdef UNICODE
#define CreateProcess  CreateProcessW
#else
#define CreateProcess  CreateProcessA
#endif // !UNICODE
Run Code Online (Sandbox Code Playgroud)

另外STARTUPINFO还有一个宏STARTUPINFOASTARTUPINFOW

CreateProcessA使用 ANSI 字符字符串char*STARTUPINFOA

CreateProcessW使用 Unicode 宽字符字符串wchar_t*并且STARTUPINFOW

如果您坚持使用 ANSI(不推荐),请转到“项目设置”->“字符集”并禁用 Unicode。

如果你坚持使用带有 Unicode 设置的 ANSI 版本(仍然不推荐),你需要

//Using ANSI when UNICODE is defined (not recommended):
STARTUPINFOA si = { sizeof(si) };
PROCESS_INFORMATION pi;
std::string path = "c:\\windows\\notepad.exe \"c:\\test\\_text.txt\"";

//if not using C++11 or later, force a zero at the end 
//to make sure path is null-ternminated
path.push_back(0);

if(CreateProcessA(NULL, &path[0], NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
{
    WaitForSingleObject(pi.hProcess, INFINITE); 
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
}
Run Code Online (Sandbox Code Playgroud)

只要目录名称与 ANSI 兼容,上面的代码就可以工作。但推荐的版本是:

//recommended:
{
    STARTUPINFO si = { sizeof(si) };
    PROCESS_INFORMATION pi;
    std::wstring path = L"c:\\windows\\notepad.exe \"c:\\test\\_text.txt\"";

    //if not using C++11 or later, force a zero at the end 
    //to make sure path is null-ternminated
    path.push_back(0);

    if(CreateProcess(0, &path[0], NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
    {
        WaitForSingleObject(pi.hProcess, INFINITE);
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
    }
}
Run Code Online (Sandbox Code Playgroud)

另外,不要从常量字符串转换为字符串,如下所示:

wchar_t* arg_concat = const_cast<wchar_t*>( input.c_str() );
Run Code Online (Sandbox Code Playgroud)

中的第二个参数CreateProcess应该是wchar_t*因为进程可能会修改命令行。