Главная страница
    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.47 MB
Время: 0.003 c
15-1293452863
Ega23
2010-12-27 15:27
2011.04.17
Наткнулся на интересное поведение в D2010


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


2-1295255823
delphist
2011-01-17 12:17
2011.04.17
помогите составить XPath выражение


15-1293597688
Curse
2010-12-29 07:41
2011.04.17
Профсоюз IT


15-1294155528
Sidak
2011-01-04 18:38
2011.04.17
Выпускная работа





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский