كيف يمكنني الاتصال ::CreateProcess في c++ لإطلاق ويندوز للتنفيذ ؟

StackOverflow https://stackoverflow.com/questions/42531

  •  09-06-2019
  •  | 
  •  

سؤال

أبحث عن مثال على ذلك:

  1. تطلق EXE
  2. ينتظر EXE إلى النهاية.
  3. صحيح يغلق جميع مقابض عندما قابل للتنفيذ التشطيبات.
هل كانت مفيدة؟

المحلول

شيء من هذا القبيل:

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(مقابل.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 );
}

إذا كنت تطبيق ويندوز واجهة المستخدم الرسومية تطبيق ثم استخدام رمز أدناه للقيام الانتظار ليست مثالية كما الرسائل على التطبيق الخاص بك لن يكون الحصول على المعالجة.أن المستخدم سوف تبدو مثل التطبيق الخاص بك قد علقت.

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);
      }
    }
  }
}

إذا كان الخاص بك exe يحدث أن تكون وحدة التحكم التطبيق, كنت قد تكون مهتمة في قراءة المعياري و stderr -- لذلك سوف بتواضع أحيلكم إلى هذا المثال:

http://support.microsoft.com/default.aspx?scid=kb EN-US;q190351

انها قليلا من الفم من التعليمات البرمجية ، ولكن لقد استخدمت نماذج من هذا القانون أن تفرخ و قراءة.

على شبه المتعلقة ملاحظة إذا كنت تريد أن تبدأ عملية المزيد من الامتيازات من العملية الحالية (أقول إطلاق التطبيق المشرف الذي يتطلب حقوق المسؤول ، من التطبيق الرئيسي تشغيل كمستخدم عادي), لا يمكنك القيام بذلك باستخدام CreateProcess() على ويندوز فيستا لأنه لن يؤدي الحوار UAC (على افتراض أنه هو تمكين).UAC الحوار يتم تشغيلها عند استخدام ShellExecute () ، على الرغم من.

ولعل هذا هو الأكثر كاملة ؟ http://goffconcepts.com/techarticles/development/cpp/createprocess.html

نضع في اعتبارنا أن استخدام WaitForSingleObject يمكن أن تحصل في ورطة في هذا السيناريو.التالي هو مقصوص من طرف على موقع الويب الخاص بي:

المشكلة تنشأ بسبب التطبيق الخاص بك لديه نافذة ولكن ليس ضخ الرسائل.إذا ولدت تطبيق استدعاء SendMessage مع واحد من بث الأهداف (HWND_BROADCAST أو HWND_TOPMOST) ، ثم SendMessage لن يعود إلى التطبيق الجديد حتى جميع التطبيقات التعامل مع الرسالة ولكن التطبيق الخاص بك لا يمكن التعامل مع الرسالة لأنه ليس ضخ الرسائل....وبالتالي فإن التطبيق الجديد الأقفال حتى الانتظار لم ينجح....الجمود.

إذا كان لديك السيطرة المطلقة على ولدت التطبيق ، ثم هناك تدابير يمكن اتخاذها ، مثل استخدام SendMessageTimeout بدلا من SendMessage (مثلا ، بالنسبة DDE التلقين ، إذا كان أي شخص لا يزال يستخدم هذا).ولكن هناك الحالات التي تسبب الضمني SendMessage تبث أكثر من التي لديك أي سيطرة ، مثل استخدام SetSysColors API على سبيل المثال.

فقط طرق آمنة هذه الجولة هي:

  1. انشقت الانتظار في موضوع مستقل ، أو
  2. استخدام مهلة على الانتظار واستخدام مباشر في الانتظار حلقة لضمان ضخ الرسائل ، أو
  3. استخدام MsgWaitForMultipleObjects API.

هنا هو مثال جديد يعمل على نظام التشغيل ويندوز 10.عند استخدام windows10 sdk لديك لاستخدام CreateProcessW بدلا من ذلك.هذا المثال هو علق ونأمل النفس التفسيرية.

#ifdef _WIN32
#include <Windows.h>
#include <iostream>
#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", GetLastError());
                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
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top