Wie kann man Berechtigungen nur bei Bedarf erhöhen?

84

Diese Frage gilt für Windows Vista!

Ich habe eine Anwendung, die normalerweise ohne Administratorrechte funktioniert. Es gibt eine Aktivität, für die Administratorrechte erforderlich sind, aber ich möchte die Anwendung selbst nicht mit höheren Berechtigungen starten, wenn ich weiß, dass Benutzer diese Funktion meistens nicht einmal verwenden.

Ich denke über eine bestimmte Methode nach, mit der ich die Anwendungsrechte bei bestimmten Ereignissen erhöhen kann (z. B. per Knopfdruck). Beispiel:

Wenn der Benutzer auf diese Schaltfläche klickt, wird er mit einem UAC-Dialog oder einer Einwilligung aufgefordert. Wie kann ich das machen?

Hemant
quelle

Antworten:

58

Ich glaube nicht, dass es möglich ist, den aktuell laufenden Prozess zu verbessern. In Windows Vista ist integriert, dass einem Prozess nach meinem Verständnis Administratorrechte beim Start erteilt werden. Wenn Sie sich verschiedene Programme ansehen, die die Benutzerkontensteuerung verwenden, sollten Sie feststellen, dass sie jedes Mal, wenn eine Verwaltungsaktion ausgeführt werden muss, einen separaten Prozess starten (Task-Manager ist eines, Paint.NET ist ein anderes, letzteres ist tatsächlich eine .NET-Anwendung ).

Die typische Lösung für dieses Problem besteht darin, beim Starten eines Prozesses mit erhöhten Rechten Befehlszeilenargumente anzugeben (der Vorschlag von abatishchev ist eine Möglichkeit, dies zu tun), damit der gestartete Prozess nur ein bestimmtes Dialogfeld anzeigen und nach Abschluss dieser Aktion beenden kann abgeschlossen. Daher sollte es für den Benutzer kaum wahrnehmbar sein, dass ein neuer Prozess gestartet und dann beendet wurde, und es würde eher so aussehen, als ob ein neues Dialogfeld innerhalb derselben App geöffnet wurde (insbesondere, wenn Sie etwas Hackerei betreiben, um das Hauptfenster des zu erstellen erhöhter Prozess ein Kind des übergeordneten Prozesses). Wenn Sie keine Benutzeroberfläche für den erhöhten Zugriff benötigen, ist dies sogar noch besser.

Für eine vollständige Diskussion der Benutzerkontensteuerung unter Vista empfehle ich, dass Sie diesen Artikel zu diesem Thema lesen (Codebeispiele sind in C ++ enthalten, aber ich vermute, dass Sie WinAPI und P / Invoke verwenden müssen, um die meisten Aufgaben in C # auszuführen wie auch immer). Hoffentlich sehen Sie jetzt zumindest den richtigen Ansatz, obwohl das Entwerfen eines UAC-kompatiblen Programms alles andere als trivial ist ...

Noldorin
quelle
4
Gibt es Änderungen bei Windows 7 oder gilt die Antwort "Nein, neuen Prozess verwenden"? Danke ...
Radim Vansa
2
Keine Änderung mit Windows 7 Ich fürchte, sorry. (Soweit ich weiß, und ich bin ein regelmäßiger Benutzer / Entwickler auf Win7.)
Noldorin
2
Genau so macht es der Task-Manager. Wenn Sie auf die Schaltfläche klicken, um Aufgaben für alle Benutzer anzuzeigen, die vorhanden sind, ruft der aktuelle Task-Manager einen anderen Task-Manager mit Administratorrechten auf.
Natalie Adams
3
@NathanAdams Technisch gesehen wird zuerst der neue Task-Manager geöffnet. Was macht sonst die Eröffnung? :-)
wizzwizz4
16

Wie dort gesagt wurde :

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

führt den Prozess als Administrator aus, um mit der Registrierung alles zu tun, was Sie benötigen, kehrt jedoch mit den normalen Berechtigungen zu Ihrer App zurück.

abatishchev
quelle
Das beinhaltet das Überspannen eines neuen Prozesses. richtig? Ich suchte nach einer Erhöhung der Privilegien des aktuellen Prozesses.
Hemant
Versuchen Sie es mit Process.GetCurrentProcess ()
abatishchev
27
Sie können einen aktuell ausgeführten Prozess nicht erhöhen.
Jacob Proffitt
1
Das ist nicht wahr. Sie können den Eigentümer des Prozesses ändern und die DACL- und ACL-Werte für den Benutzer festlegen, der ihm Verwaltungsbefugnisse
erteilt
4
@ nightforce2: Dies würde sicherlich nur funktionieren, wenn Sie bereits Administratorrechte haben (dh Sie sind bereits erhöht). Andernfalls schlagen AdjustTokenPrivileges usw. einfach fehl, oder?
Ben Schwehn
13

Der folgende MSDN-KB-Artikel 981778 beschreibt, wie Sie eine Anwendung selbst erhöhen:

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 umgangen, einen separaten Prozess zu starten. Tatsächlich wird jedoch die ursprüngliche Anwendung neu gestartet und als Benutzer mit erhöhten Rechten ausgeführt. Trotzdem kann dies in einigen Kontexten sehr nützlich sein, in denen es nicht praktikabel ist, Code in einer separaten ausführbaren Datei zu duplizieren.

Um die Erhebung zu entfernen, müssen Sie die Anwendung beenden.

FruitBreak
quelle
1
Praktisch für eine Schaltfläche, aber wenn Sie dasselbe für einen Menüpunkt möchten, stehen Sie vor einem wirklich verworrenen Durcheinander.
Nyerguds
Der Link der Antwort ist tot und der Link des Kommentars verweist auf eine Liste mit 2608 Elementen.
DonBoitnott
2

Vielleicht ist jemand in diesem einfachen Beispiel hilfreich:

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);
            }
        }

    }
}
Konstantin S.
quelle
1

Ich weiß, dass dies ein alter Beitrag ist, aber dies ist eine Antwort auf alle anderen, die auf MarcPs Vorschlag stoßen. Der MSDN-Beitrag, auf den er verwiesen hat, startet tatsächlich die Anwendungen in allen Codebeispielen neu. Die Codebeispiele verwenden dierunas bereits in anderen Vorschlägen vorgeschlagene Verb.

Ich habe den Code heruntergeladen, um sicherzugehen, aber dies ist aus dem ursprünglichen msdn-Artikel:

4. Klicken Sie auf Ja, um die Höhe zu genehmigen. Anschließend wird die ursprüngliche Anwendung neu gestartet und als Administrator mit erhöhten Rechten ausgeführt.
5. Schließen Sie die Anwendung.

SpaceGhost440
quelle
1
Können Sie den betreffenden MSDN-Link hinzufügen? Ich kann keinen Benutzer namens MarcP finden.
Alf