这篇文章,我反复写了3遍,第一遍是快写完的时候电脑重启,第二遍是发表文章的时候发现超时,然后文章丢失。
现在我只想说Mother fuck。。。
通常在程序生成后可能需要调用其他的DLL,这就导致发布程序的时候需要将EXE文件和DLL一起发布,但有些情况下只允许一个EXE文件存在,这时我们可以采用DLL自释放的方法来解决,需要做的事情就是:
1. 将DLL添加到应用程序的资源文件中
2. 在程序运行的初始化阶段将DLL释放出来
下面是一个完整的VC2008实现的DLL自释放的实例:
1. 创建一个MFC程序
2. 添加DLL到资源文件中
资源视图--添加资源--导入--选择DLL--资源类型填“RAWBINARY”或自己起的名字也可以。
完成上面的步骤后会发现资源视图中多了一个RAWBINARY类型,且里面有一个资源,将其ID改为:IDR_RAWBINARY_MYDLL,并将属性external file改成False。
3. 修改构造函数添加DLL释放代码
#include "shlwapi.h" // CDLLAutoExtractApp 构造 CDLLAutoExtractApp::CDLLAutoExtractApp() { // TODO: 在此处添加构造代码, // 将所有重要的初始化放置在 InitInstance 中 // 合成路径为系统目录下的DLL TCHAR DLLName[MAX_PATH]; // 得到系统目录即:system32目录 ::GetSystemDirectory(DLLName, MAX_PATH); SetCurrentDirectory(DLLName); StrCat(DLLName, _TEXT("//MyDllTest.dll")); LPVOID lpDll = NULL; DWORD DLLSize = 0; HGLOBAL hMem = NULL; // 取得资源句柄 HRSRC hRes = ::FindResourceEx(theApp.m_hInstance, _TEXT("RawBinary"), // 资源类型 MAKEINTRESOURCE(IDR_RAWBINARY_MYDLL), // 这是我们添加的资源ID MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL)); if(hRes) { // 得到资源大小 DLLSize = ::SizeofResource(theApp.m_hInstance, hRes); hMem = ::LoadResource(theApp.m_hInstance, hRes); if(hMem) { lpDll = ::LockResource(hMem); } } if (lpDll == NULL) { // DLL释放失败则程序不会启动 ::MessageBox(NULL, _TEXT("Resource File error"), _TEXT("ERROR"), MB_OK); ::ExitProcess(0); } HANDLE hFile = CreateFile( DLLName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, NULL); DWORD unuse = 0; // 写为文件 WriteFile(hFile, lpDll, DLLSize, &unuse, NULL); // 释放所有资源 UnlockResource(hMem); FreeResource(hMem); CloseHandle(hFile); }
4. 修改项目属性,将刚才添加的DLL设置为延迟加载的DLL
至于如何使用DLL,请参考我之前的文章《VC2008如何生成及使用DLL》。
不能上传RAR文件,有需要我写好的示例程序的请留下邮箱。