【问题标题】:VC++ project, how to define DLL missing error messages?VC++项目,如何定义DLL缺失错误信息?
【发布时间】:2013-09-03 13:01:26
【问题描述】:

所以想法是当用户没有安装 DirectX End-User Runtime 时,程序会显示诸如“DirectX Runtime 丢失!从这里下载”之类的消息,而不是 Windows 加载程序错误(例如:“d3dx9_43.dll不见了!”)。因此,我找到了一个非常时髦的解决方案,因为在使用 LoadLibrary 调用模块中定义的任何函数之前,我使用了延迟加载的 DLL 和 DLL 检查。如果缺少 dll,程序会显示一个用户定义的对话框并退出,否则它会使用 LoadLibrary 返回的 HMODULE 调用 FreeLibrary 并继续执行。这是作为如下函数实现的:

bool CheckResourcesAvailability() //Mainly check for the existence of delay loaded DLL's
{
    HMODULE hMod; //Resourse handle

    if((hMod = LoadLibraryEx(_T("d3d9.dll"), NULL, LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE)) == NULL)
    {
        DialogBox(hProgramInstance, MAKEINTRESOURCE(IDD_DX_RE), 0, (DLGPROC)&DxRedistMissingDlg);
        return false;
    }

    FreeLibrary(hMod);

    if((hMod = LoadLibraryEx(_T("D3DX9_43.dll"), NULL, LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE)) == NULL)
    {
        DialogBox(hProgramInstance, MAKEINTRESOURCE(IDD_DX_RE), 0, (DLGPROC)&DxRedistMissingDlg);
        return false;
    }

    FreeLibrary(hMod);

    return true;
}

*As DxRedistMissingDlg 和 MAKEINTRESOURCE(IDD_DX_RE) 创建用户定义的错误消息对话框。

在 WinMain 中调用如下:

int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine,
                   int nCmdShow)
{
    hProgramInstance = hInstance;

#ifndef _DEBUG
    SetErrorMode(SEM_FAILCRITICALERRORS); //Don't display windows error messages
#endif

    //Check for missing delay - loaded dependencies and inform the user
    if(!CheckResourcesAvailability())
        return -1;
    //Some other code.........

}

但我认为这不是最干净的方法。首先,我们不确定 d3dx9.lib 是否真的继承自 D3DX9_43.dll(我知道是因为我使用了 IDA PRO),并且 LoadLibrary 函数也被调用了两次——一次是在 CheckResourcesAvailability() 函数中,第二次是在 DLL 延迟时-加载。有什么想法可以更好地实现吗?

【问题讨论】:

  • 你为什么要“LoadLibrary”,你可以简单地用“OPEN_EXISTING”标志做“CreateFile”。
  • 因为 LoadLibrary 搜索模块的方式与加载程序 do 相同。 CreateFile 函数只打开指定路径的文件,不做任何额外的搜索。
  • 是的,这是正确的,但我认为加载 Dll 可能不是最好的选择,因为您只检查它的存在。此外,您可以只使用“GetFileAttributes”而不是“CreateFile”,关于加载顺序::从您指定的链接中众所周知。无论如何,只是一个建议。您也可以在使用和不使用 LoadLibrary 的情况下检查性能。
  • 谢谢,但我的第一个问题仍未得到解答。我如何确定 d3dx9.lib 确实需要 D3DX9_43.dll?我的意思是,无论 DX SDK 版本是什么,我怎么能动态知道呢?
  • “官方”响应将是您的包应该是独立的,并且包含所需的 D3D 可再发行组件。作为管理员,我同意,因为它使自动部署变得更加容易。

标签: c++ visual-studio-2010 winapi visual-c++ dll


【解决方案1】:

使用delay load hooks 让延迟加载程序在缺少给定 DLL 或特定导出函数时通知您。这不仅可以告诉您缺少哪个 DLL/函数,还可以让您在需要时指定替代 DLL/函数。

【讨论】:

    猜你喜欢
    • 2012-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-07
    • 1970-01-01
    • 1970-01-01
    • 2018-01-31
    • 1970-01-01
    相关资源
    最近更新 更多