我似乎找不到确切的答案。我的目标是使用用户令牌启动一个过程。说,所涉及的过程是这样开始的:

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


因此,当我为CreateProcessAsUser 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均为非NULL,
  * lpApplicationName指定要执行的模块,* lpCommandLine指定命令行。新过程可以使用GetCommandLine来
  检索整个命令行。用C编写的控制台进程可以
  使用argc和argv参数来解析命令行。因为
  argv [0]是模块名称,C程序员通常会重复该模块
  名称作为命令行中的第一个标记。


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

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


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


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

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

10-11 01:53