Search inside Registries with VB.NET
Know everything on registries is not possible in a single day but this page might give you a good start. Here is a Visual Studio VB.NET sample project with all the code. It search and scan your computer or a remote computer. It also contains the answers you need.
Someone once ask me if I was capable to do some whatever operations inside the Windows registries. I said yes, I do but I haven�t told him all the things I have to do to make a good and reliable program. It is always easier to make something work, but making something life time good is harder.
What are registries?
The simplest way to answer that question is a place where most program inside Windows save data make then work. The data is structured and are accessible with REGEDIT. The main registry keys are these ones:
HKEY_CLASSES_ROOT
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS
HKEY_CURRENT_CONFIG
The two main difficulties are the read/write and the 32/64 architecture inside the registries. You should know that programs need to deal with HKEY_LOCAL_MACHINE \SOFTWARE and HKEY_CURRENT_USER \SOFTWARE to save their data. What is hard is that some programs are in 32 while other is in 64. It becomes harder when the OS could be either in 32 or in 64. If a programmer is not careful enough, what will happen is that his program may not work in every computer or for anyone. Common mistakes occurs when test are not done on every platforms such as Windows XP/7/8, 32/64 bits�
I will try to split the entire subject inside this post and for all those who wish to have a project sample, you just need to go at the end of this post to get it. I am sorry if I can�t spend too much time writing something extraordinary.
32 bits or 64 bits
At the moment, there are two types of processors: 32 bits and 64 bits. The multi-core thing is not important for now. All it matter is the 2 type of instructions set. Here is a little list processor names in 32 and in 64 bits:
32 bits Processors:
Intel� Atom� Processor
Intel Core 2 (1st generation)
Intel Pentium 4
Virtual Computer
64 bits Processors:
INTEL CORE i7-3630QM
AMD FX-8150
AMD E2-1800
INTEL CORE i5-3210M
What was said is that 64 bits processors where available before 64 bit OS. AMD start selling his AMD ATHLON 64 in 1999. AMD release his ATHLON 64 X2 (DUAL-CORE 64 bits) in 2005. That was times where software technologies haven�t follow the hardware. Intel have release multi-core processor and still, Microsoft and Windows where not ready for any multi-processor technologies. You could have to strongest computer with a dual processor, but your program will never exceed 50%.
People have to wait for Windows 7 in 2008 with Microsoft Release Candidate to experience the 64 bit. On older versions, Windows OS at 64 bit were hard to find and many program were not working well. I am talking about Windows XP 64, Windows Vista x64 and Windows Server 2008 x64.
Because the software industry toke a lot of time to adjust them selves, Microsoft decided to build an OS that could handle 32 and 64 programs. After that, people still wonder why Windows is always coming bigger and more power consuming.
Software vs Wow6432Node
Working with registries is not a simple task. It gets worst when you have to deal with 32 and 64 software on the same computer.
You have to know that every Windows in x64 will have 2 types of registries: 32 and 64. If you want to make a program, you have to choice to make it in 32 or in 64. If you are using Microsoft Visual Studio NET or any other Visual Studio edition, my best advice is to set your project to �Any CPU�. That way, your program will run with the best speed and setting.
If you make your program in x86 (32 bits), you might make your life easier, but your program will not run has fast if the computer is an x64.
If you install or make a program in 32 bits for a Windows x64, then you will notice that all the registries will the save inside a sub Registry Key called Wow6432Node. Windows automatically detects that your program doesn�t meet the requirement and Windows will try to install it in 32 modes. That way, old program could still work in new computers.
Unless you are doing something very specific, you should not outsmart Windows by readying and writing directly inside Wow6432Node. Let Windows x64 manage your x86 programs by diverting all queries that special folder.
Because is not easy for my to explain this part, I�ll give you some examples here :
If you OS is in 32 bits, then HKEY_LOCAL_MACHINE \SOFTWARE will contains all your 32 bits programs.
If you OS is in 64 bits, then HKEY_LOCAL_MACHINE \SOFTWARE will contains all your 64 bits programs and HKEY_LOCAL_MACHINE \SOFTWARE\Wow6432Node will contains all your 32 bits programs.
In other words, if you install an old program made for Windows XP on a Windows 7 x64; chances that those registries will be in HKEY_LOCAL_MACHINE \SOFTWARE\Wow6432Node automatically.
If you make a program that uses registries, try to avoid at all cost the use of Wow6432Node. Checking if your Windows OS is in 64 or in 32 by verifying the existence of Wow6432Node is not a good idea. Forcing to save data inside Wow6432Node is not a good idea either. Always try to choose to work in 32 bits or in 64 at the beginning.
Microsoft made a �good� choice making two time of registry for every software developers.
I made an example of program. It works the same way than the famous REGEDIT from Windows. I use a TreeView to sort the table. You will also see that I had made two RadioButton. The first one is for the 32 bits and the other is for the 64 bits. If you look at the source code, you won�t see the use of Wow6432Node. The registry object will automatically make sure to work with the right registry key if you tell him 32 or 64.
The first part of my program is here :
If rb32BitsView.Checked Then oBaseKey = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, tbComputerName.Text, RegistryView.Registry32) Else oBaseKey = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, tbComputerName.Text, RegistryView.Registry64) End If |
If you check carefuly, the code is exactly the same syntax for the 32 or the 64. This should make your work easier. A good programmer should always consider the 32 and the 64 bit aspect to make a complete program. I you are careless, your program will not be popular.
GetSubKey et GetValues
The registries works the same way that directories and files in Windows. The only main difference is that files could contain large amount of data.
To be able to read and write, you need to use GetSubKey and GetValues.
Dim sGetSubKeyNames() As String ' 1st level of Key Dim oRegistryKey As RegistryKey Try '[ . . .] sGetSubKeyNames = oRegistryKey.GetSubKeyNames() '[ . . .] |
In Dot NET, GetSubKeyNames return an array of String with all the key names under a Key. If there is no result, then the array size will be zero. You get an error message if you try to access a Key that doesn�t exist or if you don�t have the rights. And you will have a error message if you try to access HKEY_LOCAL_MACHINE\SECURITY with GetSubKey
Reading a registry and writing is almost the same thing. That is why I haven�t done the writing part.
Registry Explorer
REGEDIT from Microsoft is a good tool to explore inside the registries. You could also access to a remote computer, export registries, read and change the permissions�
Private Sub LoadRegistry(ByRef oTreeNode As TreeNode, ByRef oRegistryKey As RegistryKey) Dim index1 As Integer Dim index2 As Integer Dim index3 As Integer Dim sGetSubKeyNames() As String ' 1st level of Key Dim sGetSubKeyNames2() As String ' ' 2nd level of Key Dim oRegistryKey2 As RegistryKey Dim tempNode As TreeNode Dim tempNode2 As TreeNode Dim found As Boolean Dim found2 As Boolean Try 'this is important because you might not be able to access registry 'Exemple : HKEY_LOCAL_MACHINE\SECURITY sGetSubKeyNames = oRegistryKey.GetSubKeyNames() For index1 = 0 To sGetSubKeyNames.Length - 1 Step 1 'unfortunally i don't have a AddRange from String Array to TreeNode Array :-( tooooo bad Try tempNode = New TreeNode(sGetSubKeyNames(index1)) found = False For Each fNode As TreeNode In oTreeNode.Nodes If fNode.Text = sGetSubKeyNames(index1) Then found = True Exit For End If Next If found = False Then oTreeNode.Nodes.Add(tempNode) End If Catch ex As Exception End Try Next 'seulement pr�chercher les directory imm�diats suivantes 'This will only look the next level of Keys , creating plus signs next to the Nodes. For index1 = 0 To sGetSubKeyNames.Length - 1 Step 1 Try oRegistryKey2 = oRegistryKey.OpenSubKey(sGetSubKeyNames(index1)) sGetSubKeyNames2 = oRegistryKey2.GetSubKeyNames() For index2 = 0 To sGetSubKeyNames2.Length - 1 Step 1 'unfortunally i don't have a AddRange from String Array to TreeNode Array :-( tooooo bad tempNode2 = New TreeNode(sGetSubKeyNames2(index2)) found2 = False For Each fNode As TreeNode In oTreeNode.Nodes(index1).Nodes If fNode.Text = sGetSubKeyNames2(index2) Then found2 = True Exit For End If Next If found2 = False Then oTreeNode.Nodes(index1).Nodes.Add(tempNode2) End If 'If Not oTreeNode.Nodes(index1).Nodes.Contains(tempNode2) Then 'the basic Contains methods inside the node is not reliable ' oTreeNode.Nodes(index1).Nodes.Add(tempNode2) 'End If Next Catch ex As Exception End Try Next Catch ex As Exception 'MsgBox(ex.Message) End Try End Sub |
Of course, we could improve the code. For example, we could make this code faster if we don�t ask the program to loop over all the subKey and create node under the sub Node if the main purpose is to create a plus sign. But because this is an example, I prefer to keep it this way.
]
Type de KeyValues
Il existe plusieurs types de valeur dans les clefs de registres. Si vous utilise en DOT NET la m�thode TOSTRING pour convertir une valeur en un format lisible, vous pourriez obtenir un message d�erreur si le format n�est pas une chaine de caract�re ou un nombre normal. C�est dans le cas d�une valeur en binaire. �a ne vous donnera pas une belle s�rie de z�ros ou de uns. Donc, vous devez v�rifier le type de valeur avant de la traiter.
Notez qu�en g�n�ral, la notion de nombre en d�cimal ou en hexad�cimal n�a pas trop d�importance puisqu�un nombre reste un nombre.
Voici une partie de code disponible dans l�exemple t�l�chargeable o� je traite la valeur selon le type. J�admets que c�est assez idiot comme exemple, mais dans la vie pourquoi faire compliqu� lorsqu�on peut faire simple ? Vous connaissez le KISS ? Keep It Simple and Stupid !
If oRegistryKey.GetValueKind(sGetValueNames(index1)) = RegistryValueKind.DWord Then str(cValue.Index) = oRegistryKey.GetValue(sGetValueNames(index1)).ToString ElseIf oRegistryKey.GetValueKind(sGetValueNames(index1)) = RegistryValueKind.ExpandString Then str(cValue.Index) = oRegistryKey.GetValue(sGetValueNames(index1)).ToString ElseIf oRegistryKey.GetValueKind(sGetValueNames(index1)) = RegistryValueKind.MultiString Then str(cValue.Index) = oRegistryKey.GetValue(sGetValueNames(index1)).ToString ElseIf oRegistryKey.GetValueKind(sGetValueNames(index1)) = RegistryValueKind.QWord Then str(cValue.Index) = oRegistryKey.GetValue(sGetValueNames(index1)).ToString ElseIf oRegistryKey.GetValueKind(sGetValueNames(index1)) = RegistryValueKind.String Then str(cValue.Index) = oRegistryKey.GetValue(sGetValueNames(index1)).ToString ElseIf oRegistryKey.GetValueKind(sGetValueNames(index1)) = RegistryValueKind.Binary Then ElseIf oRegistryKey.GetValueKind(sGetValueNames(index1)) = RegistryValueKind.Unknown Then ElseIf oRegistryKey.GetValueKind(sGetValueNames(index1)) = RegistryValueKind.None Then End If |
Searching the KeyValue
If you need to look for a value inside the registries but you havent made an index of your registries, you won�t have the choice of searching into every RegistryKey. If you do not want to make a huge program with a lot of lines, here is one solution, making a thread running in background using a recursive function. It is a little bit hard at the beginning because the arguments are not easy to set. Now that I made this example, I will save time if I wish to make another recursive thread.
Recursive function and et basic THREAD
Here is a function called SEARCH2. It includes the structure myArguments in parameter for the function. This function is fairly short and effective. If the function found a match then it put the results inside a DATAGRIDVIEW. The animation is done with an invoke function.
Structure myArguments Public rPath As String Public sStringSearch As String Public BaseRegistryKey As RegistryKey Public View As Microsoft.Win32.RegistryView Public MatchCase As Boolean Public MatchWholeWord As Boolean End Structure Private Sub Search2(ByVal oArgs As myArguments) Dim oRegistryKey As RegistryKey Dim sGetValueNames() As String Dim sGetSubKeyNames() As String ' 1st level of Key Dim index1 As Integer Dim index2 As Integer Dim str(DataGridView1.ColumnCount - 1) As String Dim add_result As Boolean Try oRegistryKey = oArgs.BaseRegistryKey '.OpenSubKey(oArgs.rPath) If oRegistryKey IsNot Nothing Then Try UpdateGroupBox2(oRegistryKey.Name) sGetValueNames = oRegistryKey.GetValueNames() For index1 = 0 To sGetValueNames.Length - 1 Step 1 ''test add or not add_result = False If oArgs.MatchWholeWord = True Then If sGetValueNames(index1) IsNot Nothing And oArgs.sStringSearch IsNot Nothing Then If sGetValueNames(index1).Length = oArgs.sStringSearch.Length Then If oArgs.MatchCase = True Then If InStr(sGetValueNames(index1), oArgs.sStringSearch, CompareMethod.Binary) > 0 Then ' add_result = True End If Else If InStr(UCase(sGetValueNames(index1)), UCase(oArgs.sStringSearch), CompareMethod.Binary) > 0 Then add_result = True End If End If End If End If Else If oArgs.MatchCase = True Then If InStr(sGetValueNames(index1), oArgs.sStringSearch, CompareMethod.Binary) > 0 Then add_result = True End If Else If InStr(UCase(sGetValueNames(index1)), UCase(oArgs.sStringSearch), CompareMethod.Binary) > 0 Then add_result = True End If End If End If If add_result = True Then 'MSgBox(sGetValueNames(index1)) If oRegistryKey.GetValueKind(sGetValueNames(index1)) = RegistryValueKind.DWord Then str(cValue.Index) = oRegistryKey.GetValue(sGetValueNames(index1)).ToString ElseIf oRegistryKey.GetValueKind(sGetValueNames(index1)) = RegistryValueKind.ExpandString Then str(cValue.Index) = oRegistryKey.GetValue(sGetValueNames(index1)).ToString ElseIf oRegistryKey.GetValueKind(sGetValueNames(index1)) = RegistryValueKind.MultiString Then str(cValue.Index) = oRegistryKey.GetValue(sGetValueNames(index1)).ToString ElseIf oRegistryKey.GetValueKind(sGetValueNames(index1)) = RegistryValueKind.QWord Then str(cValue.Index) = oRegistryKey.GetValue(sGetValueNames(index1)).ToString ElseIf oRegistryKey.GetValueKind(sGetValueNames(index1)) = RegistryValueKind.String Then str(cValue.Index) = oRegistryKey.GetValue(sGetValueNames(index1)).ToString ElseIf oRegistryKey.GetValueKind(sGetValueNames(index1)) = RegistryValueKind.Binary Then ElseIf oRegistryKey.GetValueKind(sGetValueNames(index1)) = RegistryValueKind.Unknown Then ElseIf oRegistryKey.GetValueKind(sGetValueNames(index1)) = RegistryValueKind.None Then End If str(cComputer.Index) = _ComputerName str(cKeyName.Index) = sGetValueNames(index1) str(cRegistryPath.Index) = oRegistryKey.Name Me.Invoke(New MethodInvoker(Sub() DataGridView1.Rows.Add(str))) Else End If Next Catch ex As Exception 'MsgBox(ex.StackTrace) End Try Try sGetSubKeyNames = oRegistryKey.GetSubKeyNames() For index2 = 0 To sGetSubKeyNames.Length - 1 Step 1 'La fonction r�cursive Try oArgs.rPath = oArgs.rPath & "\" & sGetSubKeyNames(index2) oArgs.BaseRegistryKey = oRegistryKey.OpenSubKey(sGetSubKeyNames(index2)) Search2(oArgs) Catch ex As Exception End Try Next Catch ex As Exception 'MsgBox(ex.StackTrace) End Try End If Catch ex As Exception 'MsgBox(ex.StackTrace) End Try End Sub |
Create a RegistryKey
I haven�t made a function to create a RegistryKey in this article. Basically, writing is almost the same thing than reading. Use the method SETVALUE and CREATESUBKEY to achieve your goals.
Conclusion, download and Visual Studio
I use Microsoft Visual Studio 2010 to do all my projects. I suggest you to buy and get the best IDE in the world and the newest one: Microsoft Visual Studio 2012 on Amazon .
or
Here are a few interesting post to read :
Update Contact :
No Wa/Telepon (puat) : 085267792168
No Wa/Telepon (fajar) : 085369237896
Email : Fajarudinsidik@gmail.com
No Wa/Telepon (puat) : 085267792168
No Wa/Telepon (fajar) : 085369237896
Email: Fajarudinsidik@gmail.com
atau Kirimkan Private messanger melalui email dengan klik tombol order dibawah ini :





