Fragensteller
Interaktiven Prozess von Windows Service aus starten

Allgemeine Diskussion
-
Hallo Leute,
ich muss von einem Windows Dienst aus eine Applikation auf dem interaktiven Desktop (interaktiver User) starten. Soweit keine Probleme, wenn der Service unter LocalSystem läuft:
DWORD dwSessionId = WTSGetActiveConsoleSessionId(); if (dwSessionId != 0xFFFFFFFF) { if (WTSQueryUserToken(dwSessionId, &hUserToken)) { sa.bInheritHandle = TRUE; pStartupInfo->cb = sizeof(*pStartupInfo); pStartupInfo->lpDesktop = "winsta0\\default"; if (ImpersonateLoggedOnUser(hUserToken)) { bRet = CreateProcessAsUser(hUserToken, szFile, szCmdLine, &sa, &sa, FALSE, dwCreationFlags, NULL, szPath, pStartupInfo, pProcessInfo); RevertToSelf(); } CloseHandle(hUserToken); }
Wenn der Dienst jetzt aber unter einem anderen Konto läuft (z.B. eigener Domänen-Account), funktioniert natürlich WTSQueryUserToken nicht mehr.
Also versuche ich es so:
else if (GetLastError() == ERROR_PRIVILEGE_NOT_HELD || GetLastError() == ERROR_ACCESS_DENIED) { DWORD dwProcSessionId = 0, dwProcId = 0; PROCESSENTRY32 PEntry = {0}; HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hSnapShot == INVALID_HANDLE_VALUE) return FALSE; PEntry.dwSize = sizeof(PEntry); BOOL bOK = Process32First(hSnapShot, &PEntry); for(; bOK; bOK = Process32Next(hSnapShot, &PEntry)) { if (strcmp(PEntry.szExeFile, "explorer.exe") == 0) { if (ProcessIdToSessionId(PEntry.th32ProcessID, &dwProcSessionId) && dwProcSessionId == dwSessionId) { dwProcId = PEntry.th32ProcessID; bFound = TRUE; break; } } } CloseHandle(hSnapShot); if (bFound) { HANDLE hOwnToken = NULL; if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hOwnToken)) { LUID luid = {0}; TOKEN_PRIVILEGES adjTokenPrivileges = {0}; if (LookupPrivilegeValue(NULL, SE_TCB_NAME, &luid)) { adjTokenPrivileges.PrivilegeCount = 1; adjTokenPrivileges.Privileges[0].Luid = luid; adjTokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; bRet = AdjustTokenPrivileges(hOwnToken, FALSE, &adjTokenPrivileges, sizeof(adjTokenPrivileges), NULL, NULL); } if (LookupPrivilegeValue(NULL, SE_INCREASE_QUOTA_NAME, &luid)) { adjTokenPrivileges.PrivilegeCount = 1; adjTokenPrivileges.Privileges[0].Luid = luid; adjTokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; bRet = AdjustTokenPrivileges(hOwnToken, FALSE, &adjTokenPrivileges, sizeof(adjTokenPrivileges), NULL, NULL); } if (LookupPrivilegeValue(NULL, SE_ASSIGNPRIMARYTOKEN_NAME, &luid)) { adjTokenPrivileges.PrivilegeCount = 1; adjTokenPrivileges.Privileges[0].Luid = luid; adjTokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; bRet = AdjustTokenPrivileges(hOwnToken, FALSE, &adjTokenPrivileges, sizeof(adjTokenPrivileges), NULL, NULL); } CloseHandle(hOwnToken); } HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwProcId); if (hProcess) { HANDLE hToken = NULL; if (OpenProcessToken(hProcess, TOKEN_DUPLICATE, &hToken)) { pStartupInfo->cb = sizeof(*pStartupInfo); pStartupInfo->lpDesktop = "winsta0\\default"; if (DuplicateTokenEx(hToken, MAXIMUM_ALLOWED/*TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_QUERY*/, &sa, SecurityImpersonation, TokenPrimary, &hUserToken)) { bRet = CreateProcessAsUser(hUserToken, szFile, szCmdLine, &sa, &sa, FALSE, CREATE_NEW_CONSOLE, NULL, szPath, pStartupInfo, pProcessInfo); CloseHandle(hUserToken); } CloseHandle(hToken); } CloseHandle(hProcess); } } }
Erhalte aber wieder nur auf CreateProcessAsUser ERROR_PRIVILEGE_NOT_HELD, bei Verwendung von CreateProcessWithLogonW ERROR_ACCESS_DENIED.
Wie kann ich also eine GUI Applikation unter dem interaktiven User starten, wenn mein Dienst z.B. unter demselben User läuft ??
Log On des Users ist kein Problem, es wird davon ausgegangen, dass dieser Benutzer angemeldet ist...
Vielen Dank im Voraus, hoffe es war verständlich. :)
- Bearbeitet R3dNeXX Donnerstag, 10. Mai 2012 07:59
- Typ geändert Robert BreitenhoferModerator Freitag, 15. Juni 2012 12:30 Keine Rückmeldung des Fragenstellender
Alle Antworten
-
Ich glaube, ImpersonateAsLoggedOnUser ist immer noch nötig. Und andere Frage: hast du mal überlegt, ob der User nicht dem Dienst sein Token übergeben könnte? Weil sonst befürchte ich, dass du nicht an das aktuelle kommst, sondern der User einfach ein zweites Mal eingeloggt wird und du dieses Token erhälst...
Rudolf
... wenn's überhaupt noch aktuell ist die Frage :-)
-
****************************************************************************************************************
Dieser Thread wurde mangels weiterer Beteiligung des Fragestellenden ohne bestätigte Lösung abgeschlossen.
Neue Rückfragen oder Ergänzungen zu diesem Thread bleiben weiterhin möglich.
****************************************************************************************************************Robert Breitenhofer, MICROSOFT
Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „Entwickler helfen Entwickler“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.