(Richtig) auf die Registry zugreifen

    • VB.NET

    Es gibt 7 Antworten in diesem Thema. Der letzte Beitrag () ist von Toorms.

      (Richtig) auf die Registry zugreifen

      Man sieht immer wieder, dass versucht wird, Werte aus der Registry mit My.Computer.Registry.* zu verändern/auslesen.
      Wenn man den My-Namspace umgehen möchte, sind die Klassen Microsoft.Win32.Registry bzw. Microsoft.Win32.RegistryKey unbedingt zu verwenden.

      Wie verwendet man den MS.Win32-Namespace um auf die Registry zuzugreiffen?
      Ganz einfach. Zuerst einmal den Microsoft.Win32-Namespace importieren.

      VB.NET-Quellcode

      1. Imports Microsoft.Win32


      Dann müssen wir einen RegistryKey instanzieren:

      VB.NET-Quellcode

      1. Dim Key As RegistryKey


      Vorsicht!!!: Weder Registry noch RegistryKey besitzen ein Konstruktor!

      Deshalb müssen wir Key folgendermaßen einen Wert zuweisen(in diesem Fall ist es der Schlüssel HKEY_LOCAL_MACHINE)

      VB.NET-Quellcode

      1. Key = Registry.LocalMachine


      Edit:Druch den Hinweis von @Artentus: hab eich folgende Zeile editiert:
      Da RegistryKey IDisposable implentiert, kann man die Methode Dispose aufrufen. Dies wäre sehr empfehlenswert.
      Noch besser wäre es, Using zu verwenden:

      VB.NET-Quellcode

      1. Using Key As RegistryKey = Registry.LocalMachine
      2. '...
      3. End Using


      Jetzt "sind" wir mit Key im Schlüssel HKEY_LOCAL_MACHINE

      Um z.B. in den Key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon zu kommen, muss es folgendermaßen aussehen:

      VB.NET-Quellcode

      1. Key = Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon")


      Jetzt "Sind" wir im Key SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon

      Aber um jetzt in den Schlüssel auch schreiben zu können, muss manbei OpenSubKey einen zweiten Paramter angeben:

      VB.NET-Quellcode

      1. Key = Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon", True)

      True bewirkt, dass man in den Schlüssel auch schreiben kann/darf.

      Um laut MSDN schnell er lesen zu können, muss man den Boolean entfernen und stattdessen einen Parameter vom Typ RegistryKeyPermissionCheck angeben:

      VB.NET-Quellcode

      1. Key = Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon", RegistryKeyPermissionCheck.ReadSubTree)
      Dies soll laut MSDN(Link oben) schneller sein als

      VB.NET-Quellcode

      1. Key = Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon", RegistryKeyPermissionCheck.Default)





      Wie liest man Werte in einem Schlüssel aus?

      Unser bisheriger Code schaut inetwa so aus:

      VB.NET-Quellcode

      1. Imports Microsoft.Win32
      2. Public Class RegistryTutorial
      3. Public Sub New()
      4. Using Key As RegistryKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon")
      5. End Using
      6. End Sub
      7. End Class


      Um jetzt Werte auszulesen, müssen wir folgendermaßen vorgehen:

      VB.NET-Quellcode

      1. Dim Shell As String = Key.GetValue("Shell")


      Wenn man jetzt Option Strict On hätte, das würde man wissen, das der obrige Code nicht möglich ist, da man "Object" nicht in konverntieren darf.

      Also:

      VB.NET-Quellcode

      1. Dim Shell As String = CStr(Key.GetValue("Shell"))


      Was ist jetzt wenn die Zeichenfolge nicht existiert? Dann wird Nothing zurückgegeben.

      Wenn etwas anderes als Nothing zurückgegeben werden soll, dann muss man bei GetValue einen zweiten Parameter angeben.
      Dieser zweite Parameter wird zurückgegben, falls die Zeichenfolge existiert.

      VB.NET-Quellcode

      1. Dim Shell As String = CStr(Key.GetValue("BlaBa", "Fehler"))

      Da es in diesem Schlüssel keinen Wert namens BlaBla gibt, wird Fehler zurückgegeben.




      Wie verändert man Werte in einem Schlüssel?

      Um Werte zu schreiben, braucht man nur:

      VB.NET-Quellcode

      1. Key.SetValue("Zeichenfolge", "Wert")


      Mit diesem Code wird in den Schlüssel HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon die Zeichenfolge "Zeichenfolge" mit dem Wert "Wert" erstellt.

      Wenn man jetzt auf die Zeichenfolge "(Standard)" zugreiffen will, muss der Parameter "name" leer sein:

      VB.NET-Quellcode

      1. Key.SetValue("", "Wert")


      Jetzt wird in den "(Standard)"-Wert der Text "Wert" geschreiben.

      Jetzt gibt es auch verschiedene Datentype, z.B. Zeichenfolge, DWord, Binärwert, ... Um z.B. einen DWord in die Registry zu schreiben, muss man bei SetValue einen dritten Parameter angeben, der den Datentyp bestimmt:

      VB.NET-Quellcode

      1. Key.SetValue("", 15, RegistryValueKind.DWord)

      Damit wird in der "(Standard)"-Wert, der eigentlich eine Zeichenfloge ist, in einen DWord-Typ "verwandelt" und der Wert 15 (Integer) wird reingeschrieben.




      Unterschlüssel hinzufügen/löschen

      Hinzufügen:

      Um einen Unterschlüssel hinzuzufügen(z.B. HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Hallo) muss man nicht viel machen:

      VB.NET-Quellcode

      1. Key.CreateSubKey("Hallo")


      Aber genau wie bei OpenSubKey muss man bei CreateSubKey auch angeben, ob man schreiben will/kann.

      VB.NET-Quellcode

      1. Key.CreateSubKey("Hallo", True)


      Falls man nicht weiß, ob ein Key existiert, kann man auch CreateSubKey verwenden. Falls der Key bereits existriert, wird er ncith überschrieben oder neu erzeugt.

      Löschen:

      Hinweis!!!: Um einen Key zu löschen, muss man den Key mit Schreibrechten geöffnet haben.

      VB.NET-Quellcode

      1. Key.DeleteSubKey("Hello")

      Der Key wird gelöscht, existiert er nicht, passiert nichts. Will man aber, das eine Exception ausgelöst wird, muss mein als zweiten Parameter True übergeben.

      VB.NET-Quellcode

      1. Key.DeleteSubKey("Hallo", True)

      Existiert er nicht, wird eine Exception ausgelöst.




      Hier der Code in einer Zusammenfassung:

      VB.NET-Quellcode

      1. Public Sub New()
      2. Using Key As RegistryKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon") "Öffnet den Key OHNE Schreibrechte (SetValue, DeleteSubKey, CrateSubKey führen zu Exceptions.)
      3. Dim Shell As String = CStr(Key.GetValue("BlaBa", "Fehler"))'Liest den Wert 'BlaBla' aus
      4. Key.SetValue("Zeichenfolge", "Wert") 'Ändern/Erstellt 'Zeichenfolge' und ändert den Wert auf 'Wert'
      5. Key.CreateSubKey("Hallo", True) 'Wird mit Schreibrechten geöffnet.
      6. Key.DeleteSubKey("Hallo", True) 'Exception wird ausgelöst, falls er nicht existiert.
      7. End Using
      8. End Sub





      Credits:
      @Artentus: --> Beitrag 2

      Ich hoffe das Tutorial war hilfreich. :thumbsup:

      Grüße,
      Luki-Progger
      Grüße,
      Lukas

      Fragen über Themen im Forum per Konversation werden gelöscht und die Absender blockiert...

      Dieser Beitrag wurde bereits 7 mal editiert, zuletzt von „Luki-Progger“ ()

      Gutes Tutorial, sowas hat hier definitiv noch gefehlt.

      Eine Kleinigkeit dazu:
      Dim Shell As String = Key.GetValue("Shell").ToString
      Normalerweise wird man ja immer dazu angehalten, ToString() statt CStr() zu verwenden, was eigentlich auch vollkommen richtig ist. Nur würde ich das in genau diesem Fall nicht tun. Warum? Nun du bekommst hier nicht irgendein Object zurück, sondern einen String, dieser wird nur als Object zurückgegeben, weil halt manchmal auch Integer oder sonstiges zurückkommen kann. Wenn du nun also ToString() aufrufst, dann rufst du String.ToString() auf, was etwas sinnlos ist. Hier kann man auch ohne Sorge casten:

      VB.NET-Quellcode

      1. Dim Shell As String = DirectCast(Key.GetValue("Shell"), String)
      Dadurch holt man den tatsächlichen String aus dem Object raus, ohne ihn erst mit ToString() zu kopieren.

      Außerdem implementiert RegistryKey IDisposable, weswegen man auch entweder Dispose aufrufen oder Using verwenden sollte.
      Räumt der GC nicht automatisch die unmanaged resourcen auf, bzw. hat das ne Performance beinträchtigung,wenn man weder Dispose aufruft noch das using statement benutzt?
      Hallo,

      du hast im Using einen Rechtschreibfehler drin.

      In der Zusammenfassung schreibst du als Kommentar "Liest den Wert 'Shell' aus" liest im Code aber Blabla aus, das sollte schon zusammenpassen.
      Beim SubKey erstellen ist wieder ein Fehler drin dort steht "CrateSubKey".

      Ansonsten gutes Tutorial und verständlich erklärt. :thumbup:
      Wer fragt, ist ein Narr für eine Minute. Wer nicht fragt, ist ein Narr sein Leben lang.
      auch wegen sowas sollteman kein Tutorial schreiben, bei dem nicht eine lauffähige Sample-Solution beiliegt.
      Zum einen kann der Leser sofort die Richtigkeit des Tuts überprüfen, zum andern können obige Flüchtigkeitsfehler nicht auftreten.

      Solch Fehlerle sind ärgerlich, grad für Anfänger - die müssen den gezeigten Code ja für bare Münze nehmen.

      Luki-Progger schrieb:

      Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon")


      Wenn ich auf dem o.g. Schlüssel zugreifen möchte, nutzt er in der Registry, bei einem 64-Bit System, den Key "Computer\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows NT\CurrentVersion\Winlogon" - Lässt sich das irgendwie umgehen? Denn die Auswirkungen die ich im Node mache, haben keine Auswirkungen, mache ich die Änderungen im "Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" funktionieren die Änderungen (Beispiel: "AutoAdminLogon").

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Toorms“ ()