Searching the registry with vbs to find an unknown

2020-04-21 09:10发布

问题:

I use a path to locate pieces of information that contains a guid that can change. I had the guid value hard coded, but when it changes it doesn't function. I need to discover that guid dynamically. I know a value on the other side of the guid and have a REG Query that finds the entire path, but I can't figure out how to capture that path.

Here's the REG Query:

REG Query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products /D /V /F "Microsoft Office Professional Plus 2010" /S /E 

It returns the Value "DisplayName" and it's contents "Microsoft Office Professional Plus"

When run from a batch file it also displays the entire path that includes the elusive guid. I would like to do this from a vb script.

回答1:

Also the newer Windows Scripting Host Shell object also makes registry access easy.

Set wshshell = CreateObject("WScript.Shell")

wshshell.RegDelete(strName)

wshshell.RegRead(strName) 

wshshell.RegWrite(strName, anyValue [,strType])

See https://msdn.microsoft.com/en-us/library/293bt9hh(v=vs.84).aspx

Also WMI can access registry. Unlike both above methods it can ennumerate, so you can see what is there without having to know in advance.

Dim proglist()
Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
ret = oReg.EnumKey(&H80000002, "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", proglist)
If err.num =0 then
   For each prog in proglist
        msgbox prog
   Next
Else
    Msgbox err.num & " " & err.description & " " & err.source
    err.clear
End If

https://msdn.microsoft.com/en-us/library/aa390387(v=vs.85).aspx

It can also check security and monitor changes to keys.

This monitors changes to Windows Uninstall key.

Set objWMIService = GetObject("winmgmts:root/default") 
Set objEvents = objWMIService.ExecNotificationQuery("SELECT * FROM RegistryTreeChangeEvent WHERE Hive='HKEY_LOCAL_MACHINE' AND RootPath='SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall'")

Do
    Set objReceivedEvent = objEvents.NextEvent
    msgbox objReceivedEvent.GetObjectText_()
Loop

https://msdn.microsoft.com/en-us/library/aa393041(v=vs.85).aspx‎

Recursion is used to walk each node in a tree. The function calls itself every time it comes across a node. Start below program using cscript to avoid a few thousand msgboxs - cscript //nologo c:\folder\RecurseReg.vbs.

Set wshshell = CreateObject("WScript.Shell")

EnumReg "SOFTWARE\CLASSES"

Sub EnumReg(RegKey)
    On Error Resume Next
    wscript.echo "---------------------------------------"
    wscript.echo "HKLM\" & RegKey & " = " & wshshell.RegRead("HKLM\" & RegKey & "\")
    err.clear
    Dim KeyList()
    Dim ValueNameList()
    Dim ValueList()
    Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
    If err.number <> 0 then 
        wscript.echo err.number
        err.clear
    End If
    ret = oReg.EnumValues(&H80000002, RegKey, ValueNameList, ValueList)
    If err.number = 0 then
       For each valuename in ValueNameList
        If valuename <> "" then
            Value = wshshell.RegRead("HKLM\" & RegKey & "\" & valuename)
            err.clear
                wscript.echo valuename & " - " & Value
        End If
       Next
    Else
        Msgbox err.num & " " & err.description & " " & err.source
        err.clear
    End If


    ret = oReg.EnumKey(&H80000002, RegKey, Keylist)
    If err.number =0 then
       For each key in keylist
            EnumReg RegKey & "\" & key
       Next
    Else
        Msgbox err.num & " " & err.description & " " & err.source
        err.clear
    End If
End Sub

Putting both together (this does VC 2008 Runtime which should be on all computers)

Dim proglist()
Set wshshell = CreateObject("WScript.Shell")
On Error Resume Next
Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
ret = oReg.EnumKey(&H80000002, "SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products", proglist)
If err.num =0 then
   For each prog in proglist
'        msgbox prog
       If wshshell.RegRead("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products\" & Prog & "\InstallProperties\DisplayName") = "Microsoft Visual C++ 2008 Redistributable - x64 9.0.30729.17" then
           Msgbox "Found " & Prog 
       End If
   Next
Else
    Msgbox err.num & " " & err.description & " " & err.source
    err.clear
End If

For V6 or VBA

The registry is simple in VBA. It's is very limited and uses ini file concepts. There's a few of them such as (from Object Browser [F2] in VBA editor)

 Function GetAllSettings(AppName As String, Section As String)
Member of VBA.Interaction

 Sub SaveSetting(AppName As String, Section As String, Key As String, Setting As String)
Member of VBA.Interaction

 Sub DeleteSetting(AppName As String, [Section], [Key])
Member of VBA.Interaction

 Function GetSetting(AppName As String, Section As String, Key As String, [Default]) As String
Member of VBA.Interaction

Also the Windows API calls can be used.

RegOpenKeyEx

The RegOpenKeyEx function opens the specified registry key.

LONG RegOpenKeyEx(
  HKEY hKey,         // handle to open key
  LPCTSTR lpSubKey,  // subkey name
  DWORD ulOptions,   // reserved
  REGSAM samDesired, // security access mask
  PHKEY phkResult    // handle to open key
);


标签: vbscript