问题描述
我从中弄清楚了如何使用CreateProcessAsUserA()
打开一个进程:
现在,我需要添加过程参数以正确运行程序,我的意思是像-steam
这样的参数。
我在Google上找不到任何解决方案。请帮助我。
解决方法
BOOL CreateProcessAsUserA(
HANDLE hToken,LPCSTR lpApplicationName,LPSTR lpCommandLine,LPSECURITY_ATTRIBUTES lpProcessAttributes,LPSECURITY_ATTRIBUTES lpThreadAttributes,BOOL bInheritHandles,DWORD dwCreationFlags,LPVOID lpEnvironment,LPCSTR lpCurrentDirectory,LPSTARTUPINFOA lpStartupInfo,LPPROCESS_INFORMATION lpProcessInformation
);
您可以将命令行附加到目标EXE的末尾。
因此,使用上面的示例,它看起来像这样:
rc = CreateProcessAsUserA(hUserToken,// user token
0,// app name
(LPSTR)"c:\\foo.exe -steam",// command line
0,// process attributes
0,// thread attributes
FALSE,// don't inherit handles
DETACHED_PROCESS,// flags
0,// environment block
0,// current dir
&si,// startup info
&pi);
对于lpCommandLine
,此方法的“ A”版本不必为非常量,而另一方面,“ W”版本则为非常量。
如果可执行文件的路径中包含空格,则将其用引号引起来:
(LPSTR)"\"c:\\my files\\foo.exe\" -steam"
ETA:
对于如何为目标程序生成命令行存在一些困惑。为了使事物保持C样式(argv[0]
是目标可执行文件的路径),您不应使用lpApplication
参数,并且如果这样做,您仍希望lpCommandLine
看起来就像上面一样。
文档中的信息:
如果lpApplicationName
和lpCommandLine
都不为NULL,则*lpApplicationName
指定要执行的模块,而*lpCommandLine
指定命令行。新进程可以使用GetCommandLine
来检索整个命令行。用C编写的控制台进程可以使用argc
和argv
参数来解析命令行。因为argv[0]
是模块名称,所以C程序员通常将模块名称作为命令行中的第一个标记重复。
如果发现正确地引用正确的技巧,则可以创建一个函数来实现。
C ++ 17:
#include <initializer_list>
#include <string_view>
#include <utility>
// A function to prepare a commandline for execution by quoting
auto prep_cmd(std::initializer_list<std::string_view> args) {
if(args.size()==0) throw std::runtime_error("No command,no fun");
auto it = args.begin();
std::string AppName(*it); // AppName is returned unchanged
std::string CmdLine('"' + AppName + '"'); // but quoted when used in the commandline
for(++it; it != args.end(); ++it) {
CmdLine += ' ' + std::string(*it); // add argument unquoted
// CmdLine += " \"" + std::string(*it) + '"'; // or quote the argument too
}
return std::pair{AppName,CmdLine}; // return the result
}
然后称呼它:
auto[AppName,CmdLine] = prep_cmd({
R"aw(C:\Program Files (x86)\Steam\steamapps\common\Counter-Strike Global Offensive\csgo.exe)aw","-steam"
});
使用结果:
CreateProcessAsUserA(
hToken,AppName.c_str(),// const char*
CmdLine.data(),// char*
...
);