एक उदाहरण है कि के लिए खोज रहे:मैं Windows निष्पादन योग्य लॉन्च करने के लिए C++ में CreateProcess को कैसे कॉल करूं?
- की शुरूआत एक EXE EXE के लिए
- वेट्स खत्म करने के लिए।
- निष्पादन योग्य समाप्त होने पर सभी हैंडल को उचित रूप से बंद कर देता है।
एक उदाहरण है कि के लिए खोज रहे:मैं Windows निष्पादन योग्य लॉन्च करने के लिए C++ में CreateProcess को कैसे कॉल करूं?
कुछ इस तरह:
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);
}
बस अपने निरंतर या कार्यक्रम युक्त चर के साथ argv[1]
की जगह http://msdn.microsoft.com/en-us/library/ms682512(VS.85).aspx
पर एक उदाहरण है।
#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 एक कंसोल अनुप्रयोग होने के लिए होता है, आप stdout और stderr पढ़ने में रुचि हो सकती है - उस के लिए, मैं विनम्रतापूर्वक आप पर गौर करेंगे इस उदाहरण:
http://support.microsoft.com/default.aspx?scid=kb;EN-US;q190351
यह कोड का एक कौर का एक सा है, लेकिन मैं इस कोड के रूपांतरों का उपयोग किया है अंडे और पढ़ने के लिए।
अर्ध-संबंधित नोट पर, यदि आप ऐसी प्रक्रिया शुरू करना चाहते हैं जिसमें आपकी वर्तमान प्रक्रिया से अधिक विशेषाधिकार हैं (कहें, एक व्यवस्थापक ऐप लॉन्च करना, जिसके लिए सामान्य उपयोगकर्ता के रूप में चल रहे मुख्य ऐप से व्यवस्थापक अधिकारों की आवश्यकता होती है) आप विस्टा पर CreateProcess() का उपयोग करके ऐसा नहीं कर सकते क्योंकि यह यूएसी संवाद को ट्रिगर नहीं करेगा (माना जाता है कि यह सक्षम है)। हालांकि, ShellExecute() का उपयोग करते समय यूएसी संवाद ट्रिगर किया जाता है।
यदि आप एक विंडोज जीयूआई एप्लीकेशन है तो इंतजार करने के लिए नीचे दिए गए कोड का उपयोग आदर्श नहीं है क्योंकि आपके आवेदन के लिए संदेश प्रसंस्करण नहीं हो रहे हैं। उपयोगकर्ता को ऐसा लगेगा कि आपका आवेदन लटका हुआ है।
WaitForSingleObject(&processInfo.hProcess, INFINITE)
कुछ अपरीक्षित कोड की तरह नीचे बेहतर रूप में यह विंडोज़ संदेश कतार प्रसंस्करण रखेंगे हो सकता है और आपके आवेदन उत्तरदायी रहेगा: मन में
//-- 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
का उपयोग कर सकते हैं इस परिदृश्य में आपको परेशानी में डाल दें। निम्नलिखित मेरी वेबसाइट पर एक टिप से फिसल गया है:
समस्या उत्पन्न होती है क्योंकि आपके एप्लिकेशन में एक विंडो है लेकिन संदेश पंप नहीं कर रही है। यदि स्पॉन्डेड एप्लिकेशन प्रसारण लक्ष्यों में से एक के साथ SendMessage को आमंत्रित करता है (HWND_BROADCAST या HWND_TOPMOST), तो SendMessage नए एप्लिकेशन पर वापस नहीं आ जाएगा जब तक कि सभी एप्लिकेशन ने संदेश को संभाला नहीं है - लेकिन आपका ऐप संदेश को संभाल नहीं सकता क्योंकि यह संदेश पंप नहीं कर रहा है .... इसलिए नया ऐप लॉक हो गया है, इसलिए आपका इंतजार कभी सफल नहीं होता .... डेडलॉक। (उदाहरण के लिए डीडीई पहल के लिए, किसी को अभी भी उस का उपयोग कर रहा है, तो)
आप पैदा की आवेदन पर पूर्ण नियंत्रण है, तो इस तरह के SendMessageTimeout बजाय SendMessage का उपयोग कर के रूप में उपायों ले जा सकते हैं, कर रहे हैं।लेकिन ऐसी स्थितियां हैं जो अंतर्निहित SendMessage प्रसारण का कारण बनती हैं जिन पर आपके पास कोई नियंत्रण नहीं है, उदाहरण के लिए SetSysColors API का उपयोग करना।
केवल सुरक्षित तरीके इस दौर कर रहे हैं:
MsgWaitForMultipleObjects
API का उपयोग करें।शायद यह सबसे पूरा है? http://goffconcepts.com/techarticles/development/cpp/createprocess.html
यहां एक नया उदाहरण है जो विंडोज़ 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
WaitForSingleObject लाइन होना चाहिए :: WaitForSingleObject (processInfo.hProcess, अनंत) (बिना 'और') – wimh
का प्रयोग क्यों :: WaitForSingleObject पर लेकिन अन्य API कॉल पर नहीं वैश्विक नामस्थान निर्दिष्ट करने के लिए? –
यह आदत का बल होगा –