[英]CreateProcess and command line arguments
背景信息: Windows 7,Visual C ++ 2010 Express
問題: CreateProcess()通過'無效的命令行參數'繼續返回
說明:我正在編寫一段使用Windows API的CreateProcess調用外部程序的代碼。 到目前為止,我已接到使用一個外部程序的電話:
if( !CreateProcess( "C:\\Temp\\convert.exe",
t_str, // Arguments
...
}
//where t_str is " C:\\img1.jpeg C:\\img1.pgm" (ImageMagick if you're wondering).
即使我將所有數據都推送到Windows字符串和指針中,我也可以完美地工作。 所以我復制了CreateProcess()的所有修改,以便對另一個外部程序進行另一次調用:
if( !CreateProcess( "C:\\Temp\\sift.exe",
t_str2, // Arguments
...
}
//where t_str2 is ` < C:\\img1.pgm > C:\\img1.key`
基本上,一些非常相似,但所有變量名稱都已更改(因為我有兩個調用運行串行)。 這就是問題所在; 這不會運行,而是打印出“無效的命令行參數:<C:\\ img1.pgm”。 當然,這個命令在命令提示符下工作正常,但在我的代碼中沒有。
我將t_str2切換到其他一些不太復雜的東西(因為我知道sift.exe如何工作),我得到了相同的結果。 當我只進行篩選而不是轉換時,會發生同樣的事情。
問題:可能導致此問題的原因是什么? 我該怎么做才能進一步調試這個問題? 關於我正在使用的方法的替代方案的任何建議? 任何幫助表示贊賞。 我可以提供進一步的代碼,但它非常直接,並沒有太多可能出錯。
您不能直接使用命令行重定向運算符和CreateProcess()
。 您必須生成cmd.exe的實例並將操作符傳遞給它,例如:
CreateProcess( "C:\\windows\\system32\\cmd.exe", t_str2, ...))
其中t_str2
是"/CC:\\\\Temp\\\\sift.exe < C:\\\\img1.pgm > C:\\\\img1.key"
。 可以通過讀取%COMSPEC%
環境變量來確定cmd.exe的實際路徑。
在第二個示例中,您嘗試使用標准輸入和重定向,這是命令行應用程序的符號。 但它們不是有效的程序參數。 如果你想使用重定向,你應該打開管道並手動讀/寫輸入/輸出文件。 在這里,您可以找到如何使用輸入/輸出重定向實現流程創建的示例。
CreateProcess
有一些煩人的陷阱,如果你還沒有引用官方文檔,那么Stack Exchange中較舊的答案可能會使這個過程有點麻煩。
CreateProcess
參數1大部分是可選的,這對於第一個參數來說真的很奇怪。 如果您不想指定它,請使用NULL
,否則您應該閱讀非特定 文檔 ,了解如何在不將參數1設置為NULL
時使用參數1。 NULL
,則應用程序需要是參數2的第一部分。 再次感謝雷米清除我最初答案中的奇怪行為。
此代碼示例僅需要Windows上的基本VC ++編譯器,並且能夠在桌面上創建和存儲將由記事本打開的文件。
如果這不實用,請隨意使用%temp%
或其他位置放置測試文件。 該應用程序將一直運行,直到您關閉notepad.exe。 這也處理獲取和返回退出代碼。 如果您不希望它在退出之前無限期運行,則需要更新WaitForSingleObject
行。
#include <Windows.h>
int main()
{
STARTUPINFOA startup_info = { 0 };
LPSTARTUPINFOA p_startup_info = &startup_info;
PROCESS_INFORMATION proc_info = { 0 };
LPPROCESS_INFORMATION p_proc_info = &proc_info;
char command_line[] =
"C:\\Windows\\System32\\cmd.exe /C notepad.exe \"%USERPROFILE%\\Desktop\\test.txt\"";
bool process_created = CreateProcess(
NULL,
command_line,
NULL,
NULL,
FALSE,
DETACHED_PROCESS,
NULL,
NULL,
p_startup_info,
p_proc_info
);
if (!process_created) { return -3; }
DWORD process_exit;
WaitForSingleObject(proc_info.hThread, INFINITE);
GetExitCodeProcess(p_proc_info->hProcess, &process_exit);
return (int)process_exit;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.