You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于操作系统版本导入DLL,兼容旧系统避免GetDpiForWindow报错

解决方案

针对你的问题,有两种可靠的处理方式,既能兼容旧系统,又能在符合要求的系统上正常调用API:

方案一:提前检查Windows版本

先判断当前系统是否满足GetDpiForWindow的最低要求(Windows 10 1607,对应内部版本号14393),如果不满足则直接返回默认DPI缩放因子1.0(对应96DPI)。

修改后的代码如下:

public static class WindowUtil
{
    [DllImport("user32.dll")]
    private static extern int GetDpiForWindow(IntPtr hWnd);

    public static double GetWindowDPIFactor(IntPtr winhandle)
    {
        if (winhandle == IntPtr.Zero)
        {
            return 1;
        }

        // 检查系统是否为Windows 10 1607及以上版本
        var osVersion = Environment.OSVersion.Version;
        if (osVersion.Major >= 10 && osVersion.Build >= 14393)
        {
            return (double)GetDpiForWindow(winhandle) / 96;
        }
        else
        {
            // 旧系统返回默认DPI缩放因子
            return 1.0;
        }
    }
}

方案二:捕获API调用异常

如果不想依赖版本检查,可以在调用GetDpiForWindow时捕获EntryPointNotFoundException(当系统找不到该API入口点时抛出),捕获到异常后返回默认值。这种方式更灵活,无需硬编码版本号。

修改后的代码如下:

public static class WindowUtil
{
    [DllImport("user32.dll", SetLastError = true)]
    private static extern int GetDpiForWindow(IntPtr hWnd);

    public static double GetWindowDPIFactor(IntPtr winhandle)
    {
        if (winhandle == IntPtr.Zero)
        {
            return 1;
        }

        try
        {
            return (double)GetDpiForWindow(winhandle) / 96;
        }
        catch (EntryPointNotFoundException)
        {
            // 系统不支持该API,返回默认DPI缩放因子
            return 1.0;
        }
    }
}

补充说明

  • 方案一的版本检查更高效,避免了异常捕获的性能开销;
  • 方案二更鲁棒,即使未来系统版本号规则变化,只要API存在就能正常调用,不存在就 fallback 到默认值;
  • 两种方案都能解决Win7等旧系统中类实例化或API调用时的异常问题。

内容的提问来源于stack exchange,提问作者mrpiggy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 14:55:15