CreateProcess - lpApplicationName 与 lpCommandLine

And*_*ndy 4 c++ parameters winapi process

我一直在使用 CreateProcess Win API,我想知道使用 lpApplicationName 和 lpCommandLine 作为参数与仅使用 lpCommandLine 参数之间有什么区别。

例如:

CreateProcess(NULL, L"C:\Path\To\Notepad.exe", L"C:\Path\To\File\To\Load.txt"... etc
CreateProcess(NULL, NULL, L"C:\Path\To\Notepad.exe C:\Path\To\File\To\Load.txt"... etc
Run Code Online (Sandbox Code Playgroud)

我认为仅使用 lpCommandLine 的第二个选项就像打开 cmd.exe 并运行该行。但是第一行呢?它是否加载应用程序并以不同的方式指定命令行参数?

我已经查看了 API 的 MSDN 文档,但它似乎并没有真正详细说明发生了什么,参数可以包含什么,这很好,但我只是对出现这种情况时应该做什么感到困惑有多种方法可以做到这一点。

请注意,我知道这两个示例行可能无法工作,因为 lpCommandLine 需要 LPTSTR,而不是 LPCTSTR。只是为了便于理解。

非常感谢您的帮助!

安迪

Joh*_*ohn 6

推荐的方法是使用这两个参数。如果您不指定 lpApplicationName,您将让 Windows 解析 lpCommandLine 来找出应用程序名称。由于空格是文件名和目录名中的有效字符,因此这可能(在极少数情况下)导致运行错误的应用程序。(例如,如果您有 c:\program.exe 并且在 Windows XP 中的 c:\program files 下启动程序)。

在这两种情况下,您都应该在 lpCommandLine 中使用应用程序名称,因为它用于计算 Argv[0]。

  • 该建议基于逻辑推理。大多数应用程序期望启动进程的可执行映像作为第一个参数(“argv[0]”)。对于这些情况,传递 *lpCommandLine* 就足够了,并且可以防止生成重复的冗余信息。传递 *lpApplicationName* 和 *lpCommandLine* 允许构造一个命令行,该命令行不包含可执行映像作为其第一个参数。它应该用于那些罕见的情况,其中应用程序需要一个(非标准)命令行,而该命令行没有可执行映像作为其第一个参数。 (3认同)
  • 推荐的方法是仅使用命令行,并为 *lpApplicationName* 参数传递“NULL”。如果应用程序名称包含空格,则需要用引号引起来。仅当您需要将非标准命令行(其中一个不包含可执行映像的路径名作为第一个参数)传递给正在创建的进程时,才使用这两个参数。 (2认同)
  • @IInspectable,您的建议基于什么?请阅读“安全备注”下的 CreateProcess 的 MSDN 页面,然后描述该问题...“为避免此问题,请勿为 lpApplicationName 传递 NULL。如果确实为 lpApplicationName 传递 NULL...”。因此 Microsoft 建议不要传递 NULL,但如果传递则使用引号。 (2认同)
  • 如果您使用“lpApplicationName”,那么系统将不会使用“PATH”环境变量来定位可执行文件,这可能不是您想要的。因此,我必须支持@IInspectable关于使用“lpCommandLine”,并以正确引用的路径作为首选选项。仅当您要启动的确切可执行文件的绝对路径已知时,才应使用“lpApplicationName”。 (2认同)