Есть служба, написанная на Delphi. Ей нужно иногда получать информацию от пользователя. Она запускает для этого процесс под пользователем, который смотрит в монитор. При этом служба не должна висеть ожидая завершения процесса.
If UseDensityOnVesna then begin
Events[l].SyncEventID:=CurSyncEventID;
Events[l].hevent:=CreateEvent(nil,True,False,PChar('DensityEvent'+IntToStr(CurSyncEventID)));
CallDensityEXE(l);
inc(CurSyncEventID);
end;
procedure TdmVesna.CallDensityEXE(l:integer);
var
AppPath,s{,EventName}:string;
cpr:bool;
si:STARTUPINFO;
pi:PROCESS_INFORMATION;
hToken:dword;
GetToken:boolean;
begin
Log2('Запуск Density SyncEventid='+IntToStr(Events[l].SyncEventID),2);
AppPath:=ExtractFilePath(ParamStr(0));
s:=AppPath+'Density.exe '+IntToStr(Events[l].SyncEventID)+' '+IntToStr(Events[l].Value)+' '+DateTimeToStr(Events[l].dt);
//EventName:='DensityEvent'+IntToStr(Events[l].SyncEventID);
//Events[l].hevent:=CreateEvent(nil,True,False,PChar(EventName));
Events[l].Density:=0;
Events[l].ObjectID:=0;
FillChar(si,sizeof(STARTUPINFO),0);
si.cb:=sizeof(STARTUPINFO);
si.wShowWindow:=SW_SHOWNORMAL;
si.dwFlags:=STARTF_USESHOWWINDOW;
si.lpDesktop:=nil;
//cpr:=CreateProcess(nil,PChar(s),nil,nil,false,NORMAL_PRIORITY_CLASS,nil,PChar(AppPath),si,pi);
GetToken:=WTSQueryUserToken(WtsGetActiveConsoleSessionID,@hToken);
If not GetToken then Log2('Процесс Density не создан, нет токена!')
else begin
cpr:=CreateProcessAsUser(hToken,nil,PChar(s),nil,nil,True,0,nil,nil,si,pi);
if cpr then begin
Log2('Процесс SyncEventid='+IntToStr(Events[l].SyncEventID)+' создан',2);
end else begin
Log2('Ошибка создания процесса SyncEventid='+IntToStr(CurSyncEventID)+' '+SysErrorMessage(GetLastError));
end;
end;
end;
Суть в том, что в процессе, который служба вызывает, OpenEvent завершается с ошибкой ERROR_FILE_NOT_FOUND. Если делать там вместо OpenEvent -> CreateEvent, то все вроде бы работает, но такое ощущение, что Event у этого процесса свой собственный, хоть и с тем же именем (в службе этого Event'a по WaitSingleObject не дождешься никогда). Пробовал делать CreateEvent и потом OpenEvent, тогда GetLastError выдает 0xc0000008. Что это за код тоже непонятно.
Пробовал делать не из службы - создал тестовое приложение - начинает все работать.
Видимо проблема в том, что эти два процесса запускаются под разными пользователями. Как заставить видеть Event из процесса запущенного под другим пользователем?