Adminrechte für Programm erlangen



  • Hallo

    Ich will ein Programm schreiben, das erstmal einfach ALLE Registry Einträge auslesen können soll. Ich bin sehr schnell auf das Problem der fehlenden rechte gestossen.. D.h. mein Programm benötigt die Rechte um in der Registry zu lesen (und später auch um zu schreiben, zu ändern und zu löschen). Ich möchte, dass mein Programm nachfragt, ob es die Rechte bekommt, wie ein Installer. Leider habe ich keine Ahnung wie ich das bewerkstelligen kann. Hab einiges ausprobiert, mit Manifest (requestedExecutionLevel level="requireAdministrator"), mit RegistryPermission.Demand(), etc.). Hab auch einige Dinge dazu gelesen (z.b. http://www.codeproject.com/KB/vista-security/UAC__The_Definitive_Guide.aspx), aber um ehrlich zu sein: Ich blick da nicht durch und wäre sehr froh, wenn ihr mir auf die Sprünge helfen könntet.
    Sowohl das Manifest als auch die anderen Versuche, hatten keine Sichtbaren Auswirkungen, als ob sie ignoriert würden. Vielleicht habe ich diese Dinge auch nur falsch angewandt, bzw. die Permission-Demands am falschen Ort im Code platziert.. Ich hab wirklich keine Ahnung und einfach nur mal ausprobiert, was mir google vorgeschlagen hat^^

    Verwende:
    Vista 32bit
    MC# 2010 Express

    Im Moment ists noch ne einfache Konsolenanwendung..

    Bin sehr dankbar für hilfe!

    mfg

    :: edit ::

    So sieht meine Registryauslesmethode im Moment aus. Merkwürdig (in meinen Augen) ist, dass "rp.Demand()" (Zeile 17) noch nie was bewirkt hat, und der Fehler immer in Zeile 26 auftritt.

    public static void WriteRegTreeSnapShot(RegistryKey BaseKey, TextWriter Destination)
            {
                List<String> Keys = new List<String>();
                RegistryKey key;
                String[] Values;
                Int32 denied = 0;
    
                Keys.AddRange(BaseKey.GetSubKeyNames());
                Destination.WriteLine(BaseKey.Name);
    
                while (Keys.Count > 0)
                {
                    Values = new String[] { };
                    RegistryPermission rp = new RegistryPermission(RegistryPermissionAccess.Read, BaseKey.Name +"\\"+ Keys[0]);
                    try
                    {
                        rp.Demand();
                    }
                    catch (SecurityException e)
                    {
                        denied++;
                        Keys.RemoveAt(0); 
                        continue; 
                    }
    
                    key = BaseKey.OpenSubKey(Keys[0], false);
                    if (key == null)
                    {
                        Keys.RemoveAt(0);
                        continue;
                    } 
                    Values = key.GetSubKeyNames();
    
                    Destination.WriteLine(key.Name);
    
                    foreach (String s in Values)
                        Keys.Add(Keys[0] + "\\" + s);
                    key.Close();
                    Keys.RemoveAt(0);
                }
                Destination.WriteLine("Denied: " + denied.ToString() + " Keys");
            }
    

    Desweitern denke ich, dass es eine bessere Methode geben muss.. für jeden einzelnen Key um Erlaubnis zu fragen, kann nicht sehr effizient sein, oder sehe ich das falsch?



  • Also das mit dem Manifest einbinden funktioniert schon, allerdings weiß ich nicht wie das bei C# genau geht und es läuft nicht unter XP und es geht mit Code:

    using System;
    using System.Runtime.InteropServices;
    using System.Diagnostics;
    using System.Windows.Forms;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            [DllImport("shell32.dll")]
            public static extern bool IsUserAnAdmin();
    
            static void Main(string[] args)
            {
                if(!IsUserAnAdmin())
                {
                    Process proc = new Process();
                    proc.StartInfo.Verb = "runas";
                    proc.StartInfo.FileName = Application.ExecutablePath;
                    proc.Start();
                }
                    //Programm läuft hier mit Adminrechten...
            }
        }
    }
    

    Gruß
    Fabian



  • Danke für die Antwort.

    Reicht es zu überprüfen, ob der Benutzer ein Admin ist? Soviel ich gelesen haben, wird ein Programm unter Vista standardmässig nie mit Adminrechten ausgeführt, auch nicht wenn es von einem Admin gestartet wird, ausser es wird über "Als Administrator ausführen" gestartet.. Und ich möchte nicht, dass mein Programm so gestartet werden muss, und andernfalls einfach abstürzt.. Was mir gefallen würde, wäre ein Dialog, der dem User die Möglichkeit gibt, sich als Administrator auszuweisen, wie man das von gängigen Installern und Setups her kennt.



  • Dieser Code prüft, ob das Programm Administratorenrechte hat.
    (Dies funktioniert auch unter Vista und 7. Ich benutze den Code in C++ selbst.)

    Wenn nicht, wird der "Ausführen als..."- bzw. "Benutzerkontensteuerung"-Dialog angezeigt. Bei Usern mit Administratorenrechten, muss man dann einfach "Ja" klicken, bei welchen ohne eben ein Administratorkennwort eingeben.

    Es ist also das gleiche wie ein Manifest nur ohne das Shield-Icon auf dem Programm-Icon und es funktioniert auch unter Windows XP.

    Gruß
    Fabian



  • Danke, das ist genau das, was ich gesucht habe 🙂

    P.S. sorry dass das mit dem Dank so lange gedauert hat, hatte probleme mit meinem PC...

    mfg


Anmelden zum Antworten