如何在VC++中包含CreateProcess API的参数

How to include argument with CreateProcess API in VC++?

本文关键字:CreateProcess API 参数 包含 VC++      更新时间:2023-10-16

我已经使用createprocess API从我的主应用程序调用了另一个应用程序。但另一个进程也需要一些参数作为参数。

我创建的过程为:

BOOL ret= CreateProcess( NULL, szCmdline, NULL, NULL, TRUE, 0, NULL, NULL,&siStartInfo, &piProcInfo);  

szCmdline 是可变的,它控制应用程序的完整路径。

知道如何通过此过程传递参数。

谢谢

CreateProcess 同时具有 lpApplicationName 和 szCommandLine 参数。必须至少传递其中一个参数。但是,出于安全原因,您应该同时通过两者。

  • lpApplicationName是要运行的可执行文件的名称。
  • szCommandLine是您希望传递给该可执行文件的命令行。它应包括可执行文件作为第一项。应用程序将以此作为参数接收WinMain或由GetCommandLine函数检索(尽管如果未提供完全限定路径,系统可能会预置完全限定路径)。对于使用mainwmain的C程序,CRT会将其解析为参数。

  • 如果你传递NULL for lpApplicationName,系统将尝试在szCommandLine中找到可执行文件,并将使用该可执行文件。

  • 如果为 szCommandLine 传递 NULL,系统将对两者使用 lpApplicationName

所以命令行就是命令行。如果要传递给命令的参数,请将它们放在命令行上。

如果 lpApplicationName 为 NULL,则第一个空格分隔的标记 命令行指定模块名称。如果您使用长 包含空格的文件名,使用带引号的字符串指示位置 文件名结束,参数开始(请参阅的说明 lpApplicationName 参数)。

最好同时传递 lpApplicationName 和 szCommandLine,以确保系统不会误解命令行并运行错误的可执行文件。(几年前有一类安全问题由此引起)。

此外,在传递 lpApplicationName 和 szCommandLine 时,请记住 szCommandLine 仍然需要包含应用程序名称作为第一个参数。

例如,如果您的程序C:Program FilesMy ApplicationProgram.exe并且参数/the /arguments,则可以将lpApplicationName设置为"C:Program FilesMy ApplicationProgram.exe",并将szCmdline设置为"C:Program FilesMy ApplicationProgram.exe" /the /arguments

安全问题是什么?

想象一下,如果有人创建了一个文件"C:\Program Files\My.exe"。如果省略引号,系统会将C:Program FilesMy ApplicationProgram.exe /the /arguments解释为:C:Program FilesMy.exe ApplicationProgram.exe /the /arguments 。你会得到一个惊喜。这种类型的技巧可以用来欺骗管理员运行他们不想运行的程序,这是一个安全问题。如果传递 lpApplicationName 参数,则不会发生这种情况。

CreateProcess 函数创建一个新进程,该进程独立于创建进程运行。但是,为简单起见,该关系称为父子关系。
第一个参数 lpApplicationName 可以是 NULL,在这种情况下,可执行文件名称必须位于 lpCommandLine 指向的空格分隔字符串中。

通过这种方式,您可以在CreateProcess API中发送多个参数。

sprintf(exePath,"Project.exe %s %s "%s" "%s" ", appName,serverid,srjPath,caseName);
    if( !CreateProcess( NULL, // No module name (use command line).
        exePath,      // Command line.
        NULL,                 // Process handle not inheritable.
        NULL,                 // Thread handle not inheritable.
        FALSE,                // Set handle inheritance to FALSE.
        NORMAL_PRIORITY_CLASS,// No creation flags.
        NULL,                 // Use parent's environment block.
        NULL,                 // Use parent's starting directory.
        &si,                  // Pointer to STARTUPINFO structure.
        &pi )                 // Pointer to PROCESS_INFORMATION structure.
        )

恢复此命令行参数时,您应该解析此参数并用前面带有反斜杠 \" 的双引号被解释为文字双引号 (")。

要解析命令行参数,请访问此站点: http://msdn.microsoft.com/en-us/library/a1y7w461.aspx

和创建过程 API 访问这个:http://msdn.microsoft.com/en-us/library/windows/desktop/ms682425%28v=vs.85%29.aspx

你可以像这样形成一个由程序名+参数组成的字符串

wstring cmd;
cmd.assign(L""C:\Program Files\MyProgram.exe"  arg1 arg2 arg3 arg4");
if(!CreateProcess(NULL,(LPWSTR)cmd.c_str(),NULL,NULL,1,0,NULL,NULL,&si,&pi))
{
  return -1;
}

使用 ShellExecute(Ex)。控件要简单得多,并且由于我们有UAC,因此控件如何启动进程更容易。

使用ShellExecuteEx aou,如果需要,还可以获取进程句柄。

只有我的2美分。