C++ CreateProcess-lpApplicationName与lpCommandLine

C++ CreateProcess-lpApplicationName与lpCommandLine,c++,winapi,parameters,process,C++,Winapi,Parameters,Process,我一直在使用CreateProcess Win API,我想知道对参数v.s使用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\F

我一直在使用CreateProcess Win API,我想知道对参数v.s使用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
我假设第二个选项(仅使用lpCommandLine)类似于打开cmd.exe并运行该行。但是第一行呢,它是否加载应用程序并以不同的方式指定命令行参数

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

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

非常感谢你的帮助


Andy

建议使用这两个参数。如果不指定lpApplicationName,则允许Windows解析lpCommandLine以确定应用程序名。因为空格是文件名和目录名中的有效字符,所以在极少数情况下会导致运行错误的应用程序。(例如,如果您有c:\program.exe,并且在Windows XP中的c:\program files下启动了一个程序)

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

,lpApplicationName是可选的,可以为NULL。在这种情况下,模块名必须是lpCommandLine字符串中第一个空格分隔的标记


如果可执行模块是16位应用程序,lpApplicationName应为空,lpCommandLine指向的字符串应指定可执行模块及其参数。

我从不使用lpApplicationName,总是引用lpCommandLine的应用程序部分,在您的示例中,我将执行
“C:\Path\to\Notepad.exe”“C:\Path\To\File\To\Load.txt”
(引用传递给CreateProcess的所有路径是一个好主意)仅使用lpApplicationName可能会导致访问argv[0]的子进程出现问题,这就是我远离它的原因



在除您自己以外的任何对象上使用CreateProcess可能会有问题,因为NT6+在任何时候都会决定您正在执行的操作需要管理员权限,因为应用程序兼容性和/或安装程序检测,然后CreateProcess就会失败。除非您需要使用调试或脱离作业标志,否则我建议您调用ShellExecute[Ex]是出于安全考虑…

是什么让你说MSDN没有详细解释正在发生的事情?这很难再详细了。三个字中,lpApplicationName或多或少地满足了你的要求,而lpCommandLine则增加了很多解释和魔力(附加扩展名、搜索路径等)而且,正如John所说,通常最好的方法是同时使用两者。好吧,也许第一轮中有一些细节我不理解/错过了,但我仍然觉得有点模棱两可。关于使用ShellExecute的最后一点很有趣,这是我们最初使用的,但我们不得不转到createprocess,因为Adobe Reader nEED指定了当前用户的环境块(因此它在users documents文件夹中而不是在system profile中),我认为您无法使用ShellExecute实现这一点。如果我们使用shell execute,并且Adobe Reader是默认处理程序,它将加载,但由于拒绝访问systemprofile文件夹而崩溃。有什么建议吗?:)@安迪:这是一种咆哮。不要当真。真正的问题是执行随机字符串,例如从注册表中执行,而不知道它们指向什么。如果你不知道你在执行什么,那么是的,你可以尝试启动安装程序。至于启动Adobe Reader,这对于
ShellExecute
,是一个很明显的例子。不要试图猜测我用什么作为示例PDF reader。我不使用Adobe,部分原因是它有缺陷。建议的方法是仅使用命令行,并为lpApplicationName参数传递
NULL
。如果应用程序名称包含空格,则需要引用。如果需要传递非标准命令行,则仅使用两个参数(一个,不包含可执行映像的路径名作为第一个参数)到正在创建的进程。@IInspectable,您的建议基于什么?请阅读CreateProcess的MSDN页面“安全备注”下的内容,然后描述问题为避免此问题,请不要为lpApplicationName传递NULL。如果为lpApplicationName传递NULL…。因此,Microsoft建议不要传递NULL,但如果传递NULL,则应使用引号。此建议基于逻辑推理。大多数应用程序希望启动进程的可执行映像作为第一个参数(
argv[0]
)。对于这些情况,传递lpCommandLine就足够了,可以防止生成重复的冗余信息。传递lpApplicationName和lpCommandLine可以构造一个命令行,该命令行不包含可执行映像作为其第一个参数。它应该用于应用程序需要(非标准)命令行,该命令行的第一个参数不是可执行映像。如果使用
lpApplicationName
,则系统不会使用
PATH
环境变量来定位可执行文件,这可能不是您想要的。因此,我必须支持@IInspectable使用
lpCommandLine
,正确引用路径作为e首选选项。仅当您要启动的确切可执行文件的绝对路径已知时,才应使用
lpApplicationName