| 
| 
 | Вопрос # 5 666/ вопрос закрыт / | 
 |  Доброго времени суток, уважаемые эксперты!Возникла у меня небольшая проблема с завершением запущенного процесса. Собственно смысл вот в чем: Есть запущенная программа. Запущенных экземпляров может быть и несколько. Нужно, чтобы завершились все экземпляры, кроме первого.
 С поиском процессов проблем нет. Но вот при завершении возникает проблема следующего порядка: Если например процессов 3, то завершается только один из них. Другие два остаются.
 Приложение:Переключить в обычный режим {{code}}function Address(Win:hwnd): Bool;var  ProcessID : Cardinal;  ProcessHandle : Cardinal;  ModuleHandles : array[0..256] of DWORD;  nBytes : Cardinal;  ModuleName :array[0..259] of Char;begin  GetWindowThreadProcessId(Win, @ProcessID);  ProcessHandle := OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID);  I := I + 1;  If I > 1 then TerminateProcess(ProcessHandle, 0);  result := true;end;  procedure TForm1.Button1Click(Sender: TObject);var  Wnd: hWnd;  buff: array[0..127] of Char;  WinName, WinClass : array[0..80] of Char;begin  Wnd := GetWindow(Handle, gw_HWndFirst);  while Wnd <> 0 do   begin    if (Wnd <> Application.Handle) and       IsWindowVisible(Wnd) and       (GetWindow(Wnd, gw_Owner) = 0) and       (GetWindowText(Wnd, buff, sizeof(buff)) <> 0) then        begin         GetClassName(Wnd, WinClass, SizeOf(WinName) - 1);         If WinClass = 'ClaWin8388608Class1' then Address (Wnd);       end;       Wnd := GetWindow(Wnd, gw_hWndNext);  end;end;{{/code}}
|  |   Вопрос задал: blackhawk (статус: Посетитель)Вопрос отправлен: 7 октября 2011, 15:12
 Состояние вопроса: закрыт, ответов: 1.
 |  Ответ #1. Отвечает эксперт: winner13 Ту, blackhawk!
 Создаётся мутекс ему присваивается имя, если это имя используется приложение с мутексом, поторно не запускается.
 
 Вот тебе на WinApi в догонку раб пример.
 Приложение:Переключить в обычный режим   Const   var Mutex:cardinal; unction WindowProc(Handle,Msg,wParam,lParam:cardinal):integer;stdcall;var P:TPoint;    Drive:string;case Msg of    WM_CREATE:begin      Result:=0;      Mutex:=CreateMutex(nil,false,MutexName);      if Mutex=0 then MessageBox(Handle,'0',nil,0);      if Mutex=ERROR_ALREADY_EXISTS then Result:=-1;end;    WM_DESTROY:begin       PostQuitMessage(0);      Result:=0;    end;    else Result:=DefWindowProc(Handle,Msg,wParam,lParam);  end;end; var Handle:cardinal;    Msg:TMsg;    WindowClass:TWndClass;begin   ZeroMemory(@WindowClass,sizeof(TWndClass));     Style:=cs_HRedraw or cs_VRedraw;    lpfnWndProc:=@WindowProc;    hCursor:=LoadCursor(0, idc_Arrow);    hbrBackground:=GetStockObject(LtGray_Brush);    lpszClassName:=AppName;  end;  if RegisterClass(WindowClass)=0 then Halt(255);     cw_UseDefault, cw_UseDefault, cw_UseDefault, cw_UseDefault,    0, 0, HInstance, nil);  ShowWindow(Handle, SW_MAXIMIZE);  UpdateWindow(Handle);   while GetMessage(Msg, 0, 0, 0) do begin    TranslateMessage(Msg);    DispatchMessage(Msg);  end;  UnregisterClass(AppName,hInstance);  Halt(Msg.wParam);end.
|  | Ответ отправил: winner13 (статус: 1-ый класс)Время отправки: 7 октября 2011, 18:15
 Оценка за ответ: 5
 Комментарий к оценке: Спасибо. Нет, я понимаю, что такою мъютекс. Дело в другом. Наверно немного не верно объяснил изначально. Приведенный код тестовый. Реальная прога консольная. Запускается одновременно с тем приложением, копии котрого нужно закрыть. Работает кратковременно, пока не переберет все запущенные копии. После этого завершает работу.  В принципе есть идея сделать ее висящей постоянно, но пока не ясно насколько это целесообразно. |  
 Мини-форум вопросаВсего сообщений: 8; последнее сообщение — 7 октября 2011, 16:19; участников в обсуждении: 3. 
|   | min@y™ (статус: Доктор наук), 7 октября 2011, 15:33 [#1]:"I" - это чо за переменная? Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп! |  
|   | blackhawk (статус: Посетитель), 7 октября 2011, 15:37 [#2]:min@y™: I : Integer;
 Просто тупой счетчик. Задана глобально.
 |  
|   | min@y™ (статус: Доктор наук), 7 октября 2011, 15:46 [#3]: Цитата (blackhawk): Просто тупой счетчик.  Так из-за его значения вся котовасия-то. У тебя при I = 1 в памяти болтаются 2 процесса, а TerminateProcess() не выполняется. Переменная I как-то связана с количеством искомых процессов?
 Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп! |  
|   | blackhawk (статус: Посетитель), 7 октября 2011, 15:53 [#4]:min@y™: Бррр, почему 2? I = 0;
 При первом If WinClass = 'ClaWin8388608Class1' I := I + 1
 I := 1 - Нашли первый процесс.
 
 При втором If WinClass = 'ClaWin8388608Class1' I := I + 1
 I := 2
 
 Разьве не так?
 
 "Переменная I как-то связана с количеством искомых процессов?" Да, но ровно настолько, что какой первый процесс нашли, он и I := 1. Все остальные в топку...
 |  
|   | min@y™ (статус: Доктор наук), 7 октября 2011, 15:57 [#5]:Ну ты ж сам сказал: 
 Цитата (blackhawk): Если например процессов 3, то завершается только один из них. Другие два остаются. Значит при I = 1 (или I = 0) в памяти висит 2 процесса, но вот это условие не выполняется:
 
 If I > 1 then TerminateProcess(ProcessHandle, 0); Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп! |  
|   | blackhawk (статус: Посетитель), 7 октября 2011, 16:04 [#6]:Почему тогда при ShowMessage (IntToStr (I) + '   ' + IntToStr (ProcessHandle));
 
 1   10096
 2   10104
 3   10108
 
 ?
 |  
|   | winner13 (статус: 1-ый класс), 7 октября 2011, 16:13 [#7]:Чем так извращатся, проще использовать мютекс. Не решимых проблем нет, есть неприятные для нас решения. |  
|   | blackhawk (статус: Посетитель), 7 октября 2011, 16:19 [#8]:winner13: А по подробнее пожалуйста?
 |  12 октября 2011, 08:36: Вопрос закрыт (решение принял автор вопроса — blackhawk): ответов больше нет Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте. |