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

GetFileVersionInfo获取SqlOledB.dll文件版本返回错误值问题

简述

SqlOledB.dll的文件版本:

  • 实际版本: 10.0.18362.1
  • GetFileVersionInfo返回值: 6.2.18362.1
详细说明

我尝试获取Windows DLL C:\Program Files (x86)\Common Files\System\Ole DB\sqloledb.dll的文件版本:

在Windows资源管理器中可见:

  • 文件版本:10.0.18362.1
  • 产品版本:10.0.18362.1

文件版本信息

使用PowerShell执行:

> [System.Diagnostics.FileVersionInfo]::GetVersionInfo("C:\Program Files (x86)\Common Files\System\Ole DB\sqloledb.dll") | Format-List -property *

得到文件版本:

FileVersionRaw     : 10.0.18362.1
ProductVersionRaw  : 10.0.18362.1
Comments           :
CompanyName        : Microsoft Corporation
FileBuildPart      : 18362
FileDescription    : OLE DB Provider for SQL Server
FileMajorPart      : 10
FileMinorPart      : 0
FileName           : C:\Program Files (x86)\Common Files\System\Ole DB\sqloledb.dll
FilePrivatePart    : 1
FileVersion        : 10.0.18362.1 (WinBuild.160101.0800)
InternalName       : sqloledb.dll
IsDebug            : False
IsPatched          : False
IsPrivateBuild     : False
IsPreRelease       : False
IsSpecialBuild     : False
Language           : English (United States)
LegalCopyright     : © Microsoft Corporation. All rights reserved.
LegalTrademarks    :
OriginalFilename   : sqloledb.dll
PrivateBuild       :
ProductBuildPart   : 18362
ProductMajorPart   : 10
ProductMinorPart   : 0
ProductName        : Microsoft® Windows® Operating System
ProductPrivatePart : 1
ProductVersion     : 10.0.18362.1
SpecialBuild       :

查看该DLL的VersionInfo资源,文件版本与产品版本一致:

1 VERSIONINFO
FILEVERSION 10,0,18362,1
PRODUCTVERSION 10,0,18362,1
FILEOS 0x40004
FILETYPE 0x2
{
BLOCK "StringFileInfo"
{
    BLOCK "040904B0"
    {
        VALUE "CompanyName", "Microsoft Corporation"
        VALUE "FileDescription", "OLE DB Provider for SQL Server"
        VALUE "FileVersion", "10.0.18362.1 (WinBuild.160101.0800)"
        VALUE "InternalName", "sqloledb.dll"
        VALUE "LegalCopyright", "© Microsoft Corporation. All rights reserved."
        VALUE "OriginalFilename", "sqloledb.dll"
        VALUE "ProductName", "Microsoft® Windows® Operating System"
        VALUE "ProductVersion", "10.0.18362.1"
    }
}

BLOCK "VarFileInfo"
{
    VALUE "Translation", 0x0409 0x04B0
}
}

使用PEView查看原始版本资源,文件和产品版本均为000A0000 47BA0001,同时文件信息字符串部分显示:

  • "FileVersion": "10.0.18362.1 (WinBuild.160101.0800)"
  • "ProductVersion": "10.0.183612.1"

使用Process Monitor可确认应用程序查询的是正确的DLL:
Process Monitor截图

但通过代码查询时得到错误值!

我的32位应用程序调用以下API:

  • GetFileVersionInfoSizeW()
  • GetFileVersionInfoW()
  • VerQueryValueW()(查询"\")

查看返回的VS_FIXEDFILEINFO缓冲区内容:

  • dwSignature: 4277077181
  • dwStrucVersion: 65536
  • dwFileVersionMS: 393218
  • dwFileVersionLS: 1203372033
  • dwProductVersionMS: 655360
  • dwProductVersionLS: 1203372033
  • dwFileFlagsMask: 63
  • dwFileFlags: 0
  • dwFileOS: 262148
  • dwFileType: 2
  • dwFileSubtype: 0
  • dwFileDateMS: 0
  • dwFileDateLS: 0

将文件版本和产品版本值转换为十六进制:

字段十进制十六进制
dwFileVersionMS3932180x00060002
dwFileVersionLS12033720330x47BA0001
dwProductVersionMS6553600x000A0000
dwProductVersionLS12033720330x47BA0001

转换为十进制版本字符串:

  • 文件版本: 6.2.18362.1
  • 产品版本: 10.0.13621.1

产品版本正确,但文件版本完全错误。

由此产生以下疑问:

  • 当DLL二进制文件中所有信息都显示版本为10.0.x.x时,GetFileVersion() API为何会返回6.2.x.x版本?
  • 是否存在应用程序兼容性垫片(appcompat shim)篡改版本号,使其显示为Windows 6.2而非10.0?
  • 是否需要更新程序集清单中的SupportedOS条目?

核心问题:Windows为何返回一个二进制文件中不存在的版本值?

简化复现代码

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils, Windows;

function GetFileVersion(Filename: WideString): string;
var
    dwHandle: Cardinal;
    dwInfoLength: Cardinal;
    pInfoData: Pointer;
    lengthOfReturned: Cardinal;
    value: Pointer;
    fileInfo: PVSFixedFileInfo;
    iMajor, iMinor, iBuild, iRelease: Integer;
begin
    Result := '?.?.?.?';

    // 获取文件信息结构所需的字节数
    dwHandle := 0;
    dwInfoLength := GetFileVersionInfoSizeW(PWideChar(Filename), {var}dwHandle);
    if dwInfoLength = 0 then
        Exit;

    // 分配存储文件信息所需的内存
    GetMem(pInfoData, dwInfoLength);
    try
        // 将信息写入刚分配的缓冲区
        if not GetFileVersionInfoW(PWideChar(Filename), 0, dwInfoLength, pInfoData) then
            Exit;

        // 从pInfoData中提取所需数据到FileInformation结构
        value := nil;
        lengthOfReturned := 0;
        if not VerQueryValueW(pInfoData, '\', {var}value, {var}lengthOfReturned) then
            Exit;

        fileInfo := PVSFixedFileInfo(value);

        iMajor := fileInfo.dwFileVersionMS shr 16;
        iMinor := fileInfo.dwFileVersionMS and $FFFF;
        iRelease := fileInfo.dwFileVersionLS shr 16;
        iBuild := fileInfo.dwFileVersionLS and $FFFF;
    finally
        FreeMem(pInfoData);
    end;

    Result := Format('%d.%d.%d.%d', [iMajor, iMinor, iRelease, iBuild]);
end;

procedure Main;
var
    filename: string;
    version: string;
begin
    filename := 'C:\Program Files (x86)\Common Files\System\Ole DB\sqloledb.dll';
    version := GetFileVersion(filename);

    WriteLn('Filename:     '+filename);
    WriteLn('File version: '+version);
end;


begin
    Main;

    WriteLn('Press enter to close...');
    ReadLn;
end.

补充说明

我还尝试使用ANSI版本API(搭配ANSI字符串),怀疑旧版ANSI版本可能存在篡改版本号的兼容性特性。

已在Delphi 5和Delphi XE6中测试,均为32位应用程序。

参考资料

  • GetFileVersionInfo() returns wrong file's version information

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 22:59:51