Windows7 Problem: Bei Start einer exe von einem Service aus öffnet sich nicht das Formular der exe
-
Hallo,
habe eine Service-Anwendung mit C++-Borland-Builder 6 erstellt, welche über eine Socket-Verbindung von einem anderen Rechner auf Befehle wartet.
Jetzt erhält dieser Service einen Befehl, um eine andere C++-Anwendung (nenne ich jetzt mal INFO.EXE) zu starten. Dazu dient folgender Code in der Service-Anwendung:// Startet das Programm slProgr void StartApp(AnsiString slProgr) { setmem(&stgStartupInfo,sizeof(TStartupInfo),0); stgStartupInfo.cb = sizeof(TStartupInfo); CreateProcess(NULL,slProgr.c_str(),NULL,NULL, false,NORMAL_PRIORITY_CLASS, NULL,NULL, &stgStartupInfo,&stgProcessInfo); }
Die INFO.EXE besteht einfach nur aus einem Formular mit einem Label, welches einen Infotext enthält.
Diese Sache funzt unter WinXP einwandfrei.
ABER leider nicht mehr unter Win7. Der Service startet zwar die INFO.EXE ( welche als Prozess im Taskmanager auch auftaucht), aber es erscheint nirgends das Formular der Info.exe.
Unter WinXP erscheint übrigens neben dem Prozess INFO auch als Anwendung (unter "Anwendungen" im Taskmanager) der Name dieser Anwendung.
Übrigens: Starte ich unter Win7 direkt (also per Doppelklick) die Datei INFO.EXE, so wird deren Formular einwandfrei angezeigt!Hat jemand eine Idee?? DANKE!!!
-
Vllt lpCurrentDirectory, aber eher weniger.
-
Ein Service läuft seit Windows Vista in einer anderen Session als die angemeldeten Benutzer. Daher wirst du das Fenster nicht sehen. Wenn du einen Prozess im Kontext des Benutzers von einem Service aus ausführen willst musst du den Prozess Token von der jeweiligen winlogon.exe duplizieren und den Prozess mit dem Token starten.
-
Dieser Thread wurde von Moderator/in evilissimo aus dem Forum C++ in das Forum WinAPI verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
Der Service wird ja vom "System" ausgeführt (d.h. im Taskmanager steht bei dem Service als Benutzername "SYSTEM"). Dies ist bei XP und Win7 gleich.
Die INFO.EXE erscheint ebenso im Taskmanager bei beiden Systemen mit dem Benutzername "System".Was müsste man also ändern?
Wie ist das mit dem Token gemeint?
-
evilissimo schrieb:
Ein Service läuft seit Windows Vista in einer anderen Session als die angemeldeten Benutzer.
Dienste laufen schon seit NT in der Session 0.
Aber guck mal hier: http://www.c-plusplus.net/forum/viewtopic-var-t-is-263737.html
-
Wie erhalte ich den Prozess Token von der jeweiligen winlogon.exe? Quellcodebeispiel? Danke!
-
mit
getProcessID(TEXT("winlogon.exe"));
bekomme ich wohl schon einmal die ID, oder?
-
Aber wie bekomme ich von der ProzessID die SessionID?
Der Rest müsste doch dann so aussehen:
HANDLE hToken = NULL; HANDLE hNewToken = NULL; memset(&StartUp, 0, sizeof(StartUp)); memset(&ProcInfo, 0 , sizeof(ProcInfo)); StartUp.cb = sizeof(StartUp); DWORD dwSessionID = ???????????????????????????; if( OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_SESSIONID | TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE , &hToken) ) { if( DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenPrimary, &hNewToken) ) { if(SetTokenInformation( hNewToken, TokenSessionId, (LPVOID)&dwSessionID, sizeof(dwSessionID)) ) { if( CreateProcessAsUser(hNewToken, NULL , "\"C:\\Windows\\system32\\info.exe\"", NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &StartUp, &ProcInfo) ) { CloseHandle(ProcInfo.hProcess); CloseHandle(ProcInfo.hThread); } } } }
-
Siehe: http://msdn.microsoft.com/en-us/library/aa382990(VS.85).aspx
ProcessIdToSessionId
-
Aber so wie du das machen willst geht das nicht. Am einfachsten geht es wenn du den Winlogon.exe Prozess öffnest und den Prozess Token von da duplizierst und dann den Prozess startest.
-
Wollte eigentlich die ProcessID von z.B. "winlogon.exe" so herausfinden:
int GetProcID(const char* szProcess) { HANDLE hSnapshot; PROCESSENTRY32 ProcessEntry; ProcessEntry.dwSize = sizeof(PROCESSENTRY32); hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); int iProcID = -1; if(Process32First(hSnapshot, &ProcessEntry)) do { if(!stricmp(ProcessEntry.szExeFile,szProcess))iProcID = ProcessEntry.th32ProcessID; } while(Process32Next(hSnapshot, &ProcessEntry)); CloseHandle(hSnapshot); return iProcID; }
(windows.h und tlhelp32.h eingebunden)
Den Prozess kann ich dann mit OpenProcess und der ProcessID öffnen, oder?
Aber wie duplizieren,...??
-
Du hast es ja schon fast gehabt:
williman schrieb:
Aber wie bekomme ich von der ProzessID die SessionID?
Der Rest müsste doch dann so aussehen:
HANDLE hToken = NULL; HANDLE hNewToken = NULL; memset(&StartUp, 0, sizeof(StartUp)); memset(&ProcInfo, 0 , sizeof(ProcInfo)); StartUp.cb = sizeof(StartUp); //hProcess = OpenProcess mit winlogon.exe PID ;-) if( OpenProcessToken(hProcess, TOKEN_ADJUST_SESSIONID | TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE , &hToken) ) { if( DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenPrimary, &hNewToken) ) { if( CreateProcessAsUser(hNewToken, NULL , "\"C:\\Windows\\system32\\info.exe\"", NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &StartUp, &ProcInfo) ) { CloseHandle(ProcInfo.hProcess); CloseHandle(ProcInfo.hThread); } } }
Anstelle das du die SessionID setzt musst du die nur vom richtigen prozess verwenden
-
Ja, danke! So weit hatte ich es jetzt auch geschafft.
Noch ein Problemchen mit CreateProcessAsUser:
Das Programm, welches ich starten will, heißt nachricht.exe
Zudem muss ich der nachricht.exe als Parameter eine Zeichenkette übergeben (ein Text, wie z.B. " hallo, wie geht es euch ...").
Wie mache ich das?
Was nicht geht:CreateProcessAsUser(hToken, NULL, commandline.c_str(),...)
wobei
commandline = "nachricht.exe" + nachrichtenzeichenkette;
und
nachrichtenzeichenkette = "hallo, wie geht..."
Denn es wird nur als Parameter "hallo," übergeben. Nach dem Leerzeichen wird abgeschnitten! Hat jemand hierfür eine Lösung?
-
Du musst die parameter auch in 'quotes' übergeben:
"\"hallo, wie geht es euch\""
-
Ja super, so geht es endlich:
commandline = "nachricht.exe \"" + nachrichtenzeichenkette +"\"";
Danke!!!