2009-07-27 4 views
12

Weiß jemand, wie ich programmgesteuert (mit C#) überprüfen kann, ob mein Programm einen bestimmten Registrierungsschlüssel (speziell: "SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Run") lesen/schreiben kann?Wie überprüfe ich, ob ein Benutzer einen bestimmten Registrierungsschlüssel lesen/schreiben darf?

Ich frage, weil mein Programm die Möglichkeit hat, das Verhalten beim Start zu aktivieren oder zu deaktivieren. Ich möchte diese Option deaktivieren, wenn der aktuelle Benutzer keine Änderungen an der Registrierung vornehmen darf. Darf dieser Schlüssel immer vom aktuellen Benutzer geschrieben werden, oder besteht die Möglichkeit, dass er gesperrt wurde? Wenn letzteres, wie überprüfe ich das?

Ich habe mehrere widersprüchliche Möglichkeiten zur Überprüfung von Registrierungsberechtigungen gesehen - aber im Grunde kann ich keinen Weg finden, einen bestimmten Schlüssel zu überprüfen, bevor ich versuche, ihn zu lesen. Ich würde eher die Überprüfung durchführen, bevor ich auf den Schlüssel zugreife, als zu versuchen, darauf zuzugreifen und eine Ausnahme zu erhalten.

Jede Hilfe wird sehr geschätzt.

Tom

+2

Als allgemeine Faustregel gilt, dass die lokalen Computertasten eine Administratorberechtigung erfordern, die aktuellen Benutzerschlüssel jedoch nicht. – Brian

+0

Danke Brian - also kann man davon ausgehen, dass ich in diesen Schlüssel schreiben kann (es wird direkt zum Benutzerschlüssel geleitet) und einfach die Option immer aktiviert lassen, und dann alle Ausnahmen behandeln, die es werfen könnte, wenn es schief geht? – Beardy

Antwort

13

Die Klasse RegistryPermission regelt die Sicherheitsberechtigungen für reg-Schlüssel. Um zu überprüfen, ob Sie Schreibzugriff auf eine Berechtigung haben, können Sie es auf folgende Weise verwenden:

RegistryPermission perm1 = new RegistryPermission(RegistryPermissionAccess.Write, @"SOFTWARE\Microsoft\Windows\CurrentVersion\Run"); 

Sie würden dann die „Demand“ Methode in einem try/catch verwenden und Return on Ausfall (das Anheben eines Sicherheits Ausnahme). Bei Erfolg würden Sie fortfahren und Ihr Update durchführen. Obwohl dies nicht ganz das ist, was Sie wollen, ist eine Überprüfung der Berechtigungen vor dem Zugriff die akzeptierte Methode, um sicherzustellen, dass Sie über die Berechtigungen verfügen, die Sie benötigen, bevor Sie mit den Schlüsseln arbeiten.In einer vollständig strukturiert entspräche dies:

try 
{ 
    RegistryPermission perm1 = new RegistryPermission(RegistryPermissionAccess.Write, @"SOFTWARE\Microsoft\Windows\CurrentVersion\Run"); 
    perm1.Demand(); 
} 
catch (System.Security.SecurityException ex) 
{ 
    return; 
} 

//Do your reg updates here 

EDIT: Denken an, was ich im Kommentar erwähnt, hier Erweiterungsmethoden der Registry Klasse für Berechtigungsprüfungen sind:

using System.Security.Permissions; 
using System.Security; 

public static class RegistryExtensions 
{ 
    public static bool HavePermissionsOnKey(this RegistryPermission reg, RegistryPermissionAccess accessLevel, string key) 
    { 
     try 
     { 
      RegistryPermission r = new RegistryPermission(accessLevel, key); 
      r.Demand(); 
      return true; 
     } 
     catch (SecurityException) 
     { 
      return false; 
     } 
    } 

    public static bool CanWriteKey(this RegistryPermission reg, string key) 
    { 
     try 
     { 
      RegistryPermission r = new RegistryPermission(RegistryPermissionAccess.Write, key); 
      r.Demand(); 
      return true; 
     } 
     catch (SecurityException) 
     { 
      return false; 
     } 
    } 

    public static bool CanReadKey(this RegistryPermission reg, string key) 
    { 
     try 
     { 
      RegistryPermission r = new RegistryPermission(RegistryPermissionAccess.Read, key); 
      r.Demand(); 
      return true; 
     } 
     catch (SecurityException) 
     { 
      return false; 
     } 
    } 
} 
+0

Danke wolfwrd :) – Beardy

+0

Kein Problem, und um die Funktionalität im Stil zum Kommentar auf Joel Coehoorns Antwort zu bekommen, kann man diesen Versuch immer einpacken/fange in einer Methode in deiner Klasse (oder als eine Erweiterungsmethode für die Registry vielleicht) und gib das Wahr/Falsch zurück, das du sehen willst – Wolfwyrd

+0

^^ Just done this now: P – Beardy

0

Ich bin nicht sicher, wie man es mit C#, aber mit Win32, würden Sie RegGetKeySecurity() verwenden. Vielleicht gibt es einen C# -Wrapper? Andernfalls verwenden Sie P/Invoke.

6

Eine Sache, die Sie über Berechtigungen wissen sollten, ist, dass sie flüchtige sind. Das bedeutet, dass Sie Ihre Sicherheitsüberprüfung des Registrierungsschlüssels durchführen und versuchen können, Ihren Wert nur hinzuzufügen, wenn die Überprüfung erfolgreich ist, und weiterhin fehlschlägt mit einer unzureichenden Zugriffsausnahme, da sich die Berechtigungen zwischen dem Zeitpunkt der Überprüfung und dem Zeitpunkt des Handelns geändert haben über die Ergebnisse. Dies ist auch möglich, wenn es sich um aufeinanderfolgende Anweisungen in Ihrem Programm handelt.

Gewährt Sicherheitsberechtigungen sind relativ stabil, aber die Chance besteht noch. Das bedeutet, dass Sie Code haben müssen, um die Sicherheitsausnahme zu behandeln, und wenn Sie das trotzdem tun müssen, gibt es keinen wirklichen Punkt, den Scheck an erster Stelle zu machen. Nehmen Sie sich stattdessen Zeit, um Ihren Exception-Handler ein wenig besser zu machen.

Das sagte "boo" zu jeder App, die beim Start etwas ausführen möchte. YAGNI.

+0

Nun, die App wird standardmäßig nicht beim Start ausgeführt, aber es besteht eine gute Chance, dass der Benutzer dieses Verhalten aufgrund der Art und des Zwecks des Produkts trotzdem möchte. Besser, es verfügbar zu machen, anstatt den Benutzer zu zwingen, es manuell imo zu tun. Ich möchte das Get/Set-Verhalten die Ausnahmebehandlung verwenden, aber im Optionen-Dialog würde ich lieber etwas wie RunAtStartup.Enabled = Registry.CanWriteToKey() verwenden, wenn Sie die Idee bekommen. Es macht nicht viel Sinn für mich, eine Ausnahme in einen booleschen zu verwandeln:/ – Beardy

5

Ich denke, dass Sie am besten versuchen, Ihren Wert zu dem Schlüssel hinzuzufügen, und Fehler ordnungsgemäß behandeln, indem Sie den Benutzer informieren, dass sie nicht über ausreichende Berechtigungen zu dem Ausführen des Schlüssels verfügen.

Wenn Sie eine Art Verwaltungstool schreiben, das immer von einem Administrator ausgeführt werden soll, sollten Sie dies unter manifest angeben. Auf diese Weise erhöht sich Ihre App beim Start (über die UAC-Eingabeaufforderung).

0

Nur Versuchen Sie, den Registrierungsschlüssel mit WRITE-Berechtigungen zu öffnen.

Das sagte, was andere gesagt haben, ist richtig: Es gibt keine Möglichkeit zu sagen, ob eine Operation erfolgreich sein wird, wenn Sie es nicht versuchen. Vielleicht hat jemand die Run-Taste gelöscht. Vielleicht überschreitet die Registrierung den zugewiesenen Speicher. Vielleicht ist die Festplatte ausgefallen.

1

Einfachste Option ist zu versuchen und open der Schlüssel mit Schreibzugriff und sehen, ob Sie es bekommen. Erinnern Sie sich an close den Schlüssel danach.

bool fWriteAccess; 
try { 
    Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\Windows\CurrentVersion\Run", True).Close(); 
    fWriteAccess = True; 
} catch (SecurityException) { 
    fWriteAccess = False; 
}