دلفي - إغلاق العملية التي تم إنشاؤها في الخدمة برشاقة.(باستخدام tprocess / createProcess)

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

سؤال

لدي خدمة Windows مكتوبة بلغة دلفي والتي تقوم بتشغيل عدد من البرامج.

عند إيقاف الخدمة، أريد أيضًا إغلاق هذه البرامج.عندما تمت كتابة الخدمة في الأصل، كان هذا يعمل بشكل جيد، ولكن أعتقد أنني قمت بتحديث مكون tProcess والآن - لم يتم إغلاق البرامج الثانوية.

في tProcess - هذا هو الكود الذي يبدأ العمليات الجديدة.

  if CreateProcess( nil , PChar( FProcess.Command ) , nil , nil , False ,
    NORMAL_PRIORITY_CLASS , nil , Directory ,
    StartupInfo , ProcessInfo ) then
    begin
      if FProcess.Wait then
        begin
          WaitForSingleObject( ProcessInfo.hProcess , Infinite );
          GetExitCodeProcess( ProcessInfo.hProcess , ExitCode );
          if Assigned( FProcess.FOnFinished ) then
            FProcess.FOnFinished( FProcess , ExitCode );
        end;
      CloseHandle( ProcessInfo.hProcess );
      CloseHandle( ProcessInfo.hThread );
    end;

كل من الملفات التنفيذية التي يتم استدعاؤها بواسطة هذا هي برامج Windows GUI (مع وجود زر إغلاق في الأعلى).

عندما أقوم بإيقاف الخدمة، أريد أيضًا إيقاف (وليس إيقاف) البرامج التي قمت بتشغيلها عبر إجراء createProcess.

كيف يمكنك أن تفعل هذا؟

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

المحلول

وترغب في تعداد النوافذ المفتوحة التي تطابق ProcessId بك أطلقت وأقول لهؤلاء النوافذ لإغلاقه. وإليك بعض التعليمات البرمجية لذلك:

uses Windows;

interface   

function MyTerminateAppEnum(hHwnd:HWND; dwData:LPARAM):Boolean; stdcall;

implementation

function MyTerminateAppEnum(hHwnd:HWND; dwData:LPARAM):Boolean; 
var   
  vID:DWORD; 
begin   
  GetWindowThreadProcessID(hHwnd, @vID);   
  if vID = dwData then   
  begin
    PostMessage(hHwnd, WM_CLOSE, 0, 0); //tell window to close gracefully
    Result := False;  //can stop enumerating    
  end   
  else   
  begin
    Result := TRUE;  //keep enumerating until you find your id   
  end; 
end;

وبعد ذلك عليك أن ترغب في الاستفادة من هذا في التعليمات البرمجية عندما تريد اغلاق التطبيقات أطلق:

Procedure TerminateMe(YourSavedProcessInfo:TProcessInformation);
var
  vExitCode:UINT;
begin
  GetExitCodeProcess(YourSavedProcessInfo.hProcess, vExitCode);
  if (vExitCode = STILL_ACTIVE) then  //launched app still running..
  begin
    //tell it to close
    EnumWindows(@MyTerminateAppEnum, YourSavedProcessInfo.dwProcessId);

    if WaitForSingleObject(YourSavedProcessInfo.hProcess, TIMEOUT_VAL) <> WAIT_OBJECT_0 then
    begin
      if not TerminateProcess(YourSavedProcessInfo.hProcess, 0) then  //didn't close, try to terminate
      begin
         //uh-oh   Didn't close, didn't terminate..
      end;
    end;
  end;
  CloseHandle(YourSavedProcessInfo.hProcess);
  CloseHandle(YourSavedProcessInfo.hThread);
end;

نصائح أخرى

سأستخدم TJvCreateProcess مكون من JVCL والذي يلتف حول أي وظيفة ذات صلة بعملية Win32 بطريقة رائعة.تأتي هذه الإجابة من قسم Dont-touch-winapi-إلا إذا كان مطلوبًا بالفعل :-)

والطريقة العامة الوحيدة لوقف عملية هي استخدام TerminateProcess . ولكن هذا بقدر من رشيقة كما يمكنك الحصول عليها. لإغلاق بأمان عملية، تحتاج لنقول للعملية التي ترغب أن تتوقف، ومن ثم نأمل أن يطيع. لا توجد وسيلة للقيام بذلك بشكل عام، وإن كان.

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

هل يمكن استخدام EnumWindows للدورة من خلال جميع النوافذ و حدد تلك التي تنتمي إلى العملية الخاصة بك. (وهي تريد ان تكون تلك التي GetWindowThreadProcessId يعطي نفس العملية ID أن CreateProcess أعطاك).

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

يمكن برامج غير واجهة المستخدم الرسومية لديهم مشاكل مماثلة. قد يكون كافيا لمحاكاة ضغطة مفتاح Ctrl + C. قد قبض والتعامل مع هذا ضغطة بشكل مختلف، وإن كان. قد يكون لديك نظام القائمة التي تتوقع لك اكتب "Q" لإنهاء البرنامج.

وباختصار، لا يمكنك إغلاق برشاقة برنامج إلا إذا كنت تعرف مسبقا كيف يتوقع هذا البرنامج أن تكون مغلقة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top