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

时间:2013-10-16 08:32:35

标签: c++ winapi visual-c++ mfc

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

我创建了以下过程:

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

szCmdline是变量,它包含应用程序的完整路径。

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

谢谢,

4 个答案:

答案 0 :(得分:5)

CreateProcess同时包含lpApplicationName和szCommandLine参数。您必须至少传递一个参数。但是出于安全原因,你应该通过这两个。

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

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

  • 如果您为szCommandLine传递NULL,系统将使用lpApplicationName

因此命令行是命令行。如果您有要传递给命令的参数,请将它们放在命令行上。

  

如果lpApplicationName为NULL,则为第一个以空格分隔的标记   命令行指定模块名称。如果你使用很长时间   包含空格的文件名,使用带引号的字符串来指示位置   文件名结束,参数开始(参见解释)   lpApplicationName参数)。

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

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

例如,如果您的程序为C:\Program Files\My Application\Program.exe且参数为/the /arguments,则应将lpApplicationName设置为"C:\Program Files\My Application\Program.exe",并将szCmdline设置为"C:\Program Files\My Application\Program.exe" /the /arguments

安全问题是什么?

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

答案 1 :(得分:3)

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

和creatprocess API访问:http://msdn.microsoft.com/en-us/library/windows/desktop/ms682425%28v=vs.85%29.aspx

答案 2 :(得分:1)

您可以形成一个由程序名+参数组成的字符串,如下所示

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;
}

答案 3 :(得分:0)

使用ShellExecute(例如)。控件更简单,因为我们有UAC控件如何启动进程更容易。

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

只是我的2分。