84 Stimmen

Wie können Berechtigungen nur bei Bedarf erhöht werden?

Diese Frage gilt für Windows Vista!

Ich habe eine Anwendung, die normalerweise ohne administrative Berechtigungen funktioniert. Es gibt eine Aktivität, für die administrative Rechte erforderlich sind, aber ich möchte die Anwendung selbst nicht mit höheren Rechten starten, wenn ich weiß, dass die meiste Zeit der Benutzer diese Funktion gar nicht nutzt.

Ich denke über eine bestimmte Methode nach, mit der ich die Berechtigungen der Anwendung bei einem bestimmten Ereignis (z. B. Drücken einer Taste) erhöhen kann. Beispiel:

Wenn der Benutzer auf diese Schaltfläche klickt, wird er zu einem UAC-Dialog oder zur Zustimmung aufgefordert. Wie kann ich dies tun?

59voto

Noldorin Punkte 138548

Ich glaube nicht, dass es möglich ist, den aktuell laufenden Prozess zu erhöhen. Soweit ich weiß, ist es in Windows Vista eingebaut, dass einem Prozess beim Start Administratorrechte erteilt werden. Wenn Sie sich verschiedene Programme ansehen, die die UAC nutzen, sollten Sie sehen, dass sie jedes Mal einen separaten Prozess starten, wenn eine administrative Aktion durchgeführt werden muss (Task Manager ist eines davon, Paint.NET ist ein anderes, wobei letzteres tatsächlich eine .NET-Anwendung ist).

Die typische Lösung für dieses Problem ist die Angabe von Befehlszeilenargumenten beim Starten eines erhöhten Prozesses (der Vorschlag von abatishchev ist eine Möglichkeit, dies zu tun), so dass der gestartete Prozess nur ein bestimmtes Dialogfeld anzeigen kann und dann beendet wird, nachdem diese Aktion abgeschlossen wurde. Auf diese Weise sollte es dem Benutzer kaum auffallen, dass ein neuer Prozess gestartet und dann beendet wurde, und es würde eher so aussehen, als ob ein neues Dialogfeld innerhalb der gleichen Anwendung geöffnet wurde (vor allem, wenn man das Hauptfenster des erhöhten Prozesses mit einigen Tricks zu einem Kind des Elternprozesses macht). Wenn Sie keine Benutzeroberfläche für den erweiterten Zugriff benötigen, umso besser.

Für eine ausführliche Diskussion über UAC unter Vista empfehle ich Ihnen dieser sehr durchdachte Artikel zu diesem Thema (Codebeispiele sind in C++, aber ich vermute, dass Sie die WinAPI und P/Invoke verwenden müssen, um die meisten Dinge in C# zu tun). Hoffentlich sehen Sie jetzt zumindest den richtigen Ansatz, obwohl die Entwicklung eines UAC-kompatiblen Programms alles andere als trivial ist...

17voto

abatishchev Punkte 94886

Wie schon gesagt wurde dort :

Process.StartInfo.UseShellExecute = true;
Process.StartInfo.Verb = "runas";

führt den Prozess als Administrator aus, damit Sie mit der Registrierung tun können, was Sie wollen, kehrt aber mit den normalen Rechten zu Ihrer Anwendung zurück.

13voto

FruitBreak Punkte 570

Der folgende MSDN KB-Artikel 981778 beschreibt, wie man eine Anwendung "selbst anhebt":

http://support.microsoft.com/kb/981778

Es enthält herunterladbare Beispiele in Visual C++, Visual C# und Visual Basic.NET.

Mit diesem Ansatz wird die Notwendigkeit, einen separaten Prozess zu starten, umgangen, aber tatsächlich wird die ursprüngliche Anwendung neu gestartet und als erweiterter Benutzer ausgeführt. Dennoch kann dies in einigen Kontexten, in denen es nicht sinnvoll ist, Code in einer separaten ausführbaren Datei zu duplizieren, sehr nützlich sein.

Um die Erhöhung zu entfernen, müssen Sie die Anwendung beenden.

5voto

Richard Punkte 103159

Sie benötigen einen UAC-Moniker und den Code, der als COM-Objekt erhöht ausgeführt werden soll.

Siehe diese Frage.

Dokumentation auf MSDN.

3voto

Konstantin S. Punkte 942

Vielleicht kommt jemandem dieses einfache Beispiel gelegen:

using System;
using System.Linq;
using System.Reflection;
using System.Diagnostics;
using System.Security.Principal;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    internal static class Program
    {
        private class Form1 : Form
        {
            internal Form1()
            {
                var button = new Button{ Dock = DockStyle.Fill };
                button.Click += (sender, args) => RunAsAdmin();
                Controls.Add(button);

                ElevatedAction();
            }
        }

        [STAThread]
        internal static void Main(string[] arguments)
        {
            if (arguments?.Contains("/run_elevated_action") == true)
            {
                ElevatedAction();
                return;
            }

            Application.Run(new Form1());
        }

        private static void RunAsAdmin()
        {
            var path = Assembly.GetExecutingAssembly().Location;
            using (var process = Process.Start(new ProcessStartInfo(path, "/run_elevated_action")
            {
                Verb = "runas"
            }))
            {
                process?.WaitForExit();
            }
        }

        private static void ElevatedAction()
        {
            MessageBox.Show($@"IsElevated: {IsElevated()}");
        }

        private static bool IsElevated()
        {
            using (var identity = WindowsIdentity.GetCurrent())
            {
                var principal = new WindowsPrincipal(identity);

                return principal.IsInRole(WindowsBuiltInRole.Administrator);
            }
        }

    }
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X