c++ - 调用 CreateProcessAsUser 时,是否需要将 exe 路径指定为 lpCommandLine 中的第一个参数?

标签 c++ windows winapi

我似乎无法找到明确的答案。我的目标是使用用户 token 启动一个进程。比如说,有问题的过程是这样开始的:

"C:\My folder\My proc.exe" param=1

因此,当我为 CreateProcessAsUser 指定 lpCommandLine 参数时API,我是否需要将可执行路径指定为第一个参数:

LPCTSTR pStrExePath = L"C:\\My folder\\My proc.exe";

TCHAR buffCmdLine[MAX_PATH];
if(SUCCEEDED(::StringCchPrintf(buffCmdLine, MAX_PATH, 
    L"\"%s\" %s", pStrExePath, L"param=1")))

bResult = CreateProcessAsUser(
    hToken,            // client's access token
    pStrExePath,       // file to execute
    buffCmdLine,       // command line
    NULL,              // pointer to process SECURITY_ATTRIBUTES
    NULL,              // pointer to thread SECURITY_ATTRIBUTES
    FALSE,             // handles are not inheritable
    NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT,   // creation flags
    envBlock,          // pointer to new environment block 
    NULL,              // name of current directory 
    &si,               // pointer to STARTUPINFO structure
    &pi                // receives information about new process
);

或者我可以省略 exe 路径并执行此操作吗?

LPCTSTR pStrExePath = L"C:\\My folder\\My proc.exe";

TCHAR buffCmdLine[MAX_PATH];
if(SUCCEEDED(::StringCchCopy(buffCmdLine, MAX_PATH, L"param=1")))

bResult = CreateProcessAsUser(
    hToken,            // client's access token
    pStrExePath,       // file to execute
    buffCmdLine,       // command line
    NULL,              // pointer to process SECURITY_ATTRIBUTES
    NULL,              // pointer to thread SECURITY_ATTRIBUTES
    FALSE,             // handles are not inheritable
    NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT,   // creation flags
    envBlock,          // pointer to new environment block 
    NULL,              // name of current directory 
    &si,               // pointer to STARTUPINFO structure
    &pi                // receives information about new process
);

它们似乎都有效。

最佳答案

阅读文档,这两种情况都应该有效。

来自 MSDN

If both lpApplicationName and lpCommandLine are non-NULL, *lpApplicationName specifies the module to execute, and *lpCommandLine specifies the command line. The new process can use GetCommandLine to retrieve the entire command line. Console processes written in C can use the argc and argv arguments to parse the command line. Because argv[0] is the module name, C programmers generally repeat the module name as the first token in the command line.

我同意文档可能更清楚地说当 lpApplicationName 为非 NULL 时它接受命令行的参数部分或 lpCommandLine 中的完整命令行。

更新: 如果 lpApplicationName 为 NULL,文档会更好

If lpApplicationName is NULL, the first white space–delimited token of the command line specifies the module name...

更新 2: 关于这些参数有一个很好的文档 Understanding CreateProcess and Command-line Arguments . 阅读本文档,我了解到您的两种情况有所不同。当您在 lpCommandLine 中提供 lpApplicationName 和参数时,子进程将像在 lpCommandLine 中一样解析命令行。因此,如果您不复制 exe 路径,argv[0] 将不会像往常一样表示 exe 路径,而是 param=1。

关于c++ - 调用 CreateProcessAsUser 时,是否需要将 exe 路径指定为 lpCommandLine 中的第一个参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38417790/

相关文章:

windows - 转储诊断

winapi - 为什么在 win32 上无法捕获第二个 SIGINT?

c++ - UnhookWindowsHookEx() 期间崩溃

c# - 我们可以使用 "goto"关键字来结束线程吗?

c++ - 粒子和OpenGL的问题,没有绘制任何东西

c++ - Cin 坚持输入并错误读取

c++ - Qt 应用程序在使用文件打开对话框后将焦点切换到不同的应用程序

node.js - npm 在 Windows 10 上非常慢

windows - 监视 WMI 调用的工具

c++ - 如何在 Win32 中递归创建文件夹?