0

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

我将过程创建为:

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

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

任何想法如何通过此过程传递参数。

谢谢,

4

4 回答 4

5

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

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

  • 如果您通过NULLfor lpApplicationName,系统将尝试在 中找到可执行文件szCommandLine,并将使用它。

  • 如果为 传递 NULL szCommandLine,系统将同时使用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 参数,则不会发生这种情况。

于 2013-10-16T08:57:05.940 回答
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

于 2013-10-17T12:49:08.970 回答
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;
}
于 2013-10-16T09:43:58.477 回答
0

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

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

只是我的 2 美分。

于 2013-10-16T09:09:13.980 回答