[英]CreateProcess doesn't pass command line arguments
您好我有以下代碼,但它沒有按預期工作,無法弄清楚問題是什么。
基本上,我正在執行一個進程(一個.NET進程)並傳遞它的命令行參數,它由CreateProcess()成功執行但CreateProcess()沒有傳遞命令行參數
我在這做錯了什么?
int main(int argc, char* argv[])
{
PROCESS_INFORMATION ProcessInfo; //This is what we get as an [out] parameter
STARTUPINFO StartupInfo; //This is an [in] parameter
ZeroMemory(&StartupInfo, sizeof(StartupInfo));
StartupInfo.cb = sizeof StartupInfo ; //Only compulsory field
LPTSTR cmdArgs = "name@example.com";
if(CreateProcess("D:\\email\\smtp.exe", cmdArgs,
NULL,NULL,FALSE,0,NULL,
NULL,&StartupInfo,&ProcessInfo))
{
WaitForSingleObject(ProcessInfo.hProcess,INFINITE);
CloseHandle(ProcessInfo.hThread);
CloseHandle(ProcessInfo.hProcess);
printf("Yohoo!");
}
else
{
printf("The process could not be started...");
}
return 0;
}
編輯:嘿,還有一件事,如果我像這樣傳遞我的cmdArgs
:
// a space as the first character
LPTSTR cmdArgs = " name@example.com";
然后我得到錯誤,然后CreateProcess返回TRUE
但我的目標進程沒有執行。
Object reference not set to an instance of an object
你應該在參數也指定模塊名稱: LPTSTR cmdArgs = "App name@example.com";
它應該是整個命令行(包括argv [0])。
如果CreateProcess()
的第一個參數是非NULL,它將使用它來定位要啟動的圖像。
如果它為NULL,它將解析第二個參數以嘗試從第一個令牌啟動可執行文件。
在任何一種情況下,C運行時都將使用第二個參數來填充argv
數組。 因此該參數的第一個標記顯示在argv[0]
。
您可能需要以下內容(我已將smtp.exe程序更改為echoargs.exe - 一個簡單的實用程序,我必須幫助弄清楚這種問題):
int main(int argc, char* argv[])
{
PROCESS_INFORMATION ProcessInfo; //This is what we get as an [out] parameter
STARTUPINFO StartupInfo; //This is an [in] parameter
char cmdArgs[] = "echoargs.exe name@example.com";
ZeroMemory(&StartupInfo, sizeof(StartupInfo));
StartupInfo.cb = sizeof StartupInfo ; //Only compulsory field
if(CreateProcess("C:\\util\\echoargs.exe", cmdArgs,
NULL,NULL,FALSE,0,NULL,
NULL,&StartupInfo,&ProcessInfo))
{
WaitForSingleObject(ProcessInfo.hProcess,INFINITE);
CloseHandle(ProcessInfo.hThread);
CloseHandle(ProcessInfo.hProcess);
printf("Yohoo!");
}
else
{
printf("The process could not be started...");
}
return 0;
}
這是我從該程序得到的輸出:
echoargs.exe name@example.com
[0]: echoargs.exe
[1]: name@example.com
Yohoo!
看起來您沒有正確使用CreateProcess,請參閱http://msdn.microsoft.com/en-us/library/ms682425%28VS.85%29.aspx 。
要執行的命令行。 此字符串的最大長度為32,768個字符,包括Unicode終止空字符。 如果lpApplicationName為NULL,則lpCommandLine的模塊名稱部分限制為MAX_PATH字符。
lpCommandLine參數可以為NULL。 在這種情況下,該函數使用lpApplicationName指向的字符串作為命令行。
如果lpApplicationName和lpCommandLine都是非NULL,則lpApplicationName指向的以null結尾的字符串指定要執行的模塊,lpCommandLine指向的以null結尾的字符串指定命令行 。 新進程可以使用GetCommandLine來檢索整個命令行。 用C編寫的控制台進程可以使用argc和argv參數來解析命令行。 因為argv [0]是模塊名稱,所以C程序員通常會重復模塊名稱作為命令行中的第一個標記。
所以在你的情況下,你需要這個作為命令參數,並且應該為第一個參數傳遞NULL以獲得你想要的行為。
// NOTE THE Null-Terminated string too!
LPTSTR cmdArgs = "D:\\email\\smtp.exe name@example.com\0";
以下是Zeus IDE用於運行外部進程的代碼的簡化版本:
bool createProcess(const char *pszTitle, const char *pszCommand)
{
STARTUPINFO StartInfo;
memset(&StartInfo, 0, sizeof(StartInfo));
StartInfo.cb = sizeof(StartInfo);
StartInfo.lpTitle = (pszTitle) ? (char *)pszTitle : (char *)pszCommand;
StartInfo.wShowWindow = SW_NORMAL;
StartInfo.dwFlags |= STARTF_USESHOWWINDOW;
if (CreateProcess(0, (char *)pszCommand,
0, 0, TRUE,
CREATE_NEW_PROCESS_GROUP, 0, 0,
&StartInfo, &ProcessInfo))
{
lErrorCode = 0;
}
else
{
lErrorCode = GetLastError();
}
return (lErrorCode == 0);
}
pszCommand將是完整的可執行路徑和文件名和參數,例如:
pszCommand = "D:\\email\\smtp.exe name@example.com";
據我所知,兩者之間唯一真正的區別是,在Zeus示例中, dwCreationFlags參數設置為CREATE_NEW_PROCESS_GROUP值。
嘗試這個:
LPTSTR cmdArgs = "name@example.com";
CString szcmdline("D:\\email\\smtp.exe");
szcmdline += _T(" ") + cmdArgs ;
//Leave first param empty and pass path + argms in
if(CreateProcess(NULL, szcmdline, second
您可以添加空格作為cmdArgs字符串的第一個字符:
LPTSTR cmdArgs = " name@example.com";
顯然,Windows將第二個參數字符串附加到第一個參數表示的應用程序名稱,結果作為命令行參數傳遞給可執行文件。 因此,添加空格將正確地分隔參數。
此函數的Unicode版本CreateProcessW可以修改此字符串的內容。 因此,此參數不能是只讀內存的指針(例如const變量或文字字符串)。 如果此參數是常量字符串,則該函數可能會導致訪問沖突。
因此,您可以嘗試使用LPTSTR cmdArgs = _tcsdup("name@example.com")
。
另一個問題是:目標進程如何讀取參數? 使用argv [0]作為應用程序名稱? 然后你應該將應用程序名稱附加為第一個參數。
您沒有為字符串分配內存。
代替:
LPTSTR cmdArgs = "name@example.com";
嘗試:
TCHAR cmdArgs[] = "name@example.com";
編輯:然后致電:
CreateProcess("D:\\email\\smtp.exe", &cmdArgs[0], ...
這將在堆棧上創建一個本地數組,然后將指針傳遞給該數組。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.