调用 CreateProcessAsUser 时,我是否需要在 lpCommandLine 中指定一个 exe 路径作为

Do I need to specify an exe path as the 1st parameter in lpCommandLine when calling CreateProcessAsUser?

本文关键字:一个 路径 exe CreateProcessAsUser 是否 lpCommandLine 调用      更新时间:2023-10-16

我似乎找不到明确的答案。我的目标是使用用户令牌启动一个进程。假设,有问题的过程是这样开始的:

"C:My folderMy proc.exe" param=1

因此,当我为创建进程作为用户 API 指定lpCommandLine参数时,我是否需要将可执行路径指定为第一个参数:

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

如果 lpApplicationName 和 lpCommandLine 都是非空的, *lpApplicationName 指定要执行的模块,*lpCommandLine 指定命令行。新进程可以使用 GetCommandLine 来 检索整个命令行。用 C 语言编写的控制台进程可以 使用 argc 和 argv 参数解析命令行。因为 argv[0] 是模块名称,C 程序员一般重复模块 名称作为命令行中的第一个标记

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

更新:在 lpApplicationName 为 NULL 的情况下,文档更好

如果 lpApplicationName 为 NULL,则命令行的第一个空格分隔标记指定模块名称...

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

相关文章: