Pro*_*oid 1 c++ parameters null winapi createprocess
我正在使用CreateProcess这种方式:
resultCreate = CreateProcess(Command, CommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
//"Command" contains the executable file to execute
//"CommandLine" contains the parameters to pass to that executable
Run Code Online (Sandbox Code Playgroud)
参数如下:
Param1: "C:\Users\myuser\Desktop\file.dll"
Param2: "file" (module name)
Param3: " " (blank)
Run Code Online (Sandbox Code Playgroud)
所以完整的命令行字符串将是:
"C:\Users\myuser\Desktop\file.dll" file " "
Run Code Online (Sandbox Code Playgroud)
CreateProcess 成功运行可执行文件并应用前两个参数,但是当到达第三个时,它会抛出错误
The specified process could not be found.
Function " " could not be called, due to " " doesn't exist in the DLL "(null)"
Run Code Online (Sandbox Code Playgroud)
如何正确传递所需的参数?
当同时使用lpApplicationName和 时lpCommandLine,您需要将可执行路径作为lpCommandLine值的第一个参数包含在内,即使您在lpApplication值中指定了可执行路径。该lpCommandLine原样传递是衍生的进程,大多数RTLS(尤其是基于C-RTLS,但其他人也一样)预计第一个命令行参数是可执行文件的路径,因为这是命令行控制台是如何运作的。这甚至在CreateProcess()文档中提到:
如果两个lpApplicationName和lpCommandLine是非NULL,则空终止字符串指向lpApplicationName指定执行的模块,并且通过指向空终止字符串lpCommandLine指定命令行。新进程可用于
GetCommandLine检索整个命令行。用 C 编写的控制台进程可以使用 argc 和 argv 参数来解析命令行。因为 argv[0] 是模块名称,C 程序员通常在命令行中重复模块名称作为第一个标记。
这也涵盖在 MSDN 支持中:
创建 32 位进程时 CreateProcess() 的行为
情况1:
如果传递了 ApplicationName 参数并且 CommandLine 参数为 NULL,则 ApplicationName 参数也用作 CommandLine。这并不意味着您可以在 ApplicationName 字符串中传递额外的命令行参数。例如,以下调用将失败并显示“找不到文件”错误:
Run Code Online (Sandbox Code Playgroud)CreateProcess( "c:\\MyApp.exe Param1 Param2", NULL, ... )案例2:
另一方面,如果 CommandLine 参数为非 NULL 且 ApplicationName 参数为 NULL,则 API 会尝试从 CommandLine 参数中提取应用程序名称。
案例3:
当您将有效的字符串指针传递给 ApplicationName 和 CommandLine 参数时,CreateProcess() 函数的灵活性(以及可能的混淆点)就会出现。这允许您指定要执行的应用程序以及传递给应用程序的完整命令行。人们可能认为传递给创建的应用程序的命令行是 ApplicationName 和 CommandLine 参数的组合,但事实并非如此。因此,由 CreateProcess 创建的进程可以接收其 .exe 名称以外的值作为其“argv[0]”参数。以下是产生这种“异常”行为的调用 CreateProcess 的示例:
Run Code Online (Sandbox Code Playgroud)CreateProcess( "c:\\MyApp.exe", "Param1 Param2 Param3", ...)MyApp 的参数如下:
Run Code Online (Sandbox Code Playgroud)argv[0] == "Param1" argv[1] == "Param2" argv[2] == "Param3"注意:ANSI 规范要求 argv[0] 应等于应用程序名称,但 CreateProcess 为调用应用程序提供了覆盖 32 位进程的此规则的灵活性。
第 3 种情况适用于您的情况。
使用类似这样的东西:
std::string Command = "<exe path>";
std::string CommandLine = "\"" + Command + "\" <parameters>";
// std::string::c_str() returns a const pointer. The first parameter
// of CreateProcessA() is const, but the second parameter must be a
// non-const pointer to writable memory, because CreateProcessW() can
// modify the data...
//
resultCreate = CreateProcessA(Command.c_str(), &CommandLine[0], ...);
Run Code Online (Sandbox Code Playgroud)
std::wstring Command = L"<exe path>";
std::wstring CommandLine = L"\"" + Command + L"\" <parameters>";
// std::wstring::c_str() returns a const pointer. The first parameter
// of CreateProcessW() is const, but the second parameter must be a
// non-const pointer to writable memory, because CreateProcessW() can
// modify the data...
//
resultCreate = CreateProcessW(Command.c_str(), &CommandLine[0], ...);
Run Code Online (Sandbox Code Playgroud)
或者,省略lpApplicationName并将完整的命令行指定为lpCommandLine:
std::string CommandLine = "\"<exe path>\" <parameters>";
resultCreate = CreateProcessA(NULL, &CommandLine[0], ...);
Run Code Online (Sandbox Code Playgroud)
std::wstring CommandLine = L"\"<exe path>\" <parameters>";
resultCreate = CreateProcessW(NULL, &CommandLine[0], ...);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2445 次 |
| 最近记录: |