[原]自动注册程序目录下的DLL和OCX

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"))

[原]自动注册程序目录下的DLL和OCX_第1张图片

代码如下:
  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}

你可能感兴趣的:([原]自动注册程序目录下的DLL和OCX)