簡體   English   中英

CreateProcess和命令行參數

[英]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中較舊的答案可能會使這個過程有點麻煩。

  1. CreateProcess參數1大部分是可選的,這對於第一個參數來說真的很奇怪。 如果您不想指定它,請使用NULL ,否則您應該閱讀非特定 文檔 ,了解如何在不將參數1設置為NULL時使用參數1。
  2. 如果將參數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.

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