Names of subdirectories in the registry

B

Bo Hansson

I would like to get the names of the subdirectories under a certain
directory in the registry.
Is that possible, and if - how do I do that?

/BosseH
 
S

Steve Yandl

If you're running on WinXP or Win2k machines, you can use WMI. Otherwise,
you would either have to set up some API procedures or use regedit to export
a reg file and then do some tricky string management to extract the subkeys.

Assuming you're running on a WinXP PC, here is an example that would type a
list of all the subkeys of
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services into your document.
(Note, the terms are keys and subkeys, not directory and subdirectory when
working in the registry).

_ _ _ _ _ _ _ _ _ _ _ _

Const HKEY_LOCAL_MACHINE = &H80000002

strComputer = "."

Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _
strComputer & "\root\default:StdRegProv")

strKeyPath = "SYSTEM\CurrentControlSet\Services"
oReg.EnumKey HKEY_LOCAL_MACHINE, strKeyPath, arrSubKeys

Selection.TypeParagraph

For Each subkey In arrSubKeys
Selection.TypeText subkey
Selection.TypeParagraph
Next

_ _ _ _ _ _ _ _ _ _ _ _


Steve Yandl
 
B

Bo Hansson

Thanks Steve,

Your sample works great, but I would like to find subkeys in
HKEY_CURRENT_USER and will then need another Constant I assume. Where do I
find that one?

Further on, I very much like to find the subkeys also in Win2K machines
which leads to more questions:.

1 - What's WMI?

2 - Do you have any any samples of API-procedures for this purpose?

3 - Is it possible to export a reg file by means of VBA-code?


/BosseH
 
J

Jezebel

You don't need to muck around with API calls for this. Run Regedit. Right
click the root directory under which you want the sub-entries and click
Export. This creates a text file ([name].reg) containing a listing of
everything under that root, which you can then filter using Notepad, Word,
Excel or any text editor of your choice.
 
B

Bo Hansson

Well, the problem is that I want to do it by means of VBA.code. Any
suggestions?

/BosseH

Jezebel said:
You don't need to muck around with API calls for this. Run Regedit. Right
click the root directory under which you want the sub-entries and click
Export. This creates a text file ([name].reg) containing a listing of
everything under that root, which you can then filter using Notepad, Word,
Excel or any text editor of your choice.



Bo Hansson said:
I would like to get the names of the subdirectories under a certain
directory in the registry.
Is that possible, and if - how do I do that?

/BosseH
 
J

Jezebel

Option Explicit

Private Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long
End Type

Private Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias
"RegOpenKeyExA" (ByVal hKey As Long, ByVal lpSubKey As String, ByVal
ulOptions As Long, ByVal samDesired As Long, phkResult As Long) As Long
Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long)
As Long
Private Declare Function RegEnumKeyEx Lib "advapi32.dll" Alias
"RegEnumKeyExA" (ByVal hKey As Long, ByVal dwIndex As Long, ByVal lpName As
String, lpcbName As Long, lpReserved As Long, ByVal lpClass As String,
lpcbClass As Long, lpftLastWriteTime As FILETIME) As Long

Const HKCR = &H80000000
Const HKCU = &H80000001
Const HKLM = &H80000002
Const HKKU = &H80000003
Const HKPD = &H80000004
Const HKCC = &H80000005
Const HKDD = &H80000006
Const KEY_ENUMERATE_SUB_KEYS = &H8



Private Sub XXX()

Dim keyname As String ' Receives keyname for each subkey
Dim keylen As Long ' Length of keyname
Dim classname As String ' Receives class name for each subkey
Dim classlen As Long ' Length of classname
Dim lastwrite As FILETIME ' Receives last-write-to time
Dim handle As Long ' handle to the opened key
Dim index As Long ' Index counter
Dim rval As Long ' Return value
Dim oupval As String

oupval = "Sub-Keys are " & Chr(13)

rval = RegOpenKeyEx(HKCU, "", 0, KEY_ENUMERATE_SUB_KEYS, handle)
If rval <> 0 Then
MsgBox "Registry key could not be opened."
Exit Sub
End If

Do While rval = 0 ' Continue if success
keylen = 255
keyname = Space(keylen)
classlen = 255
classname = Space(classlen)
rval = RegEnumKeyEx(handle, index, keyname, keylen, ByVal 0, classname,
classlen, lastwrite)
If rval = 0 Then
keyname = Left$(keyname, keylen)
Debug.Print "HKCU\" & keyname
End If
Loop ' End the loop
rval = RegCloseKey(handle)

End Sub



Bo Hansson said:
Well, the problem is that I want to do it by means of VBA.code. Any
suggestions?

/BosseH

Jezebel said:
You don't need to muck around with API calls for this. Run Regedit. Right
click the root directory under which you want the sub-entries and click
Export. This creates a text file ([name].reg) containing a listing of
everything under that root, which you can then filter using Notepad,
Word, Excel or any text editor of your choice.



Bo Hansson said:
I would like to get the names of the subdirectories under a certain
directory in the registry.
Is that possible, and if - how do I do that?

/BosseH
 
B

Bo Hansson

Bunches of thanks!

But I need a little bit more of help.

What I actually want to do is to get the subkeys under a specific HKCU-key.
I've therefore tried to modify the following line:
rval = RegOpenKeyEx(HKCU, "", 0, KEY_ENUMERATE_SUB_KEYS, handle)
into:
rval = RegOpenKeyEx(HKCU, strKeyPath, 0, KEY_ENUMERATE_SUB_KEYS, handle)

And it looks like it partially works. The problem is that the procedure
continues to repeatdedly "read" the first subkey, it never moves on to the
next.

/BosseH



Jezebel said:
Option Explicit

Private Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long
End Type

Private Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias
"RegOpenKeyExA" (ByVal hKey As Long, ByVal lpSubKey As String, ByVal
ulOptions As Long, ByVal samDesired As Long, phkResult As Long) As Long
Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As
Long) As Long
Private Declare Function RegEnumKeyEx Lib "advapi32.dll" Alias
"RegEnumKeyExA" (ByVal hKey As Long, ByVal dwIndex As Long, ByVal lpName
As String, lpcbName As Long, lpReserved As Long, ByVal lpClass As String,
lpcbClass As Long, lpftLastWriteTime As FILETIME) As Long

Const HKCR = &H80000000
Const HKCU = &H80000001
Const HKLM = &H80000002
Const HKKU = &H80000003
Const HKPD = &H80000004
Const HKCC = &H80000005
Const HKDD = &H80000006
Const KEY_ENUMERATE_SUB_KEYS = &H8



Private Sub XXX()

Dim keyname As String ' Receives keyname for each subkey
Dim keylen As Long ' Length of keyname
Dim classname As String ' Receives class name for each subkey
Dim classlen As Long ' Length of classname
Dim lastwrite As FILETIME ' Receives last-write-to time
Dim handle As Long ' handle to the opened key
Dim index As Long ' Index counter
Dim rval As Long ' Return value
Dim oupval As String

oupval = "Sub-Keys are " & Chr(13)

rval = RegOpenKeyEx(HKCU, "", 0, KEY_ENUMERATE_SUB_KEYS, handle)
If rval <> 0 Then
MsgBox "Registry key could not be opened."
Exit Sub
End If

Do While rval = 0 ' Continue if success
keylen = 255
keyname = Space(keylen)
classlen = 255
classname = Space(classlen)
rval = RegEnumKeyEx(handle, index, keyname, keylen, ByVal 0, classname,
classlen, lastwrite)
If rval = 0 Then
keyname = Left$(keyname, keylen)
Debug.Print "HKCU\" & keyname
End If
Loop ' End the loop
rval = RegCloseKey(handle)

End Sub



Bo Hansson said:
Well, the problem is that I want to do it by means of VBA.code. Any
suggestions?

/BosseH

Jezebel said:
You don't need to muck around with API calls for this. Run Regedit.
Right click the root directory under which you want the sub-entries and
click Export. This creates a text file ([name].reg) containing a listing
of everything under that root, which you can then filter using Notepad,
Word, Excel or any text editor of your choice.



I would like to get the names of the subdirectories under a certain
directory in the registry.
Is that possible, and if - how do I do that?

/BosseH
 
S

Steve Yandl

Const HKEY_CURRENT_USER = &H80000001

1. WMI is Windows Management Instumentation. It's Microsoft's
implementation of Web Based Enterprise Management (WBEM). It basically
gives you access to aspects of the PC that can be managed. In the script,
where I've got strComputer = ".", you're asking to look at the local PC but
using WMI you can just as easily check on or alter other computers in your
network. You can read and write to the registry, read and write to the file
system, check on hardware, processes, services, etc. and monitor events
(when a service starts or stops for example).

2. Jezebel has provided a good example of using the API

3. You can run regedit from VBA but I've always found it tough to isolate
the subkeys from the resulting text file unless you have a pretty good idea
what was there before you start. It can be done but I don't think it is the
most simple approach. You would use VBA's Shell function to run regedit.
Regedit would need to be run with the "/e" switch to export a reg file.
Something like:
Shell regedit.exe /e Temp.reg HKEY_CURRENT_USER\SOFTWARE
Then you would work with the text file, Temp.reg.

Steve Yandl
 
B

Bo Hansson

Thanks Steve

I've chosen to use API according to Jezebels idea. It works great.

/BosseH
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top