Posted on 2010-12-09 09:15
Sivan 閱讀(2185)
評論(0) 編輯 收藏 引用 所屬分類:
VC/MFC
1.概述
經(jīng)常會(huì)遇到這樣的情況:每次重裝了系統(tǒng),因?yàn)樽员韥G失,一些軟件(在非系統(tǒng)分區(qū)的軟件目錄)需要重新注冊目錄中的DLL(DLL是組件的需要注冊)或OCX才能成功運(yùn)行。通常我們會(huì)手動(dòng)在“運(yùn)行”中輸入“regsvr32 /s dll/ocx路徑”進(jìn)行手段注冊,或者寫一個(gè)如下面形式的批處理文件
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
批處理文件固然簡單高效,但是將每個(gè)目錄中的DLL和OCX都提取出來,然后寫批處理文件也是挺繁瑣的一件事情,能不能只用一個(gè)小程序?qū)⒛夸浿械腄LL與OCX都自動(dòng)注冊呢?本文解決這個(gè)小問題。
2.解決方法
自動(dòng)注冊程序目錄下的DLL和OCX,需要經(jīng)過以下幾個(gè)步驟。
獲得本程序所在目錄路徑→搜尋本目錄下的DLL和OCX文件→裝載DLL或OCX→調(diào)用DLL注冊進(jìn)入點(diǎn)函數(shù)DllRegisterServer/或反注冊函數(shù)DllUnregisterServer→卸載DLL或OCX。這個(gè)過程主要用到了四個(gè)函數(shù)。
(1)LoadLibary
HMODULE LoadLibrary(LPCTSTR lpFileName);
LoadLibrary載入指定可執(zhí)行模塊,并將它映射到當(dāng)前進(jìn)程地址空間。載入后,可以訪問庫內(nèi)的資源。
(2)FreeLibrary
BOOL FreeLibrary(HMODULE hModule);
FreeLibrary用于釋放LoadLibary函數(shù)載入的動(dòng)態(tài)鏈接庫。
(3)DllRegisterServer
STDAPI DllRegisterServer(void);
通知一個(gè)進(jìn)程內(nèi)服務(wù)創(chuàng)建它的注冊入口點(diǎn)。
(4)DllUnregisterServer
STDAPI DllUnregisterServer(void);
通知進(jìn)程內(nèi)服務(wù)移除通過DllRegisterServer創(chuàng)建的入口點(diǎn)。
注意:直接調(diào)用DLL內(nèi)函數(shù)需要使用GetProcAddress,而GetProcAddress是Windows API,在Windows32平臺(tái)導(dǎo)出函數(shù)名是ANSI字符的,它的第二個(gè)參數(shù)為LPCSTR(const char*)類型,在Unicode編譯模式下,如果第二個(gè)參數(shù)有L或_T修飾,可能編譯不通??梢詫懗扇缦滦问?br>(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("尋找程序運(yùn)行目錄錯(cuò)誤!"), _T("錯(cuò)誤"), 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
}