سؤال

لقد قمت بإنشاء عملية باستخدام CreateProcess().هذا هو الرمز:

STARTUPINFO si = {0};
PROCESS_INFORMATION pi = {0};
result = CreateProcess("C:\\AP\\DatabaseBase\\dbntsrv.exe", NULL, NULL, NULL, FALSE, 0, NULL, "C:\\ADP\\SQLBase", &si, &pi)

كيف يمكنني الحصول على المقبض ومعرف العملية لهذه العملية المحددة؟واستخدامها في نهاية المطاف لإغلاق هذه العملية؟
شكرًا لك.

هل كانت مفيدة؟

المحلول

في الهيكل pi لقد حصلت:

typedef struct _PROCESS_INFORMATION {
    HANDLE hProcess;
    HANDLE hThread;
    DWORD  dwProcessId;
    DWORD  dwThreadId;
} PROCESS_INFORMATION, *LPPROCESS_INFORMATION;

المعلمة الأولى هي مؤشر العملية.

يمكنك استخدام هذا المقبض لإنهاء العملية:

BOOL WINAPI TerminateProcess(
    __in  HANDLE hProcess,
    __in  UINT uExitCode
);

ح العملية [في]
مؤشر للعملية المراد إنهاؤها.

يجب أن يتمتع المقبض بحق الوصول إلى PROCESS_TERMINATE.لمزيد من المعلومات، راجع أمان العملية وحقوق الوصول.

uExitCode [في]
رمز الخروج الذي ستستخدمه العملية والمواضيع التي تم إنهاؤها نتيجة لهذا الاستدعاء.استخدم الدالة GetExitCodeProcess لاسترداد قيمة الخروج الخاصة بالعملية.استخدم الدالة GetExitCodeThread لاسترداد قيمة الخروج الخاصة بمؤشر الترابط.

نصائح أخرى

يتم إرجاع مؤشر العملية في قبول المعلومات بناء، pi عامل.

ال إنهاء العملية () يمكن استخدام الوظيفة لإنهاء العملية.ومع ذلك، يجب أن تفكر في سبب حاجتك إلى إيقاف العملية وسبب عدم إمكانية إيقاف التشغيل بشكل سلس.

لاحظ أنك بحاجة إلى ضبط cb عضو في si قبل الاتصال CreateProcess():

si.cb = sizeof(STARTUPINFO);

يحرر:

لقمع نافذة وحدة التحكم حدد CREATE_NO_WINDOW, ، كما علم الخلق (الحجّة السادسة) في CreateProcess() يتصل.

تحرير (2):

لقمع النافذة حاول تعيين الأعضاء التاليين لـ معلومات بدء التشغيل هيكل قبل الدعوة CreateProcess():

STARTUPINFO si = {0};
si.cb          = sizeof(STARTUPINFO);
si.dwFlags     = STARTF_USESHOWWINDOW;
si.wShowWindow = FALSE;

تم شرح هذا بالتفصيل في MSDN:

إذا كانت النتيجة غير صفرية (مما يعني أنها نجحت) فستحصل على المقبض والمعالجة في الملف pi بناء.

من أجل قتل العملية التي يمكنك استخدامها إنهاء العملية

STARTUPINFOA siStartupInfo;
PROCESS_INFORMATION piProcessInfo;
memset(&siStartupInfo, 0, sizeof(siStartupInfo));
memset(&piProcessInfo, 0, sizeof(piProcessInfo));
siStartupInfo.cb = sizeof(siStartupInfo);

DWORD dwExitCode = 0;
if (CreateProcess(prgName.c_str(),
                (LPSTR) parameters.c_str(), 
                0, 
                0, 
                false,
                CREATE_DEFAULT_ERROR_MODE, 
                0, 
                0,
                &siStartupInfo, 
                &piProcessInfo) != false)
{       
    dwExitCode = WaitForSingleObject(piProcessInfo.hProcess, (time_in_ms));
}
else
{        
    return GetLastError(); //return error or do smething else
}

CloseHandle(piProcessInfo.hProcess);
CloseHandle(piProcessInfo.hThread);

piProcessInfo.hProcess هو مقبض العملية.

ويتفورسينجليوبجيكت:ينتظر حتى يصبح الكائن المحدد في حالة الإشارة أو انقضاء الفاصل الزمني للمهلة.

بعد ذلك (time_in_ms) سيتم إغلاق العملية.

إغلاق العملية بشكل نظيف

لإغلاق العملية بشكل نظيف، يجب عليك إرسال إشارة إغلاق أولاً:

كيفية إنهاء تطبيق "بشكل نظيف" في Win32.

إذا كان لا بد من إيقاف عملية ما، فاتبع الخطوات التالية:

  1. قم بنشر WM_CLOSE على كافة نوافذ المستوى الأعلى المملوكة للعملية التي تريد إيقاف تشغيلها.تستجيب العديد من تطبيقات Windows لهذه الرسالة عن طريق إيقاف التشغيل.

    ملحوظة:تعتمد استجابة تطبيق وحدة التحكم لـ WM_CLOSE على ما إذا كان قد قام بتثبيت معالج تحكم أم لا.

    استخدم EnumWindows() للعثور على مقابض النوافذ المستهدفة.في وظيفة رد الاتصال الخاصة بك، تحقق لمعرفة ما إذا كان معرف عملية Windows يتطابق مع العملية التي تريد إيقاف تشغيلها.يمكنك القيام بذلك عن طريق استدعاء GetWindowThreadProcessId().بمجرد إنشاء تطابق، استخدم PostMessage() أو SendMessageTimeout() لنشر رسالة WM_CLOSE إلى النافذة.

  2. استخدم WaitForSingleObject() لانتظار مؤشر العملية.تأكد من الانتظار بقيمة المهلة، نظرًا لوجود العديد من المواقف التي لن يقوم فيها WM_CLOSE بإيقاف تشغيل التطبيق.تذكر أن تجعل المهلة طويلة بما يكفي (إما باستخدام WaitForSingleObject() أو باستخدام SendMessageTimeout()) بحيث يتمكن المستخدم من الاستجابة لأية مربعات حوار تم إنشاؤها استجابة لرسالة WM_CLOSE.

  3. إذا كانت القيمة المرجعة هي WAIT_OBJECT_0، فهذا يعني أن التطبيق أغلق نفسه بشكل نظيف.إذا كانت القيمة المرجعة هي WAIT_TIMEOUT، فيجب عليك استخدام TerminateProcess() لإيقاف تشغيل التطبيق.

    ملحوظة:إذا كنت تحصل على قيمة إرجاع من WaitForSingleObject() بخلاف WAIT_OBJECT_0 أو WAIT_TIMEOUT، فاستخدم GetLastError() لتحديد السبب.

باتباع هذه الخطوات، فإنك تمنح التطبيق أفضل فرصة ممكنة لإيقاف التشغيل بشكل نظيف (بصرف النظر عن IPC أو تدخل المستخدم).

انظر هذه الإجابة للحصول على الكود.

إنهاء العملية

إذا كنت لا تهتم بالإغلاق النظيف، فيمكنك استخدامه TerminateProcess().ومع ذلك، فمن المهم أن نلاحظ ذلك TerminateProcess() غير متزامن؛يبدأ الإنهاء ويعود على الفور.إذا كنت تريد التأكد من إنهاء العملية، فاتصل بـ WaitForSingleObject() وظيفة مع مؤشر لهذه العملية.

TerminateProcess(pi.hProcess, 0);

// 500 ms timeout; use INFINITE for no timeout
const DWORD result = WaitForSingleObject(pi.hProcess, 500);
if (result == WAIT_OBJECT_0) {
    // Success
}
else {
    // Timed out or an error occurred
}

CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);

لا يغلق، فقط انتظر حتى تنتهي

إذا كانت العملية ستنتهي من تلقاء نفسها، فبدلاً من إنهائها يمكنك الانتظار حتى تنتهي.

WaitForSingleObject(pi.hProcess, INFINITE);

CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top