Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 08.06.2019, 22:27   #1
governor
Новичок
Джуниор
 
Регистрация: 27.01.2015
Сообщений: 2
Лампочка Как перезапустить стороннюю программу

Задача: вам нужно написать программу, которая будет следить за работой другой программы, исходных кодов которой у вас нет. При необходимости ваша программа будет перезапускать её.

Данная задача делится на 3 подзадачи:

1. Определить необходимость перезапуска
2. Закрыть программу
3. Запустить программу заново


1. Необходимость перезапуска

Перезапуск программы может потребоваться по следующим причинам:

1) Желание пользователя. Это, понятное дело, закон.

2) Программа перестала выполнять свою функцию или выполняет её неверно. Здесь невозможно дать универсального совета. Вы сами должны определить это в соответствии с назначением программы и инструкцией к ней.

3) Программа не запущена (например, после перезагрузки) или запущена несколько раз. Вот код, позволяющий отследить это:

Код:
function FindTask(ExeFileName: string): integer;
var
  ContinueLoop: BOOL;
  FSnapshotHandle: THandle;
  FProcessEntry32: TProcessEntry32;
  r:word;
begin
  r := 0;
  FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  FProcessEntry32.dwSize := Sizeof(FProcessEntry32);
  ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
  while integer(ContinueLoop) <> 0 do
  begin
    if (ANSIUpperCase(ExtractFileName(FProcessEntry32.szExeFile)) = ANSIUpperCase(ExeFileName))
    or (PCHAR(ANSIUpperCase(FProcessEntry32.szExeFile)) = PCHAR(ANSIUpperCase(ExeFileName)))
        then inc(r);
   
    ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
  end;
  CloseHandle(FSnapshotHandle);
  Result := r;
end;

Функция возвращает значение, равное числу запусков программы: 0 - программа не запущена.

4) Программа зависла - окно не отвечает. Здесь требуется знать название окна: WindowName


Код:
var  h: HWND;
    lngReturnValue : longint;
    DWResult : DWORD;

begin
H := FindWindow(nil,PChar(WindowName));
  if H > 0 then
  begin
    lngReturnValue := SendMessageTimeout(
      H, WM_NULL, 0, 0, SMTO_ABORTIFHUNG And SMTO_BLOCK,
      1000, DWResult
    );
    if lngReturnValue > 0 then
      label1.caption:='Программа работает нормально!'
    else
      begin
      label1.caption:='Произошёл сбой в работе программы!';
      
      end
  end
  else
    begin
      label1.caption:='Окно не запущено!';
    end;

2. Закрыть программу


Функция, которая завершает все процессы программы, сколько бы их не было запущено и в каком состоянии (зависшем или рабочем) они ни были:

Код:
function KillTask(ExeFileName:string):integer;
const
PROCESS_TERMINATE=$0001;
var
Co:BOOL;
FS:THandle;
FP:TProcessEntry32;
begin
result:=0;
FS:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
FP.dwSize:=Sizeof(FP);
Co:=Process32First(FS,FP);
while integer(Co) <> 0 do
begin
if ((UpperCase(ExtractFileName(FP.szExeFile))=UpperCase(ExeFileName)) or
(UpperCase(FP.szExeFile)=UpperCase(ExeFileName))) then
Result:=Integer(TerminateProcess(OpenProcess(PROCESS_TERMINATE, BOOL(0),
FP.th32ProcessID),0));
Co:=Process32Next(FS,FP);
end;
CloseHandle(FS);
end;



3. Запустить программу заново

Программу можно запустить при помощи функции ShellExecute из модуля ShellAPI:

(здесь случай, когда программа в том же каталоге, если нет - укажите полный путь вместо ExtractFilePath(paramstr(0)))

Код:
ShellExecute(handle,nil,PChar(ExtractFilePath(paramstr(0))+'\'+ExeFileName),nil,nil,SW_SHOWNORMAL);

Но если программа не имеет цифровой подписи может возникнуть проблема в виде окошка "Предупреждение системы безопасности - Не удаётся проверить издателя. Вы действительно хотите запустить этот файл?" , которое можно убрать редактированием реестра.

Если по соображениям безопасности данный вариант вам не подходит, можно сделать эмуляцию нажатия кнопки:

Код:
procedure EmulateKey(Wnd: HWND; VKey: Integer);
asm
  push 0
  push edx
  push 0101H //WM_KEYUP
  push eax
  push 0
  push edx
  push 0100H //WM_KEYDOWN
  push eax
  call PostMessage
  call PostMessage
end; 

var h:hwnd;
begin
  h := FindWindow(nil,'Открыть файл - предупреждение системы безопасности');
  if (h <> 0) and IsWindowVisible(h) then
  begin
  EmulateKey(h, VK_TAB);
  EmulateKey(h, VK_TAB);
  EmulateKey(h, VK_RETURN);
  end
end;


Две табуляции нужны, чтобы перейти на кнопку "Выполнить", так как по умолчанию фокус стоит на кнопке "Отмена".
Если у вас не русская Windows, замените заголовок окна на соответствующий вашей системе.

Последний раз редактировалось governor; 08.06.2019 в 22:40.
governor вне форума Ответить с цитированием
Старый 20.06.2019, 09:34   #2
WorldMaster
Старожил
 
Аватар для WorldMaster
 
Регистрация: 25.08.2011
Сообщений: 2,841
По умолчанию

Так и чего дальше?? Все коды есть, соберите все в кучу и все.
Skype - wmaster_s E-Mail - WorldMasters@gmail.com
Работаем по 3 критериям - быстро, качественно, недорого. Заказчик выбирает любые два.
WorldMaster вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Передача настроек из моей формы в стороннюю программу DarkEvolution Общие вопросы Delphi 2 26.07.2018 21:11
Как закрыть стороннюю программу программно 1_4yma_1 Общие вопросы Delphi 5 08.06.2018 13:43
Прикрутить стороннюю библиотеку builder6 Imjonhson C++ Builder 15 05.02.2017 08:50
Как перезапустить программу по нажатию одной кнопки? nomerochek C# (си шарп) 1 14.09.2016 11:50
Запустить стороннюю программу с ПРАВАМИ АДМИНИСТРАТОРА - Delphi WinAPI yurius Общие вопросы Delphi 6 15.05.2016 15:19