论坛风格切换切换到宽版
  • 1714阅读
  • 2回复

请教老虎版主,运行前等待进程结束函数问题 [复制链接]

上一主题 下一主题
离线546242502
 

发帖
332
金钱
-3060
威望
-306
只看楼主 倒序阅读 0 发表于: 2015-08-16
请教老虎版主这个函数有木有问题,能否举个例子?
  1. #ifdef Unicode
  2. #define PChar "PAnsiChar"
  3. #define A "W"
  4. #else
  5. #define A "A"
  6. #define PChar "PChar"
  7. #endif
  8. [Code]
  9. ////////////////////////////////////////////////////////////////////////////////////
  10. /////////////////////////////ExecAndWait.iss////////////////////////////////////////
  11. ////////////////////////////////////////////////////////////////////////////////////
  12. ////////////////////////////////Описание////////////////////////////////////////////
  13. // Данный скрипт позволяет запускать другие программы, с ожиданием их завершения. //
  14. // Инсталлятор в момент ожидания остаётся 'кликабельным', т.е. отвечает на все    //
  15. // действия пользователя.                                                         //
  16. //                                                                                //
  17. ///////////////////////////////Использование////////////////////////////////////////
  18. // Добавьте этот скрипт в свой проект, с помощью директивы препроцессора #include.//
  19. // Пример:                                                                        //
  20. // #include "ExecAndWait.iss"                                                     //
  21. //                                                                                //
  22. // После добавления этого скрипта в свой проект, вы можете вызвать функцию:       //
  23. // function ExecAndWait(const Filename, Params, WorkingDir: string;               //
  24. //                      const ShowCmd: Word; TerminateChild: Boolean): Boolean;   //
  25. // где:                                                                           //
  26. // Filename - имя файла;                                                          //
  27. // Params - параметр командной строки, с которым нужно запустить программу;       //
  28. // WorkingDir - каталог, где находится программа;                                 //
  29. // ShowCmd - параметр для запуска программы (SW_HIDE, SW_SHOWNORMAL и т.д.);      //
  30. // TerminateChild - указывается, нужно ли завершить запущенную инсталлятором      //
  31. //                  программу, если пользователь отменил установку во время       //
  32. //                  её работы.                                                    //
  33. //                  Возможные значения: True (запущенная программа будет закрыта  //
  34. //                  вместе с инсталлятором), False (продолжит свою работу);       //
  35. // Примечание:                                                                    //
  36. // Params и WorkingDir можно не указывать.                                        //
  37. //                                                                                //
  38. // Пример 1:                                                                      //
  39. //   ExecAndWait(ExpandConstant('{sys}\notepad.exe'), '', '', SW_SHOW, True);     //
  40. // Пример 2:                                                                      //
  41. //   ExecAndWait('notepad.exe', '', ExpandConstant('{sys}'), SW_SHOW, False);     //
  42. ////////////////////////////////////////////////////////////////////////////////////
  43. //                                                                                //
  44. ////////////////////////////////////////////////////////////////////////////////////
  45. // Автор скрипта: Serega, http://forum.oszone.net/member.php?userid=88670         //
  46. // e-mail: serg_0675@mail.ru                                                      //
  47. ////////////////////////////////////////////////////////////////////////////////////
  48. const
  49.   MAX_PATH              = 260;
  50.   TH32CS_SNAPPROCESS    = $00000002;
  51.   INVALID_HANDLE_VALUE  = -1;
  52.   PROCESS_TERMINATE     = $0001;
  53.   PM_REMOVE             = 1;
  54.   STARTF_USESHOWWINDOW  = 1;
  55.   NORMAL_PRIORITY_CLASS = $00000020;
  56. type
  57.   TProcessEntry32 = record
  58.     dwSize: DWORD;
  59.     cntUsage: DWORD;
  60.     th32ProcessID: DWORD;
  61.     th32DefaultHeapID: DWORD;
  62.     th32ModuleID: DWORD;
  63.     cntThreads: DWORD;
  64.     th32ParentProcessID: DWORD;
  65.     pcPriClassBase: Longint;
  66.     dwFlags: DWORD;
  67.     szExeFile: array[0..MAX_PATH] of Char;
  68.   end;
  69.   _TMsg = record
  70.     hWnd: HWND;
  71.     msg: Word;
  72.     wParam: Word;
  73.     lParam: LongWord;
  74.     Time: TFileTime;
  75.     pt: TPoint;
  76.   end;
  77.   TProcessInformation = record
  78.     hProcess: THandle;
  79.     hThread: THandle;
  80.     dwProcessId: DWORD;
  81.     dwThreadId: DWORD;
  82.   end;
  83.   TStartupInfo = record
  84.     cb: DWORD;
  85.     lpReserved: Longint;
  86.     lpDesktop: Longint;
  87.     lpTitle: {#PChar};
  88.     dwX: DWORD;
  89.     dwY: DWORD;
  90.     dwXSize: DWORD;
  91.     dwYSize: DWORD;
  92.     dwXCountChars: DWORD;
  93.     dwYCountChars: DWORD;
  94.     dwFillAttribute: DWORD;
  95.     dwFlags: DWORD;
  96.     wShowWindow: Word;
  97.     cbReserved2: Word;
  98.     lpReserved2: Byte;
  99.     hStdInput: THandle;
  100.     hStdOutput: THandle;
  101.     hStdError: THandle;
  102.   end;
  103. function _CreateToolhelp32Snapshot(dwFlags, th32ProcessID: DWORD): THandle;
  104. external 'CreateToolhelp32Snapshot@kernel32.dll stdcall';
  105. function _Process32First(hSnapshot: THandle; var lppe: TProcessEntry32): BOOL;
  106. external 'Process32First@kernel32.dll stdcall';
  107. function _Process32Next(hSnapshot: THandle; var lppe: TProcessEntry32): BOOL;
  108. external 'Process32Next@kernel32.dll stdcall';
  109. function _OpenProcess(dwDesiredAccess: DWORD; bInheritHandle: BOOL; dwProcessId: DWORD): THandle;
  110. external 'OpenProcess@kernel32.dll stdcall';
  111. function _TerminateProcess(hProcess: THandle; uExitCode: UINT): BOOL;
  112. external 'TerminateProcess@kernel32.dll stdcall';
  113. function _CloseHandle(hObject: THandle): BOOL;
  114. external 'CloseHandle@kernel32.dll stdcall';
  115. function _PeekMessage(var lpMsg: _TMsg; hWnd: HWND; wMsgFilterMin, wMsgFilterMax,wRemoveMsg: UINT): BOOL;
  116. external 'PeekMessage{#A}@user32.dll stdcall';
  117. function _TranslateMessage(const lpMsg: _TMsg): BOOL;
  118. external 'TranslateMessage@user32.dll stdcall';
  119. function _DispatchMessage(const lpMsg: _TMsg): Longint;
  120. external 'DispatchMessage{#A}@user32.dll stdcall';
  121. function _CreateProcess(lpApplicationName: {#PChar}; lpCommandLine: {#PChar};
  122.   lpProcessAttributes, lpThreadAttributes: DWORD; bInheritHandles: BOOL; dwCreationFlags: DWORD;
  123.     lpEnvironment: {#PChar}; lpCurrentDirectory: {#PChar}; const lpStartupInfo: TStartupInfo;
  124.       var lpProcessInformation: TProcessInformation): BOOL;
  125.         external 'CreateProcess{#A}@kernel32.dll stdcall';
  126. var
  127.   _QUIT: Boolean;
  128. procedure _Application_ProcessMessages;
  129. var
  130.   Msg: _TMsg;
  131. begin
  132.   if not _PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then
  133.     Exit;
  134.   _TranslateMessage(Msg);
  135.   _DispatchMessage(Msg);
  136. end;
  137. function _KillProcess(ProcessID: DWORD): Boolean;
  138. var
  139.   hProcess: THandle;
  140. begin
  141.   hProcess:= _OpenProcess(PROCESS_TERMINATE, False, ProcessID);
  142.   Result:= _TerminateProcess(hProcess, 0);
  143.   _CloseHandle(hProcess);
  144. end;
  145. function _ArrayCharToString(ArrayChar: array of Char): string;
  146. var
  147.   i: Integer;
  148.   str: string;
  149. begin
  150.   for i:= 0 to MAX_PATH do
  151.     if (ArrayChar[i]) <> #0 then
  152.       str:= str + ArrayChar[i]
  153.     else Break;
  154.   Result:= str;
  155. end;
  156. function _ProcIsRunning(Process: string; ProcessID: DWORD): Boolean;
  157. var
  158.   Snap: THandle;
  159.   pe32: TProcessEntry32;
  160. begin
  161.   Result:= False;
  162.   if Pos('\', Process) > 0 then Process:= ExtractFileName(Process);
  163.   Snap:= _CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  164.   if Snap = INVALID_HANDLE_VALUE then Exit;
  165.   pe32.dwSize:= SizeOf(pe32);
  166.   if _Process32First(Snap, pe32) then
  167.     while _Process32Next(Snap, pe32) do
  168.       begin
  169.         if pe32.th32ProcessID = ProcessID then
  170.           if (LowerCase(_ArrayCharToString(pe32.szExeFile)) = LowerCase(Process)) then
  171.             begin
  172.               Result:= True;
  173.               Break;
  174.             end;
  175.         if _QUIT then Break;
  176.         _Application_ProcessMessages;
  177.       end;
  178.   _CloseHandle(Snap);
  179. end;
  180. procedure _WizardFormOnCloseQuery(Sender: TObject;  var CanClose: Boolean);
  181. begin
  182.   _QUIT:= True;
  183. end;
  184. function _StartProc(const Filename, Params, WorkingDir: string; const ShowCmd: Word;
  185.   TerminateChild: Boolean): Boolean;
  186. var
  187.   PI: TProcessInformation;
  188.   SI: TStartupInfo;
  189.   ProcessId: DWORD;
  190.   ProcessName: string;
  191.   CmdLine: string;
  192. begin
  193.   _QUIT:= False;
  194.   CmdLine:= '"' + Filename + '" ' + Params;
  195.   SI.cb:= SizeOf(SI);
  196.   SI.dwFlags:= STARTF_USESHOWWINDOW;
  197.   SI.wShowWindow:= ShowCmd;
  198.   try
  199.     Result:= _CreateProcess('', {#PChar}(CmdLine), 0, 0, False, NORMAL_PRIORITY_CLASS,
  200.                             '', {#PChar}(WorkingDir), SI, PI);
  201.   except
  202.     ShowExceptionMessage;
  203.   end;
  204.   if Result then
  205.     begin
  206.       WizardForm.OnCloseQuery:= @_WizardFormOnCloseQuery;
  207.       ProcessName:= ExtractFileName(Filename);
  208.       ProcessId:= PI.dwProcessId;
  209.       _CloseHandle(PI.hProcess);
  210.       _CloseHandle(PI.hThread);
  211.       while _ProcIsRunning(ProcessName, ProcessID) do;
  212.       if _QUIT and TerminateChild then _KillProcess(ProcessID);
  213.     end;
  214. end;
  215. ////////////////////////////////////////////////////////////////////////////////////
  216. function ExecAndWait(const Filename, Params, WorkingDir: string;
  217.                      const ShowCmd: Word; TerminateChild: Boolean): Boolean;
  218. // функция запускает указанный файл и ждёт его завершения
  219. begin
  220.   Result:= _StartProc(Filename, Params, WorkingDir, ShowCmd, TerminateChild);
  221. end;
  222. ////////////////////////////////////////////////////////////////////////////////////


离线gnatix

发帖
7696
金钱
-8279
威望
-828
只看该作者 1 发表于: 2015-08-16
能不能说明一下代码的具体目的?你具体有什么问题?
离线546242502

发帖
332
金钱
-3060
威望
-306
只看该作者 2 发表于: 2015-08-17
回 1楼(gnatix) 的帖子
gnatix:能不能说明一下代码的具体目的?你具体有什么问题? (2015-08-16 23:35) 

代码是别人的,就是看不懂,也不会用,想用它来实现运行某个程序时在另一个程序结束之后;
老虎版主不知道这样做是不是有点麻烦