Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2011.04.17;
Скачать: CL | DM;

Вниз

Трудности с WMI (инфо о процессах)   Найти похожие ветки 

 
Тоха   (2011-01-14 20:36) [0]

Доброго времени суток.

Используя приведёный исходник, пытаюсь написать оконную программу. Если в консольном приложении всё работает на ура, то в оконном происходит следующее. Когда я останавливаю поток, либо просто жму на кресик закрытия окна (срабатывает обработчик, который освобождает поток), он ни в какую не желает останавливаться, а программа зависает. Как выяснилось, поток упорно ждёт наступления Eventquery.NextEvent. Если после попытки закрыть программу запустить и закрыть любую другую, то поток вполне нормально останавливается.
Объясните, пожалуйста, где я ступил.

исходник консольной проги (свою не привожу, ибо практически то же самое):

program ProcessWatcher;

{$APPTYPE CONSOLE}

uses
 Windows,
 SysUtils, Classes, WbemScripting_TLB, ActiveX;
var
 SWbemLocator1: TSWbemLocator;
 csSync: _RTL_CRITICAL_SECTION;

type
 TCreateProcThread = class(TThread)
 private
   { Private declarations }
 protected
   procedure Execute; override;
 end;
 TStopProcThread = class(TThread)
 private
   { Private declarations }
 protected
   procedure Execute; override;
 end;

const
 WBEM_FLAG_RETURN_IMMEDIATELY     = $10;
 WBEM_FLAG_FORWARD_ONLY           = $20;

{ TCreateProcThread }

procedure TCreateProcThread.Execute;
var
 Service: ISWbemServices;
 Eventquery: ISWbemEventSource;
 objLatestProcess: ISWbemObject;
 Prop: OleVariant;
begin
 CoInitializeEx(nil, COINIT_APARTMENTTHREADED);
 Service := SWbemLocator1.ConnectServer(".",
   "root\cimv2",
   "", "",
   "",
   "", 0, nil);
 Eventquery := Service.ExecNotificationQuery(
   "select * from __InstanceCreationEvent WITHIN 1 WHERE TargetInstance ISA ""Win32_Process""",
   "WQL",
   WBEM_FLAG_RETURN_IMMEDIATELY or WBEM_FLAG_FORWARD_ONLY, nil);
 while not Terminated do
 begin
   objLatestProcess := Eventquery.NextEvent(Integer(INFINITE));
   Prop := objLatestProcess;
   EnterCriticalSection(csSync);
   Writeln("Started: " + Prop.TargetInstance.Name + #09#09 + DateTimeToStr(Now));
   LeaveCriticalSection(csSync);
 end;
end;

{ TStopProcThread }

procedure TStopProcThread.Execute;
var
 Service: ISWbemServices;
 Eventquery: ISWbemEventSource;
 objLatestProcess: ISWbemObject;
 Prop: OleVariant;
begin
 CoInitializeEx(nil, COINIT_APARTMENTTHREADED);
 Service := SWbemLocator1.ConnectServer(".",
   "root\cimv2",
   "", "",
   "",
   "", 0, nil);
 Eventquery := Service.ExecNotificationQuery(
   "select * from __InstanceDeletionEvent WITHIN 1 WHERE TargetInstance ISA ""Win32_Process""",
   "WQL",
   WBEM_FLAG_RETURN_IMMEDIATELY or WBEM_FLAG_FORWARD_ONLY, nil);
 while not Terminated do
 begin
   objLatestProcess := Eventquery.NextEvent(Integer(INFINITE));
   Prop := objLatestProcess;
   EnterCriticalSection(csSync);
   Writeln("Stopped: " + Prop.TargetInstance.Name + #09#09 + DateTimeToStr(Now));
   LeaveCriticalSection(csSync);
 end;
end;

begin
 InitializeCriticalSection(csSync);
 Writeln("Process name"#09#09#09"Event date");
 CoInitializeEx(nil, COINIT_APARTMENTTHREADED);
 SWbemLocator1 := TSWbemLocator.Create(nil);
 try
   TCreateProcThread.Create(false);
   TStopProcThread.Create(false);
   while True do
     Sleep(1);
 finally
   SWbemLocator1.Free;
 end;
end.


 
Тоха   (2011-01-14 21:09) [1]

Написал небольшой демо-проект http://zalil.ru/30333955  (Delphi 2010)

Запускаете, потоки стартуют автоматически. Затем нажимаете кнопку Terminate:

CPT.Terminate;
CPT.WaitFor;
SPT.Terminate;
SPT.WaitFor;


Итог - из обработчика кнопки уже не возвращаемся. Чтобы вернуться и прервать-таки потоки необходимо запустить и закрыть произвольную программу.

В чем тут дело и как решить проблему?


 
DiamondShark ©   (2011-01-14 21:35) [2]

У тебя модель Apartment, а объекты создаются и используются в разных потоках.


 
Сергей М. ©   (2011-01-14 21:50) [3]

> из обработчика кнопки уже не возвращаемся

А должны ?
В обработчике клика кнопки взводится флаг Terminated, после чего осн.поток на вызове WaitFor до опупения ждет когда доп.лоток соизволит обратить на это внимание, чтобы закруглиться по хозяйству. А доп.поток ни сном ни духом об этом не ведает - он ждет наступления события , которое ты сам же и приказал ему ждать.


 
Тоха   (2011-01-15 00:39) [4]


> он ждет наступления события , которое ты сам же и приказал
> ему ждать.

Хорошо, а как заставить его закруглиться? WMI предусматривает какие-либо способы, либо вы можете посоветовать другой путь решения?


 
Германн ©   (2011-01-15 01:38) [5]


> Хорошо, а как заставить его закруглиться? WMI предусматривает
> какие-либо способы, либо вы можете посоветовать другой путь
> решения?

А при чем тут WMI?
Это ты сам создал такую ситуацию.


 
Тоха   (2011-01-15 02:44) [6]

Германн, ну посоветуй тогда альтернативу... Я сам уже знаю, что я создал, а как сделать по-другому? Подскажи.

ЗЫ. В сторону хуков смотрел, точнее, WM_SHELL, однако не все программы отлавливает. Разбираться не стал, решил пробовать по-простому, как мне казалось...


 
DiamondShark ©   (2011-01-16 19:07) [7]


> Хорошо, а как заставить его закруглиться?


Вот ты когда написал:

>    objLatestProcess := Eventquery.NextEvent(Integer(INFINITE));

ты понимал, что означает каждое слово в этой строчке? Например, INFINITE?
Или просто скописпастил?



Страницы: 1 вся ветка

Текущий архив: 2011.04.17;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.009 c
15-1293565837
TUser
2010-12-28 22:50
2011.04.17
Почему эбонит электризуется при натерании об шерсть?


2-1295279025
SamBrown
2011-01-17 18:43
2011.04.17
Как убрать колонки у VCL ListView (vsReport)


2-1295103406
Pcrepair
2011-01-15 17:56
2011.04.17
Разработка и модификация компонентов


8-1211477420
presston
2008-05-22 21:30
2011.04.17
Выделение области на рисунке


15-1292840260
ocean
2010-12-20 13:17
2011.04.17
К вопросу о нобелевских премиях