HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows/CurrentVersion/SharedDlls 键是用来储存系统中所有 SharedDlls 的使用情况的,其中每一项的值代表着这个 SharedDll 被多少个应用程序所引用,如果某项的值为 0,那么就说明这个 SharedDll 已经变成无用的了。我们就这个原理,分别以批处理、C/C++、VB三种方法进行枚举。
1.批处理
使用批处理文件枚举时人是占据主导地位的,也就是说,批处理文件只可以导出该键下的所有项和值,具体的某一项值是否为0,则需要人工判别,其命令如下:

lua的枚举类型_microsoft


REG QUERY HKLM/SOFTWARE/Microsoft/Windows/CurrentVersion/SharedDlls /s >>"C:/List.TXT" 由于列表过长,所以我们将程序的运行结果保存至 C:/List.TXT 以便于分析。


2.C/C++


在用 C/C++ 进行枚举时需要用到 RegOpenKey() 和

RegEnumValue() 以及 RegCloseKey() 这三个函数且不需要再人工查找,其具体代码如下:



lua的枚举类型_microsoft

#include"stdafx.h"

lua的枚举类型_microsoft

#include"stdio.h"

lua的枚举类型_microsoft

#include"windows.h"

lua的枚举类型_microsoft


lua的枚举类型_microsoft

void main(int argc, char* argv[])

lua的枚举类型_vb_07

lua的枚举类型_vb_08

{

lua的枚举类型_function_09

    if(argc==2)

lua的枚举类型_function_09

        if(argv[1]=="/love")

lua的枚举类型_function_09

            printf("%s/n/n","I love WYC!");//这是一个彩蛋

lua的枚举类型_function_09


lua的枚举类型_function_09

    printf("%s/n/n","(C) 2006 陈炜");

lua的枚举类型_function_09


lua的枚举类型_function_09

    HKEY hKey=HKEY_LOCAL_MACHINE;

lua的枚举类型_function_09

    LPTSTR KeyName[257];//必须在声明 i 之前声明 KeyName

lua的枚举类型_function_09

    DWORD dwIndex=0,KeyValue,lpType=REG_DWORD,i=sizeof(KeyName),j=sizeof(DWORD);

lua的枚举类型_function_09


lua的枚举类型_function_09

    if (RegOpenKey(hKey,"SOFTWARE//Microsoft//Windows//CurrentVersion//SharedDlls",&hKey)!=ERROR_SUCCESS)

lua的枚举类型_microsoft_20

lua的枚举类型_microsoft_21

    ...{

lua的枚举类型_function_09

        printf("%s ","打开键时出现错误");

lua的枚举类型_function_09

        exit(0);

lua的枚举类型_string_24

    }

lua的枚举类型_function_09

    while(RegEnumValue(hKey,dwIndex,(LPTSTR)KeyName,&i,NULL,&lpType,(LPBYTE)&KeyValue,&j)!=ERROR_NO_MORE_ITEMS)

lua的枚举类型_microsoft_20

lua的枚举类型_microsoft_21

    ...{

lua的枚举类型_function_09

        if(KeyValue!=0)

lua的枚举类型_microsoft_20

lua的枚举类型_microsoft_21

        ...{

lua的枚举类型_function_09

            dwIndex++;

lua的枚举类型_function_09

            i=sizeof(KeyName);

lua的枚举类型_function_09

            j=sizeof(DWORD);

lua的枚举类型_string_24

        }

lua的枚举类型_function_09

        else

lua的枚举类型_microsoft_20

lua的枚举类型_microsoft_21

        ...{

lua的枚举类型_function_09

            printf("%s/n",KeyName);

lua的枚举类型_function_09

            dwIndex++;

lua的枚举类型_function_09

            i=sizeof(KeyName);

lua的枚举类型_function_09

            j=sizeof(DWORD);

lua的枚举类型_string_24

        }

lua的枚举类型_string_24

    }

lua的枚举类型_function_09

    RegCloseKey(hKey);

lua的枚举类型_function_09

    putchar('/n');

lua的枚举类型_vb_46

} ... 这里需要说明的是, RegEnumValue() 函数的第七个参数原型为 unsigned char*,所以如果我们在声明 KeyValue 时声明的是参数原型,则在运行时会出现错误,即若读出的值为1,则在向屏幕输出时会将其作为 ASCII 码中的 001 字符打印,也就是说会打印出一个笑脸而不是数字1,这样是无法通过程序判断的,故而我们将其声明为 unsigned long 并在执行函数时强值转换类型,以避免错误的发生。此外,由于i和j变量分别表示的是一个长度指针,所以在每次循环后都会改变,如果不在循环体内重新赋值则可能出现读出数据与原数据不符的错误。


3.Visual Basic


在用 VB 进行枚举时同样需要用到 RegOpenKey() 和 RegEnumValue() 以及

RegCloseKey() 这三个函数且不需要再人工查找,其具体方法如下:


首先,我们新建一个 标准EXE 工程,并将 Form1 的

AutoRedraw 属性设为 True,之后我们声明 API 函数和常数:


Option Explicit
Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
Private Declare Function RegEnumValue Lib "advapi32.dll" Alias "RegEnumValueA" _
(ByVal hKey As Long, ByVal dwIndex As Long, ByVal lpValueName As String, lpcbValueName _
As Long, ByVal lpReserved As Long, lpType As Long, lpData As Long, lpcbData As Long) As Long
Private Declare Function RegOpenKey Lib "advapi32.dll" Alias "RegOpenKeyA" (ByVal hKey As Long, _
ByVal lpSubKey As String, phkResult As Long) As Long
Private Const HKEY_LOCAL_MACHINE = &H80000002
Private Const ERROR_SUCCESS = 0&
Private Const ERROR_NO_MORE_ITEMS = 259&
Private Const REG_DWORD = 4

然后,向 Form1 的 Form_Load() 过程添加如下代码:



lua的枚举类型_vb_07

lua的枚举类型_vb_08

Private Sub Form_Load()

lua的枚举类型_function_09

    

lua的枚举类型_function_09

    Dim hKey As Long, hOpen As Long, hEnum As Long

lua的枚举类型_function_09

    Dim KeyName As String * 256, KeyValue As Long, i As Long, j As Long, dwIndex As Long

lua的枚举类型_function_09

    

lua的枚举类型_function_09

    dwIndex = 0

lua的枚举类型_function_09

    i = 256

lua的枚举类型_function_09

    j = 256

lua的枚举类型_function_09

    hOpen = RegOpenKey(HKEY_LOCAL_MACHINE, _

lua的枚举类型_function_09

    "SOFTWARE/Microsoft/Windows/CurrentVersion/SharedDlls", hKey)

lua的枚举类型_function_09

    If hOpen <> ERROR_SUCCESS Then

lua的枚举类型_function_09

        Print "打开键出现错误"

lua的枚举类型_function_09

        Exit Sub

lua的枚举类型_function_09

    End If

lua的枚举类型_function_09

    Do

lua的枚举类型_function_09

        hEnum = RegEnumValue(hKey, dwIndex, KeyName, i, 0&, REG_DWORD, KeyValue, j)

lua的枚举类型_function_09

        If hEnum = ERROR_SUCCESS Then

lua的枚举类型_function_09

            If CLng(Left$(KeyValue, j)) = 0 Then Print Left$(KeyName, i)

lua的枚举类型_function_09

        End If

lua的枚举类型_function_09

        dwIndex = dwIndex + 1

lua的枚举类型_function_09

        i = 256

lua的枚举类型_function_09

        j = 256

lua的枚举类型_function_09

    Loop While hEnum = ERROR_SUCCESS

lua的枚举类型_function_09

    RegCloseKey(hKey)

lua的枚举类型_function_09


lua的枚举类型_vb_46

End Sub Sub Form_Load() 这里需要说明的是,在声明 RegEnumValue() 函数时,为了匹配本文内容我将第七个参数的类型改为了 Long。


*在删除某一 DLL 时,建议先使用 regsvr32.exe <路径> /u 命令注销 DLL 再删除文件及注册表值。