I'm looking for a very simple way to browse the registry. I don't want to make changes/edit anything, I just want to fill a listview with the information from the systems registry so someone can highlight a key and get the full name of the key. I've search all over the internet and our of the 15 some examples (most that edited) I could not find a VB one that did close to what I want. Can anyone give me an example or point me in the right direcrion? I would think I would enumerate each key, then look below the key for subkeys and values, and keep going until I find nothing, back up and do the next key. Just a big sequence of loops. I just don't know where to start.
-Allan.
DSJ
September 9th, 2005, 10:04 AM
The Microsoft.Win32 namespace has Registry and RegistryKey classes for this.
CrystalAnnoysMe
September 9th, 2005, 10:10 AM
The Microsoft.Win32 namespace has Registry and RegistryKey classes for this.
I know. I already read and write to the registry. I'm just not sure on how to go about pulling each of the main keys (HKLM, HKCU, etc) into a list view. The idea is to have five radio buttons and the user can click a radio button and the listview will populate with that section of the registry.
jmcilhinney
September 9th, 2005, 09:43 PM
If you know about the RegistryKey class then how about taking a look at its members. I'd say the GetSubKeyNames and GetValueNames methods would be useful, but I'm sure you've read about them already, right?
CrystalAnnoysMe
September 21st, 2005, 01:39 PM
*sigh* O.k...let me try this because either no one understands me or no one feels like being helpful. I understand the registry class. I don't understand how to go through each key and populate a treeview. Can someone give me a brief psudocode example? i.e. this is in the reg:
HKLM
|-- Hardward
|-- SAM
|-- Security
|-- Adobe
|-- Classes
|-- Microsoft
How would I go through each level and populate the listview.
-Allan.
DSJ
September 21st, 2005, 02:10 PM
Dim SubKeys() as string = registry.getsubkeynames
Dim Keyname as string
For each Keyname in Subkeys
'Code here to add to listview....
Dim Values() as string = CurrentKey.GetValueNames
Dim Value as string
For Each value in Values
'Code here
Next
Next
CrystalAnnoysMe
September 21st, 2005, 03:00 PM
Dim SubKeys() as string = registry.getsubkeynames
Dim Keyname as string
For each Keyname in Subkeys
'Code here to add to listview....
Dim Values() as string = CurrentKey.GetValueNames
Dim Value as string
For Each value in Values
'Code here
Next
Next
Thats what I was looking for. I managed to populat the list view with the subkeys of HKLM, and then populate those with thier subkeys. Its going to be a huge pain to keep going down levels though....hopefully I can figure out an efficient way to call a function that will return the subkey list and a function to return values, then go through the subkey list and call each function, and repeat, repeat, repeat until no subkeys/values are returned.
-Allan.
jmcilhinney
September 21st, 2005, 06:57 PM
Now that you've actually specified what you want, you should use a recursive method to populate a TreeView with all the keys. Then when the user selects a key you would call GetValueNames to get the names of all the values and then GetValue to get each value to populate a ListView. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.GetSubKeys(Registry.CurrentUser, Me.TreeView1.Nodes)
'Repeat for other hives.
End Sub
Private Sub GetSubKeys(ByVal key As RegistryKey, ByVal nodes As TreeNodeCollection)
Dim root As TreeNode = nodes.Add(IO.Path.GetFileName(key.Name))
For Each subkeyName As String In key.GetSubKeyNames
Try
Me.GetSubKeys(key.OpenSubKey(subkeyName, True), root.Nodes)
Catch ex As Exception
'The key could not be opened. Ignore and continue.
End Try
Next
End Sub
CrystalAnnoysMe
September 22nd, 2005, 01:44 PM
I've gotten the values down. I have a listview and when you click on a key it populates using the selectedindex.fullpath property of the key. I'll probably switch to using the tag property so I can store in the root key into the tag text.....right now I'm only playing with HKLM. I'm glad you posted the recursive example....I didn't think you could call a function from itself and I started with a rediculous for each inside a for each inside a for each....it was getting confusing. I was able to pull the first three levels though so I was doing something right.
Once I finish I'll post my code in case someeone else needs it.
jmcilhinney
September 22nd, 2005, 06:17 PM
I tried using my code to populate a TreeView with every key in the registry and it took over a minute to do so. I'm not sure how much of that was caused by exceptions being thrown when trying to open keys that were inaccessible due to permissions. I think you may find that using the same recursive principle but calling API functions to access the registry keys might be quicker, but I don't know for sure. You might also consider populating the TreeView on demand. You could just populate the first two levels and then when the user expands a key you could then add another level so that every visible key has its immediate subkeys available at all times, but you also retrieve as little data as possible.
CrystalAnnoysMe
September 23rd, 2005, 07:52 AM
I tried using my code to populate a TreeView with every key in the registry and it took over a minute to do so. I'm not sure how much of that was caused by exceptions being thrown when trying to open keys that were inaccessible due to permissions. I think you may find that using the same recursive principle but calling API functions to access the registry keys might be quicker, but I don't know for sure. You might also consider populating the TreeView on demand. You could just populate the first two levels and then when the user expands a key you could then add another level so that every visible key has its immediate subkeys available at all times, but you also retrieve as little data as possible.
The only reason I wanted to do this was because I have a program I wrote that is made to edit KiXtart login scripts. I added in a "wizard" to do some of the script commands for reading/writing/etc the registry and I wanted a nice and easy way for the user to select a key instead of manually typing it in. What I may do is populate the top levels (HKLM, HKCU, etc) and when they click on a top level key it will populate below it. Or I'll have them select the main key and have a browse button so it will kow which key to populate and then the header above the TreeView would have the root key name.
CrystalAnnoysMe
September 23rd, 2005, 10:30 AM
Its slow but functional. Still need to figure out how to get the proper Data Type out but for now what I'm using will suffice:
Option Explicit On
Option Strict On
Imports Microsoft.Win32
Public Class frmMain
Inherits System.Windows.Forms.Form
#Region " Windows Form Designer generated code "
Public Sub New()
MyBase.New()
isLoading = True
'This call is required by the Windows Form Designer.
InitializeComponent()
'Add any initialization after the InitializeComponent() call
End Sub
'Form overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub
'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer
'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
Friend WithEvents ImageList1 As System.Windows.Forms.ImageList
Friend WithEvents Panel1 As System.Windows.Forms.Panel
Friend WithEvents tvRegistryKeys As System.Windows.Forms.TreeView
Friend WithEvents Panel2 As System.Windows.Forms.Panel
Friend WithEvents lvValues As System.Windows.Forms.ListView
Friend WithEvents lblKeys As System.Windows.Forms.Label
Friend WithEvents lblValues As System.Windows.Forms.Label
Friend WithEvents rbHKEY_CLASSES_ROOT As System.Windows.Forms.RadioButton
Friend WithEvents rbHKEY_CURRENT_CONFIG As System.Windows.Forms.RadioButton
Friend WithEvents rbHKEY_USERS As System.Windows.Forms.RadioButton
Friend WithEvents rbHKEY_LOCAL_MACHINE As System.Windows.Forms.RadioButton
Friend WithEvents rbHKEY_CURRENT_USER As System.Windows.Forms.RadioButton
Friend WithEvents Label1 As System.Windows.Forms.Label
Friend WithEvents btnSelectKey As System.Windows.Forms.Button
Friend WithEvents btnSelectValue As System.Windows.Forms.Button
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
Me.components = New System.ComponentModel.Container
Dim resources As System.Resources.ResourceManager = New System.Resources.ResourceManager(GetType(frmMain))
Me.ImageList1 = New System.Windows.Forms.ImageList(Me.components)
Me.Panel1 = New System.Windows.Forms.Panel
Me.Label1 = New System.Windows.Forms.Label
Me.rbHKEY_CURRENT_USER = New System.Windows.Forms.RadioButton
Me.rbHKEY_LOCAL_MACHINE = New System.Windows.Forms.RadioButton
Me.rbHKEY_USERS = New System.Windows.Forms.RadioButton
Me.rbHKEY_CURRENT_CONFIG = New System.Windows.Forms.RadioButton
Me.rbHKEY_CLASSES_ROOT = New System.Windows.Forms.RadioButton
Me.lblKeys = New System.Windows.Forms.Label
Me.tvRegistryKeys = New System.Windows.Forms.TreeView
Me.Panel2 = New System.Windows.Forms.Panel
Me.lblValues = New System.Windows.Forms.Label
Me.lvValues = New System.Windows.Forms.ListView
Me.btnSelectKey = New System.Windows.Forms.Button
Me.btnSelectValue = New System.Windows.Forms.Button
Me.Panel1.SuspendLayout()
Me.Panel2.SuspendLayout()
Me.SuspendLayout()
'
'ImageList1
'
Me.ImageList1.ImageSize = New System.Drawing.Size(16, 16)
Me.ImageList1.ImageStream = CType(resources.GetObject("ImageList1.ImageStream"), System.Windows.Forms.ImageListStreamer)
Me.ImageList1.TransparentColor = System.Drawing.Color.Transparent
'
'Panel1
'
Me.Panel1.Controls.Add(Me.Label1)
Me.Panel1.Controls.Add(Me.rbHKEY_CURRENT_USER)
Me.Panel1.Controls.Add(Me.rbHKEY_LOCAL_MACHINE)
Me.Panel1.Controls.Add(Me.rbHKEY_USERS)
Me.Panel1.Controls.Add(Me.rbHKEY_CURRENT_CONFIG)
Me.Panel1.Controls.Add(Me.rbHKEY_CLASSES_ROOT)
Me.Panel1.Controls.Add(Me.lblKeys)
Me.Panel1.Controls.Add(Me.tvRegistryKeys)
Me.Panel1.Location = New System.Drawing.Point(8, 8)
Me.Panel1.Name = "Panel1"
Me.Panel1.Size = New System.Drawing.Size(280, 416)
Me.Panel1.TabIndex = 4
'
'Label1
'
Me.Label1.Location = New System.Drawing.Point(16, 8)
Me.Label1.Name = "Label1"
Me.Label1.Size = New System.Drawing.Size(32, 16)
Me.Label1.TabIndex = 10
Me.Label1.Text = "Root:"
'
'rbHKEY_CURRENT_USER
'
Me.rbHKEY_CURRENT_USER.Location = New System.Drawing.Point(80, 24)
Me.rbHKEY_CURRENT_USER.Name = "rbHKEY_CURRENT_USER"
Me.rbHKEY_CURRENT_USER.Size = New System.Drawing.Size(184, 16)
Me.rbHKEY_CURRENT_USER.TabIndex = 9
Me.rbHKEY_CURRENT_USER.Text = "HKEY_CURRENT_USER"
'
'rbHKEY_LOCAL_MACHINE
'
Me.rbHKEY_LOCAL_MACHINE.Location = New System.Drawing.Point(80, 40)
Me.rbHKEY_LOCAL_MACHINE.Name = "rbHKEY_LOCAL_MACHINE"
Me.rbHKEY_LOCAL_MACHINE.Size = New System.Drawing.Size(184, 16)
Me.rbHKEY_LOCAL_MACHINE.TabIndex = 8
Me.rbHKEY_LOCAL_MACHINE.Text = "HKEY_LOCAL_MACHINE"
'
'rbHKEY_USERS
'
Me.rbHKEY_USERS.Location = New System.Drawing.Point(80, 56)
Me.rbHKEY_USERS.Name = "rbHKEY_USERS"
Me.rbHKEY_USERS.Size = New System.Drawing.Size(184, 16)
Me.rbHKEY_USERS.TabIndex = 7
Me.rbHKEY_USERS.Text = "HKEY_USERS"
'
'rbHKEY_CURRENT_CONFIG
'
Me.rbHKEY_CURRENT_CONFIG.Checked = True
Me.rbHKEY_CURRENT_CONFIG.Location = New System.Drawing.Point(80, 72)
Me.rbHKEY_CURRENT_CONFIG.Name = "rbHKEY_CURRENT_CONFIG"
Me.rbHKEY_CURRENT_CONFIG.Size = New System.Drawing.Size(184, 16)
Me.rbHKEY_CURRENT_CONFIG.TabIndex = 6
Me.rbHKEY_CURRENT_CONFIG.TabStop = True
Me.rbHKEY_CURRENT_CONFIG.Text = "HKEY_CURRENT_CONFIG"
'
'rbHKEY_CLASSES_ROOT
'
Me.rbHKEY_CLASSES_ROOT.Location = New System.Drawing.Point(80, 8)
Me.rbHKEY_CLASSES_ROOT.Name = "rbHKEY_CLASSES_ROOT"
Me.rbHKEY_CLASSES_ROOT.Size = New System.Drawing.Size(184, 16)
Me.rbHKEY_CLASSES_ROOT.TabIndex = 5
Me.rbHKEY_CLASSES_ROOT.Text = "HKEY_CLASSES_ROOT"
'
'lblKeys
'
Me.lblKeys.Location = New System.Drawing.Point(8, 104)
Me.lblKeys.Name = "lblKeys"
Me.lblKeys.Size = New System.Drawing.Size(256, 16)
Me.lblKeys.TabIndex = 4
Me.lblKeys.Text = "Sub Keys"
'
'tvRegistryKeys
'
Me.tvRegistryKeys.ImageList = Me.ImageList1
Me.tvRegistryKeys.Location = New System.Drawing.Point(8, 120)
Me.tvRegistryKeys.Name = "tvRegistryKeys"
Me.tvRegistryKeys.Size = New System.Drawing.Size(264, 288)
Me.tvRegistryKeys.TabIndex = 3
'
'Panel2
'
Me.Panel2.Controls.Add(Me.lblValues)
Me.Panel2.Controls.Add(Me.lvValues)
Me.Panel2.Location = New System.Drawing.Point(296, 8)
Me.Panel2.Name = "Panel2"
Me.Panel2.Size = New System.Drawing.Size(424, 416)
Me.Panel2.TabIndex = 5
'
'lblValues
'
Me.lblValues.Location = New System.Drawing.Point(0, 8)
Me.lblValues.Name = "lblValues"
Me.lblValues.Size = New System.Drawing.Size(328, 16)
Me.lblValues.TabIndex = 5
Me.lblValues.Text = "Values"
'
'lvValues
'
Me.lvValues.FullRowSelect = True
Me.lvValues.Location = New System.Drawing.Point(0, 24)
Me.lvValues.MultiSelect = False
Me.lvValues.Name = "lvValues"
Me.lvValues.Size = New System.Drawing.Size(416, 384)
Me.lvValues.Sorting = System.Windows.Forms.SortOrder.Ascending
Me.lvValues.TabIndex = 4
Me.lvValues.View = System.Windows.Forms.View.Details
'
'btnSelectKey
'
Me.btnSelectKey.Enabled = False
Me.btnSelectKey.Location = New System.Drawing.Point(168, 432)
Me.btnSelectKey.Name = "btnSelectKey"
Me.btnSelectKey.Size = New System.Drawing.Size(112, 24)
Me.btnSelectKey.TabIndex = 6
Me.btnSelectKey.Text = "Select this key"
'
'btnSelectValue
'
Me.btnSelectValue.Enabled = False
Me.btnSelectValue.Location = New System.Drawing.Point(600, 432)
Me.btnSelectValue.Name = "btnSelectValue"
Me.btnSelectValue.Size = New System.Drawing.Size(112, 24)
Me.btnSelectValue.TabIndex = 7
Me.btnSelectValue.Text = "Select this value"
'
'frmMain
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(720, 464)
Me.Controls.Add(Me.btnSelectValue)
Me.Controls.Add(Me.btnSelectKey)
Me.Controls.Add(Me.Panel2)
Me.Controls.Add(Me.Panel1)
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog
Me.Icon = CType(resources.GetObject("$this.Icon"), System.Drawing.Icon)
Me.MaximizeBox = False
Me.MinimizeBox = False
Me.Name = "frmMain"
Me.Text = "Registry Key Browser"
Me.Panel1.ResumeLayout(False)
Me.Panel2.ResumeLayout(False)
Me.ResumeLayout(False)
End Sub
#End Region
Private isLoading As Boolean = False
#Region "Form events"
Private Sub frmMain_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
Call SetupColumnHeaders()
End Sub
Private Sub frmMain_Activated(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Activated
isLoading = False
End Sub
#End Region
Private Sub GetSubKeys(ByVal key As RegistryKey, ByVal nodes As TreeNodeCollection)
Dim root As TreeNode = nodes.Add(IO.Path.GetFileName(key.Name))
For Each subkeyName As String In key.GetSubKeyNames
Try
Me.GetSubKeys(key.OpenSubKey(subkeyName, True), root.Nodes)
Catch ex As Exception
'The key could not be opened. Ignore and continue.
End Try
Next
End Sub
Private Sub LoadSubkeys(ByVal myKey As RegistryKey)
' freeze updating treeview
tvRegistryKeys.BeginUpdate()
' remove any existing nodes
For Each node As TreeNode In tvRegistryKeys.Nodes
tvRegistryKeys.Nodes.RemoveAt(node.Index)
Next
' update the user interface
lblKeys.Text = "Keys (Populating...please wait...)"
Me.Refresh()
' populate our selected key
Me.GetSubKeys(myKey, Me.tvRegistryKeys.Nodes)
' update the interface
lblKeys.Text = "Keys"
' repaint treeview
tvRegistryKeys.EndUpdate()
End Sub
#Region "TreeView Events"
Private Sub tvRegistryKeys_AfterSelect(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles tvRegistryKeys.AfterSelect
If isLoading = True Then Exit Sub
Dim Values() As String
Dim strFP As String = tvRegistryKeys.SelectedNode.FullPath
Dim myKey As RegistryKey
Dim myNode As TreeNodeCollection = tvRegistryKeys.Nodes
' Setup our listview
lvValues.BeginUpdate()
lvValues.Clear()
Call SetupColumnHeaders()
' Get which root key were in
If InStr(strFP, "HKEY_CLASSES_ROOT", CompareMethod.Text) > 0 Then
myKey = Registry.ClassesRoot
ElseIf InStr(strFP, "HKEY_CURRENT_USER", CompareMethod.Text) > 0 Then
myKey = Registry.CurrentUser
ElseIf InStr(strFP, "HKEY_LOCAL_MACHINE", CompareMethod.Text) > 0 Then
myKey = Registry.LocalMachine
ElseIf InStr(strFP, "HKEY_USERS", CompareMethod.Text) > 0 Then
myKey = Registry.Users
Else
myKey = Registry.CurrentConfig
End If
' Check if the user picked a root key or a subkey
Try
Values = myKey.OpenSubKey(Mid(strFP, 1 + InStr(strFP, "\"))).GetValueNames()
Values.Sort(Values)
If Values.Length > 0 Then
Dim x As Integer = 0
For Each KeyValue As String In Values
If KeyValue = "" Then KeyValue = "(default)"
lvValues.Items.Add(KeyValue)
Dim myValue As String
Dim rk As RegistryKey = myKey.OpenSubKey(Mid(strFP, 1 + InStr(strFP, "\")), True)
lvValues.Items(x).SubItems.Add(rk.GetValue(KeyValue).GetType.ToString)
Try
myValue = CType(rk.GetValue(KeyValue), String)
rk.Close()
Catch
myValue = "Error getting value"
End Try
lvValues.Items(x).SubItems.Add(myValue)
x += 1
Next
Else
lvValues.Items.Add("No values found")
End If
Catch ex As Exception
Debug.WriteLine(ex.Message)
lvValues.Items.Add("Error accessing key")
End Try
btnSelectValue.Enabled = False
btnSelectKey.Enabled = True
' Begin repainting the TreeView.
lvValues.EndUpdate()
End Sub
#End Region
#Region "Radio Buttons"
Private Sub rbHKEY_CLASSES_ROOT_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles rbHKEY_CLASSES_ROOT.CheckedChanged
Me.LoadSubkeys(Registry.ClassesRoot)
End Sub
Private Sub rbHKEY_CURRENT_USER_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles rbHKEY_CURRENT_USER.CheckedChanged
Me.LoadSubkeys(Registry.CurrentUser)
End Sub
Private Sub rbHKEY_LOCAL_MACHINE_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles rbHKEY_LOCAL_MACHINE.CheckedChanged
Me.LoadSubkeys(Registry.LocalMachine)
End Sub
Private Sub rbHKEY_USERS_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles rbHKEY_USERS.CheckedChanged
Me.LoadSubkeys(Registry.Users)
End Sub
Private Sub rbHKEY_CURRENT_CONFIG_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles rbHKEY_CURRENT_CONFIG.CheckedChanged
Me.LoadSubkeys(Registry.CurrentConfig)
End Sub
#End Region
#Region "Command Buttons"
Private Sub btnSelectValue_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSelectValue.Click
If lvValues.SelectedItems(0).Text = "Error accessing key" Or lvValues.SelectedItems(0).Text = "No values found" Then Exit Sub
MsgBox("Selected value is:" & vbCrLf & tvRegistryKeys.SelectedNode.FullPath & "\" & lvValues.SelectedItems(0).Text, MsgBoxStyle.Information, "Value Selected")
End Sub
Private Sub btnSelectKey_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSelectKey.Click
If Len(tvRegistryKeys.SelectedNode.Text) = 0 Then Exit Sub
MsgBox("Selected key is:" & vbCrLf & tvRegistryKeys.SelectedNode.FullPath, MsgBoxStyle.Information, "Key Selected")
End Sub
#End Region
#Region "Listview routines"
Private Sub lvValues_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles lvValues.SelectedIndexChanged
btnSelectValue.Enabled = True
btnSelectKey.Enabled = False
If lvValues.SelectedIndices.Count = 0 Then
btnSelectValue.Enabled = False
Else
If lvValues.SelectedItems(0).Text = "Error accessing key" Or lvValues.SelectedItems(0).Text = "No values found" Then btnSelectValue.Enabled = False
End If
End Sub
Private Sub SetupColumnHeaders()
Dim intTotalWidth As Integer = lvValues.Width - 5
lvValues.Columns.Add("Name", CInt(intTotalWidth * 0.4), HorizontalAlignment.Left)
lvValues.Columns.Add("Data Type", CInt(intTotalWidth * 0.2), HorizontalAlignment.Left)
lvValues.Columns.Add("Data (as string)", CInt(intTotalWidth * 0.4), HorizontalAlignment.Left)
End Sub
#End Region
End Class
Thanks for your help guys.
-Allan.
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.