winApi使用c++创建进程

Posted

技术标签:

【中文标题】winApi使用c++创建进程【英文标题】:winApi create process using c++ 【发布时间】:2020-03-24 17:55:04 【问题描述】:

我正在尝试在 c++ 中使用 WinApi 打开图片,尝试了 createProcessWcreateProcessA,我的主要问题是连接用作 cmdLine 参数的字符串。这就是我得到的:

STARTUPINFOW process_startup_info 0 ;
process_startup_info.cb = sizeof(process_startup_info); // setup size of strcture in bytes

PROCESS_INFORMATION process_info 0 ;

wchar_t* s = L"\"C:\\Windows\\system32\\mspaint.exe\" ";
std::string s2 = pic.getPath();
// connecting strings here
if (CreateProcessW(NULL, /* string should be here */, NULL, NULL, TRUE, 0, NULL, NULL, &process_startup_info, &process_info))

    WaitForSingleObject(process_info.hProcess, INFINITE);
    CloseHandle(process_info.hProcess);
    CloseHandle(process_info.hThread);

【问题讨论】:

需要将图片的路径转换成宽字符串,才能将两者拼接起来。 【参考方案1】:

如果可以,请尝试在任何地方对命令和参数使用相同的类型。这里我使用wstring,将参数连接到命令,然后将其转换为LPWSTR 用于CreateProcess 方法。

STARTUPINFOW process_startup_info 0 ;
process_startup_info.cb = sizeof(process_startup_info); // setup size of strcture in bytes

PROCESS_INFORMATION process_info 0 ;

std::wstring params = L"\"C:\\Windows\\system32\\mspaint.exe\" ";
params.append(L"\"C:\\Vroom Owl.png\"");

// connecting strings here
if (CreateProcessW(NULL, (LPWSTR)params.data(), NULL, NULL, TRUE, 0, NULL, NULL, &process_startup_info, &process_info))

    WaitForSingleObject(process_info.hProcess, INFINITE);
    CloseHandle(process_info.hProcess);
    CloseHandle(process_info.hThread);

【讨论】:

将项目设置为多字节而不是 Unicode 将使CreateProcess() 调用CreateProcessA() 而不是CreateProcessW()。实际上最好不要依赖TCHAR 宏。在这种情况下,如果您使用std::wstring,那么您应该直接调用CreateProcessW() 进行匹配。另请注意,使用const_cast<LPWSTR>(params.c_str()) 在技术上是未定义的行为,请改用params.data()(C++17 或更高版本)或&params[0](C++11 或更高版本)(std::(w)string 数据未保证 i> 在 C++11 之前存储在顺序内存中,但实际上通常是这样)。 @RemyLebeau 我可以加入。我会相应地更新我的答案。 如果你能帮上忙,不要抛弃const-ness。如果您的编译器有可用的data() 方法,但没有非const 版本,则使用&[0] 将起作用,并且不需要强制转换。【参考方案2】:

在包括:

#include <sstream>

在代码中:

std::wstringstream wstringCmd;

std::wstring wstrExec = L"\"C:\\Windows\\system32\\mspaint.exe\" "; //<- wstring 
std::string strPic = pic.getPath(); //<- if getPath() return char  
// std::wstring wstrPic = pic.getPath();//<- if getPath() return wchar  

// you can combine as you like ...
wstringCmd << wstrExec.c_str() << strPic.c_str(); // or << wstrPic.c_str();
std::wstring wstrCommande= wstringCmd.str();

【讨论】:

我对这里的 strPic 和 wstrPic 值感到困惑。方法调用用双引号括起来。这肯定是一个疏忽。 另外,您也不能将std::stringchar* 流式传输到std::wstringstream。您必须先将 std::string 转换为 std::wstring @NTDLS 只是为了解释我们有“字符串”或 L“字符串” @RemyLebeau 试试看,不行我们再谈 @Landstalker I did try it,当然,&lt;&lt; 适用于 char*,即使流是 std::wstringstream,但它不适用于 std::string。此外,您无法将 std::wstringstd::wstringstream.str() 保存到 std::string

以上是关于winApi使用c++创建进程的主要内容,如果未能解决你的问题,请参考以下文章

检查文件是由进程创建还是由用户使用 C++ 创建

C#、C++、WinAPI - 从另一个进程获取窗口数

使用 WinAPI 找出锁定文件的原因

如何安全地调用 TerminateThread 和 FreeLibrary (WinAPI, C++)

为啥我使用 WinAPI C++ 录制的声音无法正常播放?

C++ Win API 函数'未在此范围内声明'