Samstag, 7. Mai 2011

Anwendung mit Administratorrechten neu starten (Windows Vista / 7)

In einem älteren Post habe ich gezeigt, wie man mit C# eine Anwendung mit Administratorechten ausstatten und starten kann.
Hierfür wurde jedoch eine eigene Datei, die Anwendungsmanifestdatei, benötigt.
Auf Anfrage eines Lesers möchte ich heute einen kleinen Trick vorstellen, wie man eine Anwendung nur durch reinen Code mit diesen Rechten ausstattet.
Entscheidend ist hierbei die Klasse System.Diagnostics, welche einen beliebigen Process mit bestimmten Argumenten starten kann.
Wenn die Anwendung also normal gestartet wird, wird sie über diese Klasse mit Administratorrechten neugestartet.
Damit das Programm nicht unendlich oft aufgerufen wird, geben wir dem Programm zur Prüfung beim Aufrufen ein neues Befehlszeilenargument mit.
Der folgende Code sollte das Beispiel erläutern:

private void Form1_Load(object sender, EventArgs e)
{
    string[] CommandLineArgs = Environment.GetCommandLineArgs(); // Befehlszeilenargumente auslesen
    if (CommandLineArgs.Length <= 1 || CommandLineArgs[1] != "restarted") // ist das 2. Argument (das 1. ist immer der Dateipfad) != restarted, wurde das Programm noch nicht neugestartet
    {
        ProcessStartInfo ProcessInfo = new ProcessStartInfo(Application.ExecutablePath, "restarted"); // Prozessinformationen festlegen, Anwendungspfad und unser eigenes Argument "restarted"
        ProcessInfo.Verb = "runas"; // Befehl zum Ausführen als Administrator
        Process.Start(ProcessInfo); // Prozess mit den eingestellten Informationen starten
    }
    else
        Environment.Exit(0); // wurde das Argument "restarted" übergeben, wurde das Programm bereits gestartet, um die Endlosrekursion zu verhindern, nicht erneut aufrufen
}

Kommentare:

  1. Wenn ich allerdings auf Nein Klicke wird die GUI immer noch angezeigt!

    AntwortenLöschen
  2. Es wurde allerdings eine Exeption geworfen mit try{ ....} catch{Application.Exit();} Lässt sich das Problem lösen.(Win 7)

    AntwortenLöschen
  3. Sollte das Environment.Exit nicht nach dem Starten des Prozesses passieren?

    AntwortenLöschen
  4. SChau ein liebesVieh

    AntwortenLöschen
  5. Interessant wäre noch, wie man die eigene Anwendung beim Systemstart als Administrator starten lassen kann, ohne dabei jedesmal wieder den UAC-Dialog bestätigen zu müssen.

    Anscheinend soll das mittels Scheduled Tasks oder mittels Windows-Services funktionieren, erscheint mir aber doch recht komplex.

    AntwortenLöschen
  6. Dieser Kommentar wurde vom Autor entfernt.

    AntwortenLöschen
  7. Ich weiß zwar nicht, ob der Code in Ordnung ist, da Anfänger, aber ich habe den etwas angepasst mit try/catch, gerade wenn man mit VS testet, da wenn man die Ausführung verneint, erscheint eine Fehlermeldung von VS :)

    Getestet mit Windows 10, VS 2015.

    try
    {
    var commandLineArgs = Environment.GetCommandLineArgs(); // Befehlszeilenargumente auslesen
    if (commandLineArgs.Length <= 1 || commandLineArgs[1] != "restarted") // ist das 2. Argument (das 1. ist immer der Dateipfad) != restarted, wurde das Programm noch nicht neugestartet
    {
    var processInfo = new ProcessStartInfo(Application.ExecutablePath, "restarted") /* Prozessinformationen festlegen, Anwendungspfad und unser eigenes Argument "restarted" */
    {Verb = "runas"}; /* Befehl zum Ausführen als Administrator */
    Process.Start(processInfo); /* Prozess mit den eingestellten Informationen starten */
    }
    else
    Environment.Exit(0); // wurde das Argument "restarted" übergeben, wurde das Programm bereits gestartet, um die Endlosrekursion zu verhindern, nicht erneut aufrufen
    }
    catch (Exception)
    {
    Environment.Exit(0); // wurde das Argument "restarted" übergeben, wurde das Programm bereits gestartet, um die Endlosrekursion zu verhindern, nicht erneut aufrufen
    }

    AntwortenLöschen
  8. Edit:
    Ich konnte noch etwas anderes finden, was in der Regel funktioniert, der Code aus dem Beitrag wird nicht benötigt.

    Im Menü "Project -> Add new item > Application Manifest file" (app.manifest) kann ebenfalls der UAC gesteuert werden, mögliche Werte: asInvoker, requireAdministrator, highestAvailable. Wie es mit der digitalen Signatur aussieht, wäre eine andere Frage. In VS erscheint selber kein UAC, wenn die exe direkt ausgeführt wird, dann ja. Das Standard-Symbol enthält ein kleines UAC-Symbol.

    In Zeile 19 asInvoker mit requireAdministrator tauschen, Projekt kompilieren und die exe-Datei direkt ausführen ;)

    Wem UAC stört, kann dies zwar die Sicherheitsstufe "runter schrauben", sollte aber doch bedenken, dass es Sicherheitsrisiken geben kann.

    AntwortenLöschen