簡體   English   中英

帶有命令行的C ++ Winapi CreateProcess問題

[英]C++ Winapi CreateProcess issue with command line

我以這種方式使用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

參數如下:

Param1: "C:\Users\myuser\Desktop\file.dll"
Param2: "file" (module name)
Param3: " " (blank)

因此完整的CommandLine字符串為:

"C:\Users\myuser\Desktop\file.dll" file " "

CreateProcess成功運行可執行文件並應用前兩個參數,但是當到達第三個參數時,它將引發錯誤

The specified process could not be found.
Function " " could not be called, due to " " doesn't exist in the DLL "(null)"

如何正確傳遞所需的參數?

當同時使用lpApplicationNamelpCommandLine ,即使您在lpApplication值中指定了可執行文件路徑,也需要將可執行文件路徑作為lpCommandLine值的第一個參數。 lpCommandLine是按lpCommandLine傳遞給生成的進程的,大多數RTL(尤其是基於C的RTL,但也有其他RTL)期望第一個命令行參數是可執行路徑,因為這是命令行控制台的操作方式。 甚至在CreateProcess()文檔中也提到了這一點:

如果lpApplicationNamelpCommandLine均為非NULL,則lpApplicationName指向的以Null終止的字符串指定要執行的模塊,而lpCommandLine指向的以Null終止的字符串指定命令行。 新進程可以使用GetCommandLine檢索整個命令行。 用C編寫的控制台進程可以使用argc和argv參數來解析命令行。 因為argv [0]是模塊名稱,所以C程序員通常將模塊名稱作為命令行中的第一個標記重復。

MSDN支持中也對此進行了介紹:

INFO:了解CreateProcess和命令行參數

創建32位進程時CreateProcess()的行為

情況1:

如果傳遞了ApplicationName參數,並且CommandLine參數為NULL,則ApplicationName參數也將用作命令行。 這並不意味着您可以在ApplicationName字符串中傳遞其他命令行參數。 例如,以下調用將失敗,並顯示“找不到文件”錯誤:

 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調用示例:

 CreateProcess( "c:\\\\MyApp.exe", "Param1 Param2 Param3", ...) 

MyApp的參數如下:

 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], ...);

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], ...);

或者,省略lpApplicationName並僅將完整的命令行指定為lpCommandLine

std::string CommandLine = "\"<exe path>\" <parameters>";
resultCreate = CreateProcessA(NULL, &CommandLine[0], ...);

std::wstring CommandLine = L"\"<exe path>\" <parameters>";
resultCreate = CreateProcessW(NULL, &CommandLine[0], ...);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM