Текущий архив: 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.004 c