Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 5 666

/ вопрос закрыт /

Доброго времени суток, уважаемые эксперты!
Возникла у меня небольшая проблема с завершением запущенного процесса. Собственно смысл вот в чем: Есть запущенная программа. Запущенных экземпляров может быть и несколько. Нужно, чтобы завершились все экземпляры, кроме первого.
С поиском процессов проблем нет. Но вот при завершении возникает проблема следующего порядка: Если например процессов 3, то завершается только один из них. Другие два остаются.

Приложение:
  1. {{code}}
  2. function Address(Win:hwnd): Bool;
  3. var
  4. ProcessID : Cardinal;
  5. ProcessHandle : Cardinal;
  6. ModuleHandles : array[0..256] of DWORD;
  7. nBytes : Cardinal;
  8. ModuleName :array[0..259] of Char;
  9. begin
  10. GetWindowThreadProcessId(Win, @ProcessID);
  11. ProcessHandle := OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID);
  12. I := I + 1;
  13. If I > 1 then TerminateProcess(ProcessHandle, 0);
  14. result := true;
  15. end;
  16.  
  17.  
  18. procedure TForm1.Button1Click(Sender: TObject);
  19. var
  20. Wnd: hWnd;
  21. buff: array[0..127] of Char;
  22. WinName, WinClass : array[0..80] of Char;
  23. begin
  24. Wnd := GetWindow(Handle, gw_HWndFirst);
  25. while Wnd <> 0 do
  26. begin
  27. if (Wnd <> Application.Handle) and
  28. IsWindowVisible(Wnd) and
  29. (GetWindow(Wnd, gw_Owner) = 0) and
  30. (GetWindowText(Wnd, buff, sizeof(buff)) <> 0) then
  31. begin
  32. GetClassName(Wnd, WinClass, SizeOf(WinName) - 1);
  33. If WinClass = 'ClaWin8388608Class1' then Address (Wnd);
  34. end;
  35. Wnd := GetWindow(Wnd, gw_hWndNext);
  36. end;
  37. end;{{/code}}


blackhawk Вопрос закрыт (ответы не принимаются, мини-форум закрыт)

Вопрос задал: blackhawk (статус: Посетитель)
Вопрос отправлен: 7 октября 2011, 15:12
Состояние вопроса: закрыт, ответов: 1.

Ответ #1. Отвечает эксперт: winner13

Ту, blackhawk!

Создаётся мутекс ему присваивается имя, если это имя используется приложение с мутексом, поторно не запускается.

Вот тебе на WinApi в догонку раб пример.

Приложение:
  1.  
  2.  
  3. Const
  4.  
  5.  
  6.  
  7. var Mutex:cardinal;
  8.  
  9. unction WindowProc(Handle,Msg,wParam,lParam:cardinal):integer;stdcall;
  10. var P:TPoint;
  11. Drive:string;
  12. case Msg of
  13. WM_CREATE:begin
  14. Result:=0;
  15. Mutex:=CreateMutex(nil,false,MutexName);
  16. if Mutex=0 then MessageBox(Handle,'0',nil,0);
  17. if Mutex=ERROR_ALREADY_EXISTS then Result:=-1;
  18. end;
  19. WM_DESTROY:begin
  20.  
  21. PostQuitMessage(0);
  22. Result:=0;
  23. end;
  24. else Result:=DefWindowProc(Handle,Msg,wParam,lParam);
  25. end;
  26. end;
  27.  
  28. var Handle:cardinal;
  29. Msg:TMsg;
  30. WindowClass:TWndClass;
  31. begin
  32. ZeroMemory(@WindowClass,sizeof(TWndClass));
  33.  
  34. Style:=cs_HRedraw or cs_VRedraw;
  35. lpfnWndProc:=@WindowProc;
  36. hCursor:=LoadCursor(0, idc_Arrow);
  37. hbrBackground:=GetStockObject(LtGray_Brush);
  38. lpszClassName:=AppName;
  39. end;
  40. if RegisterClass(WindowClass)=0 then Halt(255);
  41.  
  42. cw_UseDefault, cw_UseDefault, cw_UseDefault, cw_UseDefault,
  43. 0, 0, HInstance, nil);
  44. ShowWindow(Handle, SW_MAXIMIZE);
  45. UpdateWindow(Handle);
  46. while GetMessage(Msg, 0, 0, 0) do begin
  47. TranslateMessage(Msg);
  48. DispatchMessage(Msg);
  49. end;
  50. UnregisterClass(AppName,hInstance);
  51. Halt(Msg.wParam);
  52. end.


Ответ отправил: winner13 (статус: 1-ый класс)
Время отправки: 7 октября 2011, 18:15
Оценка за ответ: 5

Комментарий к оценке: Спасибо. Нет, я понимаю, что такою мъютекс. Дело в другом. Наверно немного не верно объяснил изначально. Приведенный код тестовый. Реальная прога консольная. Запускается одновременно с тем приложением, копии котрого нужно закрыть. Работает кратковременно, пока не переберет все запущенные копии. После этого завершает работу. В принципе есть идея сделать ее висящей постоянно, но пока не ясно насколько это целесообразно.

Мини-форум вопроса

Всего сообщений: 8; последнее сообщение — 7 октября 2011, 16:19; участников в обсуждении: 3.
min@y™

min@y™ (статус: Доктор наук), 7 октября 2011, 15:33 [#1]:

"I" - это чо за переменная?
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
blackhawk

blackhawk (статус: Посетитель), 7 октября 2011, 15:37 [#2]:

min@y™:
I : Integer;
Просто тупой счетчик. Задана глобально.
min@y™

min@y™ (статус: Доктор наук), 7 октября 2011, 15:46 [#3]:

Цитата (blackhawk):

Просто тупой счетчик.

Так из-за его значения вся котовасия-то. У тебя при I = 1 в памяти болтаются 2 процесса, а TerminateProcess() не выполняется. Переменная I как-то связана с количеством искомых процессов?
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
blackhawk

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™

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

blackhawk (статус: Посетитель), 7 октября 2011, 16:04 [#6]:

Почему тогда при
ShowMessage (IntToStr (I) + ' ' + IntToStr (ProcessHandle));

1 10096
2 10104
3 10108

?
winner13

winner13 (статус: 1-ый класс), 7 октября 2011, 16:13 [#7]:

Чем так извращатся, проще использовать мютекс.
Не решимых проблем нет, есть неприятные для нас решения.
blackhawk

blackhawk (статус: Посетитель), 7 октября 2011, 16:19 [#8]:

winner13:
А по подробнее пожалуйста?

12 октября 2011, 08:36: Вопрос закрыт (решение принял автор вопроса — blackhawk): ответов больше нет

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:29
Выполнено за 0.03 сек.