回答
事情是這樣的:
STARTUPINFO info={sizeof(info)};
PROCESS_INFORMATION processInfo;
if (CreateProcess(path, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &info, &processInfo))
{
WaitForSingleObject(processInfo.hProcess, INFINITE);
CloseHandle(processInfo.hProcess);
CloseHandle(processInfo.hThread);
}
有一個在http://msdn.microsoft.com/en-us/library/ms682512(VS.85).aspx
一例只需更換argv[1]
與恆定或包含程序變量。
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
void _tmain(int argc, TCHAR *argv[])
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
if(argc != 2)
{
printf("Usage: %s [cmdline]\n", argv[0]);
return;
}
// Start the child process.
if(!CreateProcess(NULL, // No module name (use command line)
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;
}
// Wait until child process exits.
WaitForSingleObject(pi.hProcess, INFINITE);
// Close process and thread handles.
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
如果你的EXE恰好是一個控制檯應用程序,你可能有興趣在閱讀輸出和錯誤 - 對於這一點,我會虛心向您推薦下面這個例子:
http://support.microsoft.com/default.aspx?scid=kb;EN-US;q190351
這是一個有點代碼拗口,但我用這個代碼的變化產卵和閱讀。
在一個半相關的注意,如果你想開始有比你的當前進程更權限的進程(比如,啓動一個管理應用程序,這需要管理員權限,從運行作爲一個普通用戶的主要應用)你不能這樣做,使用在Vista上的CreateProcess(),因爲它不會觸發UAC對話框(假設已啓用)。不過,使用ShellExecute()時會觸發UAC對話框。
如果你的應用是那麼的Windows GUI應用程序使用下面的代碼做的等待並不理想,因爲您的應用程序的消息將不會得到處理。對用戶來說,它看起來像你的應用程序已掛起。下面
WaitForSingleObject(&processInfo.hProcess, INFINITE)
有點像未經測試代碼可能會更好,因爲它會繼續處理Windows消息隊列和應用程序將保持響應:記住
//-- wait for the process to finish
while (true)
{
//-- see if the task has terminated
DWORD dwExitCode = WaitForSingleObject(ProcessInfo.hProcess, 0);
if ( (dwExitCode == WAIT_FAILED )
|| (dwExitCode == WAIT_OBJECT_0)
|| (dwExitCode == WAIT_ABANDONED))
{
DWORD dwExitCode;
//-- get the process exit code
GetExitCodeProcess(ProcessInfo.hProcess, &dwExitCode);
//-- the task has ended so close the handle
CloseHandle(ProcessInfo.hThread);
CloseHandle(ProcessInfo.hProcess);
//-- save the exit code
lExitCode = dwExitCode;
return;
}
else
{
//-- see if there are any message that need to be processed
while (PeekMessage(&message.msg, 0, 0, 0, PM_NOREMOVE))
{
if (message.msg.message == WM_QUIT)
{
return;
}
//-- process the message queue
if (GetMessage(&message.msg, 0, 0, 0))
{
//-- process the message
TranslateMessage(&pMessage->msg);
DispatchMessage(&pMessage->msg);
}
}
}
}
熊,使用WaitForSingleObject
可以在這種情況下讓你陷入麻煩。以下是從我的網站上的一個提示中刪除:
問題出現是因爲您的應用程序有一個窗口,但不是泵送消息。如果生成的應用程序調用其中一個廣播目標(HWND_BROADCAST或HWND_TOPMOST)的SendMessage,則在所有應用程序都處理完消息之前,SendMessage將不會返回到新應用程序 - 但是您的應用程序無法處理消息因爲它是不抽的消息....所以新的應用程序鎖定,所以你的等待永遠不會成功....僵局。
如果你有過催生了應用程序的絕對控制權,那麼您可以採取的措施,如使用SendMessageTimeout,而不是SendMessage函數(例如,用於DDE灌頂,如果有人還在使用)。但有些情況會導致您無法控制的隱式SendMessage廣播,例如使用SetSysColors API。
唯一安全的方式這一輪是:
- 分裂出去的等待到一個單獨的線程,或
- 使用上等待超時和使用的PeekMessage在等待循環,以確保您抽取消息,或
- 使用
MsgWaitForMultipleObjects
API。
這是一個在Windows 10上工作的新例子。使用windows10 sdk時,您必須改用CreateProcessW。這個例子被評論,希望能夠自我解釋。
#ifdef _WIN32
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <cstdlib>
#include <string>
#include <algorithm>
class process
{
public:
static PROCESS_INFORMATION launchProcess(std::string app, std::string arg)
{
// Prepare handles.
STARTUPINFO si;
PROCESS_INFORMATION pi; // The function returns this
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
//Prepare CreateProcess args
std::wstring app_w(app.length(), L' '); // Make room for characters
std::copy(app.begin(), app.end(), app_w.begin()); // Copy string to wstring.
std::wstring arg_w(arg.length(), L' '); // Make room for characters
std::copy(arg.begin(), arg.end(), arg_w.begin()); // Copy string to wstring.
std::wstring input = app_w + L" " + arg_w;
wchar_t* arg_concat = const_cast<wchar_t*>(input.c_str());
const wchar_t* app_const = app_w.c_str();
// Start the child process.
if(!CreateProcessW(
app_const, // app path
arg_concat, // Command line (needs to include app path as first argument. args seperated by whitepace)
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());
throw std::exception("Could not create child process");
}
else
{
std::cout << "[ ] Successfully launched child process" << std::endl;
}
// Return process handle
return pi;
}
static bool checkIfProcessIsActive(PROCESS_INFORMATION pi)
{
// Check if handle is closed
if (pi.hProcess == NULL)
{
printf("Process handle is closed or invalid (%d).\n");
return FALSE;
}
// If handle open, check if process is active
DWORD lpExitCode = 0;
if(GetExitCodeProcess(pi.hProcess, &lpExitCode) == 0)
{
printf("Cannot return exit code (%d).\n", GetLastError());
throw std::exception("Cannot return exit code");
}
else
{
if (lpExitCode == STILL_ACTIVE)
{
return TRUE;
}
else
{
return FALSE;
}
}
}
static bool stopProcess(PROCESS_INFORMATION &pi)
{
// Check if handle is invalid or has allready been closed
if (pi.hProcess == NULL)
{
printf("Process handle invalid. Possibly allready been closed (%d).\n");
return 0;
}
// Terminate Process
if(!TerminateProcess(pi.hProcess,1))
{
printf("ExitProcess failed (%d).\n", GetLastError());
return 0;
}
// Wait until child process exits.
if(WaitForSingleObject(pi.hProcess, INFINITE) == WAIT_FAILED)
{
printf("Wait for exit process failed(%d).\n", GetLastError());
return 0;
}
// Close process and thread handles.
if(!CloseHandle(pi.hProcess))
{
printf("Cannot close process handle(%d).\n", GetLastError());
return 0;
}
else
{
pi.hProcess = NULL;
}
if(!CloseHandle(pi.hThread))
{
printf("Cannot close thread handle (%d).\n", GetLastError());
return 0;
}
else
{
pi.hProcess = NULL;
}
return 1;
}
};//class process
#endif //win32
- 1. CreateProcess如何找到可執行文件?
- 2. 如何在Windows上的C中的CreateProcess執行Python腳本?
- 3. 執行使用Powershell執行的C#可執行文件出錯
- 4. 從CreateProcess調用c中的msi文件
- 5. 用於Windows的可執行包裝的CreateProcess用法?
- 6. 使用CreateProcess運行遊戲可執行文件
- 7. 如何在Windows XP上使用Perl運行可執行文件?
- 8. 我正在編譯.c文件並獲取可執行文件。如何在Windows 8中執行exe文件
- 9. 如何從windows erlang .beam文件生成windows可執行文件?
- 10. CreateProcess執行批處理文件
- 11. 如何使用c執行mac OS x可執行文件iphone
- 12. 在Visual Studio中調試由可執行文件調用的C++文件
- 13. 如何在C程序運行時正確調用可執行文件?
- 14. 使用devenv調試C++可執行文件中的回調
- 15. 如何在被調用的可執行文件運行時調用和關閉?
- 16. 如何在C中使用twilio的可執行文件聊天#
- 17. 如何在windows中執行.r文件
- 18. 從ColdFusion應用程序調用Windows可執行文件(.exe)
- 19. 用於最小可執行文件的C++ Windows編譯器
- 20. 在Windows Vista上覆蓋C:\ Program \ MyProg中的可執行文件
- 21. 從我的可執行文件調用
- 22. C/C++的Windows - ExtractIcon(所有可執行文件
- 23. 使用CreateProcess執行rundll32.exe
- 24. 如何在linux上運行windows擴展名爲.exe的windows可執行文件
- 25. 如何使用C++獲取有關Windows可執行文件(.exe)的信息
- 26. windows批處理文件:在另一個目錄中調用可執行文件
- 27. 如何在測試中用可執行文件替換可執行文件?
- 28. 如何在使用VS2013在c#中運行可執行文件的進程中調試文件?
- 29. 如何在可執行文件完成時將可執行文件的輸出寫入文件?
- 30. 如何使用Pyserial製作Windows可執行文件?
的WaitForSingleObject的行應該是:: WaitForSingleObject的(processInfo.hProcess,INFINITE)(沒有 '&') – wimh 2008-11-27 21:32:29
爲什麼要用::對WaitForSingleObject的,但不是在其他API調用指定的全局命名空間? – 2008-11-30 13:30:49