easyDelphi Q&A
0 تصويتات
34 مشاهدات

السلام عليكم لدي سؤال اذ امكن 
لدي الكود التالي 
if sCheckBox14.Checked then
ShellExecute(0,nil, 'cmd.exe','/c start /wait Apps\browser\Firefox.exe -ms',nil, SW_hide) ;
end;
نريد تثبيت برنامج كما هو واضح ./المشكل انه اريد انتظار الى حين انتهاء البرنامج من التثبيت ثم اقلاع برنامج اخر للتثبيت ايضا 
كيف يتم الانتضار في هذه الحالة .ممكن مثال ان امكن بأبسط الطرق ربي يجازيكم خير.

سُئل في تصنيف vcl بواسطة (1,410 نقاط) | 34 مشاهدات
 

1 إجابة واحدة

+1 تصويت
أفضل إجابة

دعنا نسمي البرنامج المنفذ ب"A" و البرنامج الذي نريد تنفيذه بواسطة "A" و ليكن مثلا "B"

1) بإمكانك إستعمال الوظيفتين : "ShellExecuteEx " أو "CreateProcess" و أبسطهما الأولى كالآتي:

أولا هذه الوظيفة "ShellExecuteEx "هي نفس الوظيفة "ShellExecute" لكنها موسعة "Extended" فهي توفر تفاصيل أكثر لهاندل البرنامج "B" و من أهمها الهاندل بروسس "HProcess" أي حالة البرنامج في الذاكرة (RAM) أو بإختصار هل البرنامج هو في قائمة "TaskManager" أو لا و بهذا نستطيع إنتظاره إستنادا لهذه الخاصية و معرفة هل إنتهى لتكملة باقي المهام ... فلابد من مراقبة الهاندل بروسس "Handle Process" الخاص بالبرنامج "B" من طرف برنامجك "A" مباشرة بعد تنفيذه بواسطة الوظيفة "ShellExecuteEx" و ذلك بأن نظيف حلقة أو بوكل الإنتظار و المراقبة للهاندل بروسس في كل مرة مع مراعاة عدم تشنج البرنامج المنفذ "A" و ذلك بواسطة الأداة "while" أو الأداة "Repeat" مع البروسيديور "Application.ProcessMessages". نطلب فيه التحقق من حالة البروسس هاندل  في الذاكرة فقط بإستعمال الوظيفة "WaitForSingleObject

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

ثانيا : بعد كل هذا عليك بدمج كل هذه الخطوات ضمن وظيفة مهمتها التنفيذ و المراقبة و ليكن إسمها مثلا : "ExecAppWait" و لها برامترات أبرزها إسم البرنامج الخارجي و ليكن بإسم "AppName" و "Params" هي البرامترات الخاصة بالتنفيذ .

unit ExecWait;

interface

uses
  Classes, Windows, SysUtils, Forms, ShellAPI;

function ExecAppWait(AppName, Params: string): Boolean ;

implementation

{ Execute an external application APPNAME.
  Pass optional parameters in PARAMS, separated by spaces.
  Wait for completion of the application.
  Returns FALSE if the application could not be launched.
}
function ExecAppWait(AppName, Params: string): Boolean;
var
  { Structure containing and receiving info about the application that
    you want to launch }
  ShellExInfo: TShellExecuteInfo;
begin
  { Initialize ShellExInfo }
  FillChar(ShellExInfo, SizeOf(ShellExInfo), 0); // fill with empty values
  with ShellExInfo do begin            // set desired values
    cbSize := SizeOf(ShellExInfo);
    fMask  := see_Mask_NoCloseProcess;
    Wnd    := Application.Handle;
    lpFile := PChar(AppName);
    nShow  := sw_ShowNormal;
    lpParameters := PChar(Params);
  end;

  { If no error, ShellExecuteEx will return TRUE, else FALSE }
  Result := ShellExecuteEx(@ShellExInfo);

  { If no error, wait in this loop until the process ends }
  if Result then
    while WaitForSingleObject(ShellExInfo.HProcess, 100) = WAIT_TIMEOUT do begin
      Application.ProcessMessages; // give processor time to other tasks
      if Application.Terminated then
        Break;
    end;
end;

end.

ملاحظة :

لمعلومات أكثر يرجى تصفح المصدر هنا.

النتيجة:

لتحميل المثال الرابط هنا.

وفي الأخير حظا طيبا wink

تم الرد عليه بواسطة (15,020 نقاط)
مختارة بواسطة

ملاحظة:

بإمكانك تحديث الكود أعلاه بالكود التالي من طرف "Remy Lebeau"

var
  ExecInfo: TShellExecuteInfo;
begin
  ZeroMemory(@ExecInfo, SizeOf(ExecInfo));
  with ExecInfo do
  begin
    cbSize := SizeOf(ExecInfo);
    fMask := SEE_MASK_NOCLOSEPROCESS;
    Wnd := AWindow;
    lpVerb := 'runas';
    lpFile := PChar(APath);
    lpParameters := PChar(AParams);
    lpDirectory := PChar(AWorkDir);
    nShow := SW_NORMAL;
  end;
  Result := ShellExecuteEx(@ExecInfo);
  if Result and Wait then
  begin
    if ExecInfo.hProcess <> 0 then // no handle if the process was activated by DDE
    begin
      repeat
        if MsgWaitForMultipleObjects(1, ExecInfo.hProcess, FALSE, INFINITE, QS_ALLINPUT) = (WAIT_OBJECT_0+1) then
          Application.ProcessMessages
        else
          Break;
      until False;
      CloseHandle(ExecInfo.hProcess);
    end;
  end; 
end;

مصدر مايكروسفت من هنا.

مصدر "Remy Lebeau" من هنا .

شرح ممتاز مشكور الاخ

اسئلة متعلقة

0 تصويتات
2 إجابة
سُئل سبتمبر 11، 2018 في تصنيف vcl بواسطة Yamada Fakir (1,410 نقاط) | 55 مشاهدات
+4 تصويتات
2 إجابة
+4 تصويتات
3 إجابة
سُئل يوليو 23، 2018 في تصنيف Delphi بواسطة مبرمج | 88 مشاهدات
+4 تصويتات
1 إجابة
سُئل سبتمبر 30، 2018 في تصنيف Database بواسطة فريد (860 نقاط) | 61 مشاهدات
+2 تصويتات
1 إجابة
ادعُ اصدقائك في الفايسبوك لمشاركتك
Comodo SSL

مرحبًا بك إلى EasyDelphi Q&A، حيث يمكنك طرح الأسئلة والحصول على الإجابة عليها من المستخدمين الآخرين.

لا يسمح بطلب او السؤال عن كراك او تفعيل او كسر او فك او اي شيء يخالف اتفاقيات الترخيص  مهما كان السبب ومهما كان البرنامج ونوعه. ولا حتى نشر روابط تحتوي على مثل هذه الاشياء لا في الاسئلة ولا في الاجابات ولا التعليقات . نهائيا

324 سؤال
533 إجابة
928 تعليق
222 مستخدم