Posted on 2010-12-09 09:15
Sivan 阅读(2167)
评论(0) 编辑 收藏 引用 所属分类:
VC/MFC
1.概述
经常会遇到这样的情况:每次重装了系统,因为注册表丢失,一些软件(在非系统分区的软件目录)需要重新注册目录中的DLL(DLL是组件的需要注册)或OCX才能成功运行。通常我们会手动在“运行”中输入“regsvr32 /s dll/ocx路径”进行手段注册,或者写一个如下面形式的批处理文件
regsvr32 /s Plugin\CBDict08\CBDataSet.dll
regsvr32 /s Plugin\CBNetDict08\CBNetDataSet.dll
regsvr32 /s plugin\CBGoogleDataSet\CBGoogleDataSet.dll
regsvr32 /s plugin\CBNetDicDict\CBNetDicDataSet.dll
regsvr32 /s cache.dll
批处理文件固然简单高效,但是将每个目录中的DLL和OCX都提取出来,然后写批处理文件也是挺繁琐的一件事情,能不能只用一个小程序将目录中的DLL与OCX都自动注册呢?本文解决这个小问题。
2.解决方法
自动注册程序目录下的DLL和OCX,需要经过以下几个步骤。
获得本程序所在目录路径→搜寻本目录下的DLL和OCX文件→装载DLL或OCX→调用DLL注册进入点函数DllRegisterServer/或反注册函数DllUnregisterServer→卸载DLL或OCX。这个过程主要用到了四个函数。
(1)LoadLibary
HMODULE LoadLibrary(LPCTSTR lpFileName);
LoadLibrary载入指定可执行模块,并将它映射到当前进程地址空间。载入后,可以访问库内的资源。
(2)FreeLibrary
BOOL FreeLibrary(HMODULE hModule);
FreeLibrary用于释放LoadLibary函数载入的动态链接库。
(3)DllRegisterServer
STDAPI DllRegisterServer(void);
通知一个进程内服务创建它的注册入口点。
(4)DllUnregisterServer
STDAPI DllUnregisterServer(void);
通知进程内服务移除通过DllRegisterServer创建的入口点。
注意:直接调用DLL内函数需要使用GetProcAddress,而GetProcAddress是Windows API,在Windows32平台导出函数名是ANSI字符的,它的第二个参数为LPCSTR(const char*)类型,在Unicode编译模式下,如果第二个参数有L或_T修饰,可能编译不通。可以写成如下形式
(RegSvrFun)GetProcAddress(hModule, (LPCSTR)("DllUnregisterServer"))

代码如下:
1
CString CRegisterDlg::GetExePath()
2

{
3
TCHAR szPath[MAX_PATH];
4
::GetModuleFileName(NULL, szPath, MAX_PATH);
5
TCHAR* pChr = _tcsrchr(szPath, _T('\\'));
6
CString strVal;
7
if (pChr != NULL)
8
{
9
*pChr = _T('\0');
10
lstrcpy(strVal.GetBuffer(MAX_PATH), szPath);
11
strVal.ReleaseBuffer(MAX_PATH);
12
}
13
return strVal;
14
}
15
16
void CRegisterDlg::OnBnClickedBtnReg()
17

{
18
// TODO: 在此添加控件通知处理程序代码
19
CString strDir;
20
strDir = GetExePath();
21
if (strDir.IsEmpty())
22
{
23
MessageBox(_T("寻找程序运行目录错误!"), _T("错误"), MB_OK | MB_ICONSTOP);
24
return;
25
}
26
27
BeginWaitCursor();
28
29
CStringArray saAllFile,saFile;
30
CFileFind filefind;
31
CString strFind;
32
BOOL bFind = FALSE;
33
34
saAllFile.RemoveAll();
35
strFind.Format(_T("%s\\*.*"), strDir);
36
bFind = filefind.FindFile(strFind);
37
while (bFind)
38
{
39
bFind = filefind.FindNextFile();
40
if (!filefind.IsDirectory() && !filefind.IsDots())
41
{
42
CString strPath;
43
strPath = filefind.GetFilePath();
44
TRACE(_T("%s\n"),strPath);
45
saAllFile.Add(strPath.MakeLower());
46
}
47
}
48
saAllFile.FreeExtra();
49
saFile.RemoveAll();
50
for (int i=0; i!=saAllFile.GetCount(); ++i)
51
{
52
CString strTemp = saAllFile.GetAt(i).Right(4);
53
if (strTemp == _T(".dll") || strTemp == _T(".ocx"))
54
{
55
saFile.Add(saAllFile.GetAt(i));
56
}
57
}
58
saFile.FreeExtra();
59
if (saFile.GetCount() == 0)
60
{
61
MessageBox(_T("目录中没有需要注册的文件!"), _T("提示"), MB_OK | MB_ICONINFORMATION);
62
return;
63
}
64
CStringArray saOK,saFail;
65
saOK.RemoveAll();
66
saFail.RemoveAll();
67
for (int i=0; i!=saFile.GetCount(); ++i)
68
{
69
CString strPath;
70
strPath = saFile.GetAt(i);
71
HMODULE hModule = LoadLibrary(strPath);
72
if (hModule == NULL)
73
{
74
saFail.Add(strPath);
75
return;
76
}
77
RegSvrFun DllRegisterServer = (RegSvrFun)GetProcAddress(hModule, (LPCSTR)("DllRegisterServer"));
78
if (DllRegisterServer != NULL)
79
{
80
HRESULT ret = DllRegisterServer();
81
if (ret == S_OK)
82
{
83
saOK.Add(strPath);
84
}
85
else
86
{
87
saFail.Add(strPath);
88
}
89
}
90
else
91
{
92
saFail.Add(strPath);
93
}
94
FreeLibrary(hModule);
95
}
96
CString strMsg = _T("注册成功的文件有:\n");
97
for (int i=0; i!=saOK.GetCount(); ++i)
98
{
99
CString strTemp = saOK.GetAt(i);
100
strTemp += _T("\n");
101
strMsg += strTemp;
102
}
103
strMsg += _T("\n注册失败的文件有:\n");
104
for (int i=0; i!=saFail.GetCount(); ++i)
105
{
106
CString strTemp = saFail.GetAt(i);
107
strTemp += _T("\n");
108
strMsg += strTemp;
109
}
110
EndWaitCursor();
111
MessageBox(strMsg,_T("提示"),MB_OK | MB_ICONINFORMATION);
112
}