Fab*_*ujo 2 delphi command-line-arguments delphi-xe2 delphi-ide
考虑以下命令行参数
"alfa" "beta" "4"
Run Code Online (Sandbox Code Playgroud)
当我为我正在工作的项目指定Run> Parameters ...时,应用程序在Process Explorer上显示为命令行:
"c:\myapp\myapp.exe" "alfa" "beta" "4"
Run Code Online (Sandbox Code Playgroud)
ParamCount显示4个参数.但是当我从启动器应用程序(执行访问控制)启动相同的可执行文件时,Process Explorer显示:
"alfa" "beta" "4"
Run Code Online (Sandbox Code Playgroud)
ParamCount显示3个参数.命令行是从启动器应用程序中提取的.理论上它可以工作,因为从启动器启动应用程序工作完美无缺.从IDE启动时,它尝试在"4"上面执行StrToInt ,但只检索"beta"参数.
来自启动器应用程序的示例代码:
var
StartupInfo: TSTARTUPINFO;
ProcessInfo: PROCESS_INFORMATION;
CurrentDirPath: String;
begin
Result := 0;
ZeroMemory(@StartupInfo, SizeOf(StartupInfo));
StartupInfo.cb := SizeOf(StartupInfo);
DirCorrente := ExtractFilePath(sExe);
if CreateProcess(PChar(sExe), PChar(sParam), nil, nil, true,
NORMAL_PRIORITY_CLASS, nil, PChar(CurrentDirPath),
StartupInfo, ProcessInfo) then
Run Code Online (Sandbox Code Playgroud)
sParam的内容是上面的命令行参数,sExe是可执行路径.为什么会这样?
注意:我已经设计了如何将命令行参数解释更改为此边缘情况的健壮 - 这里的重点是为什么会发生这种情况.
您的启动程序未CreateProcess正确调用.请考虑文档中的摘录(强调添加):
如果lpApplicationName和lpCommandLine都是非NULL,则lpApplicationName指向的以null结尾的字符串指定要执行的模块,lpCommandLine指向的以null结尾的字符串指定命令行.新进程可以使用GetCommandLine来检索整个命令行.用C编写的控制台进程可以使用argc和argv参数来解析命令行.因为argv [0]是模块名称,所以C程序员通常会重复模块名称作为命令行中的第一个标记.
忽略"C程序员"; 它适用于为Windows编写程序的每个人,无论语言如何.
您的启动程序为lpApplicationName和lpCommandLine参数提供了值,但它没有遵循重复程序文件名作为命令行中第一个参数的约定.Delphi ParamStr和ParamCount函数知道遵循约定,因此它们跳过命令行上的第一个标记.如果调用者没有遵循惯例,那么接收者最终认为预期的第二个参数实际上是第一个,第三个实际上是第二个,依此类推.