Ich muss ein Programm von Windows-Dienst starten. Dieses Programm ist eine Benutzer-UI-Anwendung. Außerdem sollte diese Anwendung unter einem bestimmten Benutzerkonto gestartet werden.So starten Sie einen Prozess vom Windows-Dienst in die aktuell angemeldete Benutzersitzung
Das Problem ist, dass ein Fenster Dienste in der Sitzung # 0 laufen, aber ein in Benutzersitzungen angemeldet sind 1,2 usw.
Die Frage ist also: Wie kann ein Prozess von einem Fenster Dienst in einem starten solche Wie läuft es in der aktuell angemeldeten Benutzersitzung?
Ich würde betonen, dass die Frage ist nicht, wie man einen Prozess unter bestimmten Konto starten (es ist offensichtlich - Process.Start (new ProcessStartInfo ("..") {UserName = .., Password = ..})). Selbst wenn ich meine Fenster unter dem aktuellen Benutzerkonto installiere, wird der Dienst trotzdem in der Sitzung # 0 laufen. Einstellung "Dienst mit Desktop interagieren" hilft nicht.
Mein Windows-Dienst ist .net-basiert.
UPDATE: vor allem, .NET hat nichts zu tun, es ist eigentlich reine Win32 Sache. Hier ist was ich mache. Der folgende Code in meinem Windows-Dienst (C# win32-Funktion über P/Inkove verwendet wird, übersprungen ich Import Unterschriften, sie sind alle hier - http://www.pinvoke.net/default.aspx/advapi32/CreateProcessWithLogonW.html):
var startupInfo = new StartupInfo()
{
lpDesktop = "WinSta0\\Default",
cb = Marshal.SizeOf(typeof(StartupInfo)),
};
var processInfo = new ProcessInformation();
string command = @"c:\windows\Notepad.exe";
string user = "Administrator";
string password = "password";
string currentDirectory = System.IO.Directory.GetCurrentDirectory();
try
{
bool bRes = CreateProcessWithLogonW(user, null, password, 0,
command, command, 0,
Convert.ToUInt32(0),
currentDirectory, ref startupInfo, out processInfo);
if (!bRes)
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
catch (Exception ex)
{
writeToEventLog(ex);
return;
}
WaitForSingleObject(processInfo.hProcess, Convert.ToUInt32(0xFFFFFFF));
UInt32 exitCode = Convert.ToUInt32(123456);
GetExitCodeProcess(processInfo.hProcess, ref exitCode);
writeToEventLog("Notepad has been started by WatchdogService. Exitcode: " + exitCode);
CloseHandle(processInfo.hProcess);
CloseHandle(processInfo.hThread);
Der Code geht in die Zeile „Notepad gestartet wurde von WatchdogService Exitcode: "+ exitCode. Exitcode ist 3221225794. Und es gibt keinen neuen Notizblock gestartet. Wo liege ich falsch?
Ich möchte nicht, dass mein Dienst interaktiv ist (zeigt irgendeine Benutzeroberfläche), ich möchte nur, dass er einen anderen Prozess (in der Sitzung des Benutzers) starten kann. Das ist ein bisschen anders, oder? – Shrike
@Shrike: Wenn Sie keine Benutzeroberfläche anzeigen möchten, warum reicht es dann nicht, diesen Prozess in Sitzung 0 zu starten? Ich denke, Sie müssen weitere Details hinzufügen, warum dieser Prozess eine interaktive Sitzung erfordert und warum die vorgeschlagene Problemumgehung für Sie nicht geeignet ist. –
Es gibt zwei Akteure: Windows-Service und UI-Programm. Der Server itseft zeigt keine UI, sondern startet das Programm (als neuen Prozess). Das Programm _has_ UI (und erfordert Sitzung 1). Mein Dienst ist eine Art Wachhund, der das Programm regelmäßig "pingt" und es startet/startet, wenn etwas nicht in Ordnung ist. Ich füge eine Klarstellung in den ursprünglichen Beitrag hinzu – Shrike