簡體   English   中英

CreateProcess不傳遞命令行參數

[英]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.

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