2010-10-29 45 views
10

如何將路徑和空間傳遞給CreateProcess()函數?Windows API - 具有空間的CreateProcess()路徑

以下工作

STARTUPINFO si; 
      PROCESS_INFORMATION pi; 

      ZeroMemory(&si, sizeof(si)); 
      si.cb = sizeof(si); 
      ZeroMemory(&pi, sizeof(pi)); 

      if(!CreateProcess(_T("c:\\installer\\ew3d.exe"), // No module name (use command line) 
       _T("c:\\installer\\ew3d.exe /qr"),//argv[1],  // Command line 
       NULL,   // Process handle not inheritable 
       NULL,   // Thread handle not inheritable 
       FALSE,   // Set handle inheritance to FALSE 
       0,    // No creation flags 
       NULL,   // Use parent's environment block 
       NULL,   // Use parent's starting directory 
       &si,   // Pointer to STARTUPINFO structure 
       &pi)   // Pointer to PROCESS_INFORMATION structure 
       ) 
      { 
       printf("CreateProcess failed (%d).\n", GetLastError()); 
       return false; 
      } 

      //Wait until child process exits. 
      WaitForSingleObject(pi.hProcess, INFINITE); 

      // Close process and thread handles. 
      CloseHandle(pi.hProcess); 
      CloseHandle(pi.hThread); 

但是,如果使用的路徑與空間,如下面的代碼,它不工作。

CreateProcess(_T("c:\\master installer\\ew3d.exe"), // No module name (use command line) 
        _T("c:\\master installer\\ew3d.exe /qr"),//argv[1],  // Command line 
        NULL,   // Process handle not inheritable 
        NULL,   // Thread handle not inheritable 
        FALSE,   // Set handle inheritance to FALSE 
        0,    // No creation flags 
        NULL,   // Use parent's environment block 
        NULL,   // Use parent's starting directory 
        &si,   // Pointer to STARTUPINFO structure 
        &pi)   // Pointer to PROCESS_INFORMATION structure 
        ) 

和報價的命令,如下面沒有幫助過

CreateProcess(_T("\"c:\\master installer\\ew3d.exe\""), // No module name (use command line) 
        _T("\"c:\\master installer\\ew3d.exe\" /qr"),//argv[1],  // Command line 
        NULL,   // Process handle not inheritable 
        NULL,   // Thread handle not inheritable 
        FALSE,   // Set handle inheritance to FALSE 
        0,    // No creation flags 
        NULL,   // Use parent's environment block 
        NULL,   // Use parent's starting directory 
        &si,   // Pointer to STARTUPINFO structure 
        &pi)   // Pointer to PROCESS_INFORMATION structure 
        ) 

什麼是與空間的路徑傳遞正確的方式?

+0

剛剛發佈的代碼 - 不明白爲什麼它不會爲你 – 2010-10-29 19:08:23

+0

這是在Windows Vista上32我正在使用VS 2010.可以在不同的操作系統上以不同的方式運行 – 2010-10-30 05:53:38

回答

4

你的第三個片段是正確的,不知道爲什麼你有麻煩。 GetLastError()返回值在這裏很有用。但請注意,CreateProcess的第二個參數是一個LPTSTR,而不是一個LPCTSTR。換句話說,Windows可以寫回字符串。令人毛骨悚然,不是嗎?有足夠的理由可能使用ShellExecuteEx()代替。

+0

對於第三個片段,GetLastError()返回123,這意味着「文件名,目錄名稱或卷標語法不正確。」 – 2010-10-29 16:29:40

+0

不尋常。您使用的路徑*正如張貼或您是否是醫生? – 2010-10-29 17:14:00

+0

從我的測試應用程序中完全複製。 – 2010-10-30 03:52:43

2

您不需要在第一個和第二個參數中指定應用程序路徑。根據MSDN documentation,如果列出第一個參數中的應用程序名稱,則第二個參數應該只是命令行參數。否則,請將第一個參數設置爲NULL,然後在第二個參數中將應用程序名稱用引號引起來(如果它包含空格)。不知道爲什麼你的上一個列表不起作用。

+0

我從http://stackoverflow.com/questions/1135784/createprocess-doesnt-pass-command-line-arguments得到了想法(把兩個參數都放在完整路徑中)。事實上,我測試了它 - 如果我沒有在兩個參數中都放上完整路徑,它就會失敗。 – 2010-10-29 15:46:29

2

文檔不太清楚,但是如果您包含空格,您必須允許參數2定義完整路徑。

lpApplicationName參數可以是 NULL。在這種情況下,模塊名稱 必須是 lpCommandLine字符串中的第一個白色 空格分隔的令牌。如果您正在使用包含 空間的長文件名 ,請使用帶引號的字符串表示 文件名結尾和 參數開始;否則,文件名稱 不明確。

您是否試過這種差異?

CreateProcess(NULL, // No module name (use command line) 
       _T("\"c:\\master installer\\ew3d.exe\" /qr"),//argv[1],  // Command line 
       NULL,   // Process handle not inheritable 
       NULL,   // Thread handle not inheritable 
       FALSE,   // Set handle inheritance to FALSE 
       0,    // No creation flags 
       NULL,   // Use parent's environment block 
       NULL,   // Use parent's starting directory 
       &si,   // Pointer to STARTUPINFO structure 
       &pi)   // Pointer to PROCESS_INFORMATION structure 
      ) 

編輯:以下爲我工作(dwError爲0)。我的項目是用多字節字符集構建的。

LPTSTR szCmdLine = _tcsdup(TEXT(
    "\"C:\\Program Files\\adobe\\Reader 8.0\\reader\\acrord32.exe\" /qr")); 
CreateProcess(NULL, 
       szCmdLine, 
       NULL,   // Process handle not inheritable 
       NULL,   // Thread handle not inheritable 
       FALSE,   // Set handle inheritance to FALSE 
       0,    // No creation flags 
       NULL,   // Use parent's environment block 
       NULL,   // Use parent's starting directory 
       &si,   // Pointer to STARTUPINFO structure 
       &pi   // Pointer to PROCESS_INFORMATION structure 
      );  // This works. Downcasting of pointer to members in general is fine. 

DWORD error = GetLastError(); 
1

晚會有點晚。出於某種原因,我不能對Praetorian投票,但他是對的。我遇到了同樣的問題,並且使應用程序名稱無效。我也嘗試過在App Name &中的路徑,只是在第二個參數中的命令行params,無濟於事。

我在Win7 x64上。

CreateProcess(NULL,「\」exe文件路徑\「-x -y -z」,...);

適合我。

+0

這是有效的,但並不是100%正確的。我的答案(最高評分的答案)解釋了整個背景。上面接受的答案是錯誤的。 – 2015-06-16 16:24:21

17

作爲對另一個答案的迴應,示例#3是不是正確的一個。

問題是引號應該是而不是封裝了作爲CreateProcess的第一個參數傳遞的模塊路徑名。然而,引用SHOULD封裝了arg0(再次模塊路徑)爲命令行(CreateProcess的第二個參數)傳遞。

因此,正確再現是:

在爲我的工作確定一個編輯
CreateProcess(_T("c:\\master installer\\ew3d.exe"),  
        _T("\"c:\\master installer\\ew3d.exe\" /qr"), 
        NULL,   // Process handle not inheritable 
        NULL,   // Thread handle not inheritable 
        FALSE,   // Set handle inheritance to FALSE 
        0,    // No creation flags 
        NULL,   // Use parent's environment block 
        NULL,   // Use parent's starting directory 
        &si,   // Pointer to STARTUPINFO structure 
        &pi)   // Pointer to PROCESS_INFORMATION structure 
        ) 
+1

這是正確的答案。謝謝:) – Stretch 2015-06-15 06:15:14

+0

非常歡迎。我對這個主題有一些爭論。我在一個關於'接受'答案的辯論中提到了它。我被告知OP當時接受對他們最有用的一切。這聽起來不錯,直到你將它與其他政策進行比較,這些政策都是關於答案的準確性。 – 2017-07-26 23:18:45