Cześć, mam usługę, która uruchamia aplikację okienkową. W WinXP wszystko jest ok, natomiast w Win7 muszę zaznaczyć współdziałanie z pulpitem, poza tym wyskakuje mi informacja, że jest wymagana interakcja z użytkownikiem. Dopiero gdy kliknę OK, pulpit tak jakby znika, pojawia się okno specjalne, w którym jest widoczna moja aplikacja. Czy da sie to zrobić normalnie?
normalnie tzn. jak? tak jak jest NIEZALECANE w manualu? Z definicji usługa to jest coś co nie ma okienek. A jak potrzebuje (usługa) coś pokazać userowi to należy napisać oddzielny program do wizualizacji danych, który będzie się komunikował z usługą przez komunikaty, gniazda, strumienie czy co tam jeszcze ci do głowy przyjdzie
Misiekd napisał(a)
normalnie tzn. jak? tak jak jest NIEZALECANE w manualu? Z definicji usługa to jest coś co nie ma okienek. A jak potrzebuje (usługa) coś pokazać userowi to należy napisać oddzielny program do wizualizacji danych, który będzie się komunikował z usługą przez komunikaty, gniazda, strumienie czy co tam jeszcze ci do głowy przyjdzie
Oczywiście zgadzam się z Tobą, ale nie zrozumiałes mnie do końca. Usługa NIC nie pokazuje. Uruchamia osobną aplikację okienkową. Jest to aktualizacja mojego systemu. Gdy usługa zobaczy, że na serwerze jest nowsza wersja, odpala aplikację, która zajmuje się wykonaniem tej aktualizacji. I na XP wszystko działa OK, a na 7, tak, jak napisałem w pierwszym poście.
jak uruchamia
Misiekd napisał(a)
jak uruchamia
var
sei: TShellExecuteInfoA;
begin
FillChar(sei, sizeOf(sei), 0);
sei.cbSize:=sizeof(sei);
sei.Wnd:=aHWND;
sei.fMask:=SEE_MASK_FLAG_DDEWAIT or SEE_MASK_FLAG_NO_UI;
sei.lpVerb:='runas';
sei.lpFile:=PChar(aFile);
sei.lpParameters:=PChar(aParameters);
sei.nShow:=SW_SHOWNORMAL;
ShellExecuteEx(@sei);
end;
Wcześniej było z użyciem CreateProcess, ImpersonateLoggedOnUser, itd. , ale w ogóle nie uruchamiało.
sei.Wnd:=aHWND;
jeśli go tak uruchomisz to tak jakbyś uruchamiał okno "należące" do usługi. Wpisz tam nil/null albo 0 jeśli nie przyjmie nil/null.
BTW a shellexecute nie dało rady?
Misiekd napisał(a)
sei.Wnd:=aHWND;
jeśli go tak uruchomisz to tak jakbyś uruchamiał okno "należące" do usługi. Wpisz tam nil/null albo 0 jeśli nie przyjmie nil/null.BTW a shellexecute nie dało rady?
Tak, zapomniałem napisać. W aHWND przekazuję 0. Zwykły ShellExecute nie działał, już nie pamiętam dlaczego, bo robiłem to dość dawno.
mądre głowy sugerują pobrać id aktywnej sesji WTSGetActiveConsoleSessionId, potem odpytać o token usera WTSQueryUserToken i na końcu utworzyć proces jako user CreateProcessAsUser
Misiekd napisał(a)
mądre głowy sugerują pobrać id aktywnej sesji WTSGetActiveConsoleSessionId, potem odpytać o token usera WTSQueryUserToken i na końcu utworzyć proces jako user CreateProcessAsUser
Powiem szczerze, że wydaje mi się, że cos takiego juz próbowałem. Nie wiem, czy dokładnie, ale kod wyglądał tak:
procedure ExecuteProcessAsLoggedOnUser(FileName: string);
var
ph: THandle;
hToken, nToken: THandle;
ProcInfo: TProcessInformation;
StartInfo: TStartupInfo;
begin
ph := GetShellHandle;
if ph > 0 then
begin
if OpenProcessToken(ph, TOKEN_DUPLICATE or TOKEN_QUERY, hToken) then
begin
if DuplicateTokenEx(hToken, TOKEN_ASSIGN_PRIMARY or TOKEN_DUPLICATE or TOKEN_QUERY,
nil, SecurityImpersonation, TokenPrimary, nToken) then
begin
if ImpersonateLoggedOnUser(nToken) then
begin
// Initialize then STARTUPINFO structure
FillChar(StartInfo, SizeOf(TStartupInfo), 0);
StartInfo.cb := SizeOf(TStartupInfo);
// Specify that the process runs in the interactive desktop
StartInfo.lpDesktop := PChar('WinSta0\Default');
// Launch the process in the client's logon session
CreateProcessAsUser(nToken, nil, PChar(FileName), nil, nil, False,
CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, nil, StartInfo, ProcInfo);
// End impersonation of client
RevertToSelf();
end;
CloseHandle(nToken);
end;
CloseHandle(hToken);
end;
end;
end;