HOWTO: Query information related to ProgID & CLSID, verify where the image is loaded from Disk.

Ever copied a DLL from one system to another and registered it using RegSvr32.exe? or in other words ever created a DLL hell situation? Its easy and dirty at the same time to copy-paste DLL between systems and register them using regsvr32.exe

Often you copy-paste, register DLL from temporary folders or may be desktop and then later delete the DLL or move to other folder without unregistering/re-registering it. Stop right there!!! You are creating a problem for yourself.

Every time you register a DLL, if its self-registering DLL, will create entries in System’s Registry with its current location, ProgID, CLSID along with other information. This information is used by programs when they are doing late binding to find the DLL and load in memory.

If you move/delete a DLL without unregistering/re-registering the DLL you are leaving with an entry behind in the Registry which is pointing to “Invalid Path”. In this case any program which is using that DLL will fail and you may not realize what’s happening.

As a first step in a “Could not load <Image>/Error loading <Image>” error scenario I would always go to registry and verify that the DLL is registered properly. It could be tedious task and risky as well. You may just edit a registry entry by mistake and break other functionality as well.

I have come up with a VBScript which gives you the ease to quickly verify the Image path & current version on the basic of ProgID or CLSID. This script will prompt you to enter either ProgID or CLSID and give you the desired information.

Here we are looking for PROGID of CDOSYS.DLL

image 

…and here are the results.

image

Similarly you could use CLSID to do reverse lookup for ProgID & Image Path

image

image

Here is the code that I used in this script…

 On Error Resume Next

Dim strProgId
Dim strDescription
Dim strCLSID
Dim strInProcServer
Dim strCurVer
Dim strCurVerCLSID
Dim strCurVerInProcServer
Dim strVersionIndependentProgID

Dim oShell
Set oShell = CreateObject("WScript.Shell")

Dim strOutput

strProgId = UCase(Trim(InputBox("Enter the ProgID/CLSID:","ProgID Tool")))

If Len(strProgId)<=0 Then 
    Msgbox "Invalid ProgID/CLSID"
Else
    
    If Left(strProgId,1) = "{" Then strProgId = oShell.RegRead("HKEY_CLASSES_ROOT\CLSID\" & strProgId & "\ProgID\")
    
    strDescription = oShell.RegRead("HKEY_CLASSES_ROOT\" & strProgId & "\")
    strCLSID = oShell.RegRead("HKEY_CLASSES_ROOT\" & strProgId & "\CLSID\")
    strCurVer = oShell.RegRead("HKEY_CLASSES_ROOT\" & strProgId & "\CurVer\")

    strInProcServer = oShell.RegRead("HKEY_CLASSES_ROOT\CLSID\" & strCLSID & "\InprocServer32\")
    strVersionIndependentProgID = oShell.RegRead("HKEY_CLASSES_ROOT\CLSID\" & strCLSID & "\VersionIndependentProgID\")
    
    strOutput = strOutput & "ProgID: " & strProgId & vbCrLf
    strOutput = strOutput & "Description: " & strDescription & vbCrLf 
    strOutput = strOutput & "Current Version: " & strCurVer & vbCrLf
    strOutput = strOutput & "VersionIndependentProgID: " & strVersionIndependentProgID & vbCrLf & vbCrLf
    
    strOutput = strOutput & strProgId & " CLSID: " & strCLSID & vbCrLf
    strOutput = strOutput & strProgId & " InProcServer: " & strInProcServer & vbCrLf & vbCrLf
    
    
    If (Len(strCurVer)>0) Then
        strCurVerCLSID = oShell.RegRead("HKEY_CLASSES_ROOT\" & strCurVer & "\CLSID\")
        strCurVerInProcServer = oShell.RegRead("HKEY_CLASSES_ROOT\CLSID\" & strCurVerCLSID & "\InprocServer32\")
        
        strOutput = strOutput & strCurVer & " CLSID: " & strCurVerCLSID & vbCrLf
        strOutput = strOutput & strCurVer & " InProcServer: " & strCurVerInProcServer & vbCrLf
    
    End If
    
    Msgbox strOutput,,"ProgId Tool"
    
End If

Happy debugging….