|
在MFC程序中,通过资源形式释放NuGet依赖的DLL文件,需结合资源嵌入与动态加载技术。以下是具体实现方案:
1. 将DLL嵌入资源文件
在资源视图(Resource View)中右键添加自定义资源类型(如RCDATA),导入目标DLL文件(如WebView2Loader.dll),并指定资源ID(如IDR_WEBVIEW2_DLL)。
资源脚本(.rc)自动生成如下配置:
IDR_WEBVIEW2_DLL RCDATA "path\\to\\WebView2Loader.dll"
2. 动态释放资源到本地
在程序启动阶段(如InitInstance中),调用资源释放函数将DLL写入目标目录(如程序根目录或临时文件夹):
bool ExtractDLLFromResource(int resourceID, LPCTSTR outputPath) {
HRSRC hRes = FindResource(NULL, MAKEINTRESOURCE(resourceID), RT_RCDATA);
if (!hRes) return false;
HGLOBAL hData = LoadResource(NULL, hRes);
if (!hData) return false;
DWORD dllSize = SizeofResource(NULL, hRes);
LPVOID pData = LockResource(hData);
if (!pData) return false;
HANDLE hFile = CreateFile(outputPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) return false;
DWORD written;
WriteFile(hFile, pData, dllSize, &written, NULL);
CloseHandle(hFile);
return written == dllSize;
}
调用示例:
TCHAR dllPath[MAX_PATH];
GetModuleFileName(NULL, dllPath, MAX_PATH);
PathRemoveFileSpec(dllPath);
PathAppend(dllPath, _T("WebView2Loader.dll"));
if (!PathFileExists(dllPath) &&
!ExtractDLLFromResource(IDR_WEBVIEW2_DLL, dllPath)) {
AfxMessageBox(_T("Failed to extract DLL"));
return FALSE;
}
3. 加载释放的DLL
对于静态链接的NuGet包(如WebView2),释放后无需额外操作,框架会自动加载。
动态调用的DLL需通过LoadLibrary显式加载:
HMODULE hModule = LoadLibrary(dllPath);
if (hModule) {
typedef void (*InitFunc)();
InitFunc init = (InitFunc)GetProcAddress(hModule, "Initialize");
if (init) init();
}
4. 注意事项
版本匹配:嵌入的DLL需与NuGet包版本严格一致,避免兼容性问题。
路径权限:确保目标目录可写(如程序目录需管理员权限)。
清理机制:临时文件应在程序退出时删除。
通过此方案,可避免因DLL缺失导致的运行时错误,同时保持部署的简洁性。
|
|