Privilegien erhebend funktioniert nicht mit UseShellExecute = false
-
02-10-2019 - |
Frage
Ich will ein Kind starten (in der Tat die gleiche, Konsole app) mit erhöhten Rechten, aber mit versteckten Fenster.
ich als nächstes tun:
var info = new ProcessStartInfo(Assembly.GetEntryAssembly().Location)
{
UseShellExecute = true, // !
Verb = "runas",
};
var process = new Process
{
StartInfo = info
};
process.Start();
und das funktioniert:
var identity = new WindowsPrincipal(WindowsIdentity.GetCurrent());
identity.IsInRole(WindowsBuiltInRole.Administrator); // returns true
Aber UseShellExecute = true
erstellt ein neues Fenster und ich auch, ich kann nicht Redirect ausgegeben.
Also, wenn ich als nächstes tun:
var info = new ProcessStartInfo(Assembly.GetEntryAssembly().Location)
{
RedirectStandardError = true,
RedirectStandardOutput = true,
UseShellExecute = false, // !
Verb = "runas"
};
var process = new Process
{
EnableRaisingEvents = true,
StartInfo = info
};
DataReceivedEventHandler actionWrite = (sender, e) =>
{
Console.WriteLine(e.Data);
};
process.ErrorDataReceived += actionWrite;
process.OutputDataReceived += actionWrite;
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();
Dies gilt nicht elevate Privilegien und angezeigten Code falsch zurückgibt. Warum ??
Lösung
ProcessStartInfo.Verb wird nur dann eine Wirkung, wenn der Prozess durch ShellExecuteEx gestartet wird (). Welche erfordert UseShellExecute = true. Umleiten von E / A und das Fenster zu verstecken kann nur funktionieren, wenn der Prozess von Createprocess gestartet wird (). Welche erfordert UseShellExecute = false.
Nun, das ist, warum es nicht funktioniert. Nicht sicher, ob das Verbot einen versteckten Prozess zu starten, umgeht UAC war beabsichtigt. Wahrscheinlich. Sehr wahrscheinlich.
Sehen Sie sich diese Q + A für das Manifest Sie müssen prompt die UAC angezeigt werden soll.
Andere Tipps
In meinem Fall war es ok die Ausgaben zu bekommen, sobald der erhöhten Kind-Prozess durchgeführt wird. Hier ist die Lösung, die ich kam. Es verwendet eine temporäre Datei:
var output = Path.GetTempFileName();
var process = Process.Start(new ProcessStartInfo
{
FileName = "cmd",
Arguments = "/c echo I'm an admin > " + output, // redirect to temp file
Verb = "runas", // UAC prompt
UseShellExecute = true,
});
process.WaitForExit();
string res = File.ReadAllText(output);
// do something with the output
File.Delete(output);
Überprüfen Sie diese Antwort .
Dies scheint eine Abhilfe zu schaffen. Aber ich empfehle andere Methoden zu versuchen, wie Named Pipes wenn Sie Zugriff haben In den Quellcode des Kindes Prozess.