How to Programmatically Verify DLL Registration Status in Windows (Including XP Permission Checks)


2 views

When working with legacy systems like Windows XP, you might encounter a frustrating scenario: regsvr32 reports success even when DLL registration fails due to permission issues. This creates a false positive that can be problematic during deployments.

Here are several approaches to verify DLL registration status:

1. Checking Registry Entries

Registered DLLs create entries in the Windows Registry. You can verify this using the reg command:

@echo off
reg query HKCR\CLSID /s /f "YourDllName.dll" >nul 2>&1
if %errorlevel%==0 (
    echo DLL is registered
) else (
    echo DLL is NOT registered
)

2. Using PowerShell (For Newer Systems)

For modern systems that support PowerShell:

$dllName = "YourDllName.dll"
$registered = [bool](Get-ChildItem -Path HKLM:\Software\Classes\CLSID -Recurse | 
    Where-Object { $_.GetValue("") -like "*$dllName*" })
Write-Host "Registration status: $registered"

3. Programmatic Verification with C++

For more robust checking in applications:

#include <windows.h>
#include <iostream>

bool IsDllRegistered(const wchar_t* dllName) {
    HKEY hKey;
    if (RegOpenKeyEx(HKEY_CLASSES_ROOT, L"CLSID", 0, KEY_READ, &hKey) != ERROR_SUCCESS) {
        return false;
    }

    wchar_t subkeyName[256];
    DWORD index = 0;
    bool found = false;

    while (RegEnumKey(hKey, index, subkeyName, 256) == ERROR_SUCCESS) {
        HKEY hSubKey;
        if (RegOpenKeyEx(hKey, subkeyName, 0, KEY_READ, &hSubKey) == ERROR_SUCCESS) {
            wchar_t value[1024];
            DWORD size = sizeof(value);
            if (RegQueryValueEx(hSubKey, NULL, NULL, NULL, (LPBYTE)value, &size) == ERROR_SUCCESS) {
                if (wcsstr(value, dllName) != NULL) {
                    found = true;
                    RegCloseKey(hSubKey);
                    break;
                }
            }
            RegCloseKey(hSubKey);
        }
        index++;
    }
    RegCloseKey(hKey);
    return found;
}

To verify if the registration failed due to permission problems:

@echo off
regsvr32 /s YourDllName.dll
if %errorlevel% neq 0 (
    echo Registration failed with error code %errorlevel%
) else (
    echo Registration reported success, but verify registry entries
    reg query HKCR\CLSID /s /f "YourDllName.dll" 2>&1 | find "YourDllName.dll" >nul
    if %errorlevel% neq 0 (
        echo WARNING: Registration reported success but no registry entries found
    )
)

For deeper analysis of DLL dependencies and registration status:

  1. Download Dependency Walker (depends.exe)
  2. Open your DLL file
  3. Check for unresolved dependencies that might prevent registration

Many developers working with legacy Windows systems (particularly Windows XP) encounter this frustrating scenario: You run regsvr32 yourdll.dll and get the standard "DllRegisterServer succeeded" message, yet the DLL isn't actually registered. This often occurs due to permission issues or registry virtualization in older Windows versions.

Here are three reliable ways to check DLL registration status programmatically:

1. Registry Query Approach

The most direct method is to check Windows Registry entries. Here's a PowerShell script that checks both 32-bit and 64-bit registry locations:


function Test-DllRegistration {
    param(
        [string]$dllName
    )
    
    # Check 32-bit registration (WOW6432Node)
    $clsid32Path = "HKLM:\SOFTWARE\WOW6432Node\Classes\CLSID"
    # Check 64-bit registration
    $clsid64Path = "HKLM:\SOFTWARE\Classes\CLSID"
    
    $registered = $false
    
    # Get all CLSIDs and check InProcServer32 values
    Get-ChildItem $clsid32Path, $clsid64Path -ErrorAction SilentlyContinue | ForEach-Object {
        $key = $_
        $inproc = Join-Path $key.PSPath "InProcServer32"
        if (Test-Path $inproc) {
            $path = (Get-ItemProperty -Path $inproc)."(default)"
            if ($path -like "*$dllName") {
                Write-Host "Found registration in CLSID $($key.PSChildName) at $path"
                $registered = $true
            }
        }
    }
    
    if (-not $registered) {
        Write-Host "No registration found for $dllName"
    }
    
    return $registered
}

2. Using OLE/COM Object Viewer

For a GUI approach, the built-in OLE/COM Object Viewer (oleview.exe) provides complete COM registration information. You can:

  1. Launch oleview.exe from the Start menu or command line
  2. Navigate to "Object Classes" → "All Objects"
  3. Search for your DLL name or expected COM class names

3. Programmatic Verification via COM

For C++ developers, here's how to verify registration by attempting to create a COM instance:


#include 
#include 

bool IsDllRegistered(const CLSID& clsid) {
    IUnknown* pUnknown = nullptr;
    HRESULT hr = CoCreateInstance(clsid, nullptr, CLSCTX_INPROC_SERVER, 
                                IID_IUnknown, reinterpret_cast(&pUnknown));
    
    if (SUCCEEDED(hr)) {
        pUnknown->Release();
        return true;
    }
    return false;
}

// Usage example:
// CLSID_MyComponent - replace with your component's CLSID
// bool registered = IsDllRegistered(CLSID_MyComponent);

When regsvr32 reports success but registration fails due to permissions, these techniques help identify the issue:

  • Check the registry virtualization status (common in Windows XP/Vista):
    reg query HKCU\Software\Classes\VirtualStore /s | findstr "yourdll.dll"
  • Verify effective permissions using Process Monitor (procmon.exe) during registration
  • Test registration with elevated privileges: runas /user:administrator "regsvr32 yourdll.dll"

For advanced scenarios, you can examine the DLL itself to verify it contains registration capability:


dumpbin /exports yourdll.dll | findstr "DllRegisterServer"

This confirms the DLL at least contains the registration function, though it doesn't prove successful execution.