Prozessprivilegien programmgesteuert erhöhen?

147

Ich versuche, einen Dienst mit InstallUtil.exe zu installieren, werde aber über aufgerufen Process.Start. Hier ist der Code:

ProcessStartInfo startInfo = new ProcessStartInfo (m_strInstallUtil, strExePath);
System.Diagnostics.Process.Start (startInfo);

Wo m_strInstallUtilist der vollständig qualifizierte Pfad und die Exe zu "InstallUtil.exe" und strExePathist der vollständig qualifizierte Pfad / Name zu meinem Dienst.

Das Ausführen der Befehlszeilensyntax an einer Eingabeaufforderung mit erhöhten Rechten funktioniert. Das Ausführen von meiner App (unter Verwendung des obigen Codes) funktioniert nicht. Ich gehe davon aus, dass ich ein Problem mit der Prozesserhöhung habe. Wie würde ich meinen Prozess in einem erhöhten Zustand ausführen? Muss ich mir das ansehen ShellExecute?

Dies ist alles unter Windows Vista. Ich führe den Prozess im VS2008-Debugger aus, der auf Administratorrechte erhöht ist.

Ich habe auch versucht einzustellen, startInfo.Verb = "runas";aber es schien das Problem nicht zu lösen.

Scott Marlowe
quelle
Nachdem ich zusätzlich hinzugefügt habe startInfo.UseShellExecute = true;, hat startInfo.Verb = "runas";es für mich gut funktioniert.
Matt

Antworten:

172

Sie können angeben, dass der neue Prozess mit erhöhten Berechtigungen gestartet werden soll, indem Sie die Verb-Eigenschaft Ihres startInfo-Objekts wie folgt auf 'runas' setzen:

startInfo.Verb = "runas";

Dadurch verhält sich Windows so, als ob der Prozess im Explorer mit dem Menübefehl "Als Administrator ausführen" gestartet wurde.

Dies bedeutet, dass die UAC-Eingabeaufforderung angezeigt wird und vom Benutzer bestätigt werden muss: Wenn dies unerwünscht ist (z. B. weil dies mitten in einem längeren Prozess geschehen würde), müssen Sie Ihren gesamten Host-Prozess mit ausführen Erhöhte Berechtigungen durch Erstellen und Einbetten eines Anwendungsmanifests (UAC) , um die Ausführungsstufe "Höchste Verfügbarkeit" zu erfordern: Dadurch wird die UAC-Eingabeaufforderung angezeigt, sobald Ihre App gestartet wird, und alle untergeordneten Prozesse werden mit erhöhten Berechtigungen ohne zusätzliche Aufforderung ausgeführt .

Bearbeiten: Ich sehe, Sie haben gerade Ihre Frage bearbeitet, um festzustellen, dass "Runas" bei Ihnen nicht funktioniert haben. Das ist wirklich seltsam, wie es sollte (und für mich in mehreren Produktions-Apps). Es sollte jedoch auf jeden Fall funktionieren, wenn der übergeordnete Prozess durch Einbetten des Manifests mit erhöhten Rechten ausgeführt werden muss.

mdb
quelle
9
"runas" hat auch bei mir nicht funktioniert. Könnte es sein, dass es nur mit ausgeschalteter Benutzerkontensteuerung funktioniert?
Dirk Vollmar
18
@ LukePuplett Ich würde ihnen danken. Dies ist eine großartige Möglichkeit, die Installation des Root-Kits zu verringern, ohne die Benutzerrollen vollständig zu trennen.
Colton
6
@ Sparksis, aber es gibt auch einen anderen Standpunkt. Die Leute, die wissen, wie man ihr Betriebssystem verteidigt, wissen, wie man es ohne UAC macht. Und Dummy-Benutzer, die nicht wissen, was Verteidigung ist, klicken jedes Mal auf "JA", wenn sie das UAC-Fenster sehen. Auch nichts kann Bad-Hacker-Virus-Autoren daran hindern, Exploits zu verwenden, um es zu umgehen;) Also stimme ich LukePuplett zu =)
Jet
23
Sieht so aus, startInfo.ShellExecute=trueals müssten Sie auch festlegen, dass dies funktioniert. Außerdem konnte ich diese Methode nicht für ausführbare Dateien verwenden, die sich auf einer Netzwerkfreigabe befinden (sie müssen vor dem Ausführen in das lokale temporäre Verzeichnis kopiert werden). ..
TCC
7
@Jet Sorry, aber das ist die falsche Einstellung. Jedes Mal, wenn während der Installation ein UAC-Dialogfeld angezeigt wird, liegt ein Systemfehler vor. Es ist wertvoll, wenn Sie eine UAC-Box sehen, ohne etwas auszuführen, das eine Erhöhung erfordert. Egal, wie professionell Sie - jeder von uns - denken, wir sind auf unseren PCs, Sie können Zero-Days / Drive-by-Downloads nicht auf magische Weise blockieren (z. B. einen kürzlich auf der offiziellen Nobelpreis-Website veröffentlichten). Wenn Sie zu dieser Site navigiert sind und eine UAC-Eingabeaufforderung erhalten haben, wissen Sie, dass etwas nicht stimmt. Wenn die Benutzerkontensteuerung deaktiviert ist, werden Sie nie erfahren, dass Sie gerade einem Botnetz beigetreten sind. Die Kosten für die Vorwarnung müssen gelegentlich auf Ja klicken
Basic
46

Dieser Code fügt das vor allem zusammen und startet die aktuelle wpf-App mit admin privs neu:

if (IsAdministrator() == false)
{
    // Restart program and run as admin
    var exeName = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
    ProcessStartInfo startInfo = new ProcessStartInfo(exeName);
    startInfo.Verb = "runas";
    System.Diagnostics.Process.Start(startInfo);
    Application.Current.Shutdown();
    return;
}

private static bool IsAdministrator()
{
    WindowsIdentity identity = WindowsIdentity.GetCurrent();
    WindowsPrincipal principal = new WindowsPrincipal(identity);
    return principal.IsInRole(WindowsBuiltInRole.Administrator);
}


// To run as admin, alter exe manifest file after building.
// Or create shortcut with "as admin" checked.
// Or ShellExecute(C# Process.Start) can elevate - use verb "runas".
// Or an elevate vbs script can launch programs as admin.
// (does not work: "runas /user:admin" from cmd-line prompts for admin pass)

Update: Der App-Manifest-Weg wird bevorzugt:

Klicken Sie mit der rechten Maustaste auf das Projekt in Visual Studio, fügen Sie eine neue Anwendungsmanifestdatei hinzu, und ändern Sie die Datei so, dass Sie den Administrator wie oben gezeigt eingestellt haben.

Ein Problem mit der ursprünglichen Methode: Wenn Sie den Neustartcode in app.xaml.cs OnStartup einfügen, wird das Hauptfenster möglicherweise kurz gestartet, obwohl Shutdown aufgerufen wurde. Mein Hauptfenster ging in die Luft, wenn app.xaml.cs init nicht ausgeführt wurde und dies unter bestimmten Rennbedingungen der Fall war.

Curtis Yallop
quelle
Siehe unten für Verbesserungen.
JCCyC
requireAdministrator hat in meinem Fall nicht funktioniert. Also musste ich es auf deine Weise tun. Das hat mein Problem gelöst! Danke. Aber ich musste Single Instance Application auf false setzen.
Chris
Das hat bei mir funktioniert. Ich habe auch das Original string[] argsan den Respawn-Prozess übergeben.
DotNetPadawan
7
[PrincipalPermission(SecurityAction.Demand, Role = @"BUILTIN\Administrators")]

Dies geschieht ohne Benutzerkontensteuerung - Sie müssen keinen neuen Prozess starten. Wenn der laufende Benutzer wie in meinem Fall Mitglied der Admin-Gruppe ist.

hB0
quelle
3
Bei Verwendung dieses Codes wird ein Berechtigungsfehler angezeigt: "Anforderung der Berechtigung für Sicherheitsentität fehlgeschlagen." :(
Leonardo
Vielleicht "Wenn der laufende Benutzer Mitglied von Admin ist" *
hB0
1
Interessant - dies kann für jede Methode gelten, nicht nur für eine Aktionsmethode (ich habe es sogar mit einer auf einer ASPX-Seite definierten Methode versucht)
Simon_Weaver
1

Sie sollten Identitätswechsel verwenden, um den Status zu erhöhen.

WindowsIdentity identity = new WindowsIdentity(accessToken);
WindowsImpersonationContext context = identity.Impersonate();

Vergessen Sie nicht, den imitierten Kontext rückgängig zu machen, wenn Sie fertig sind.

Vijesh VP
quelle
28
Sie haben nicht gesagt, wie Sie das accessToken erhalten. LogonUser stellt den eingeschränkten Sicherheitskontext eines Benutzers bereit, wenn die Benutzerkontensteuerung aktiviert ist.
cwa
Wenn Sie VSTS verwenden, können Sie über die Einstellungen im Webportal ein persönliches Zugriffstoken abrufen. (Suchen Sie nach dem Einstellungssymbol neben dem Benutzerbild.) MSDocs
Su Llewellyn