GetFileVersionInfo 返回 SQLOLEDB.dll 的错误文件版本

问题描述 投票:0回答:1

简短版本

SqlOledB.dll
的文件版本:

长版

我正在尝试获取 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
。我还看到文件信息字符串部分显示:

  • “文件版本”:“10.0.18362.1(WinBuild.160101.0800)”
  • “产品版本”:“10.0.183612.1”

当我使用Process Monitor时,我可以看到我的应用程序正在查询正确的DLL:

但是,当我从代码中查询它时,我得到了错误的值!

当我的 32 位应用程序调用时:

然后查看返回的

VS_FIXEDFILEINFO
缓冲区的内容,我看到:

  • dw签名:4277077181
  • dwStruc版本:65536
  • dwFileVersionMS:393218
  • dwFileVersionLS:1203372033
  • dw产品版本MS:655360
  • dw产品版本LS:1203372033
  • dwFileFlagsMask:63
  • dwFileFlags:0
  • dwFileOS:262148
  • dw文件类型:2
  • dw文件子类型:0
  • dwFileDateMS:0
  • dwFileDateLS:0

如果您查看 fileVersion 和 ProductVersion 值,并将它们转换为十六进制:

田野 十进制 十六进制
dwFileVersionMS 393218 0x00060002
dw文件版本LS 1203372033 0x47BA0001
dw产品版本MS 655360 0x000A0000
dw产品版本LS 1203372033 0x47BA0001

这为您提供了十六进制版本:

  • 文件版本:
    0x0006
    0x0002
    0x47BA
    0x0001
  • 产品版本:
    0x000A
    0x0000
    0x47BA
    0x0001

我们以十进制字符串形式获取版本:

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

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

这就引出了问题:

  • GetFileVersion()
    API函数可能从哪里获取版本
    6.2.x.x
    ;当有关 DLL 二进制文件的所有内容都显示为
    10.0.x.x
  • 是否有应用程序兼容垫片启动;对我撒谎,说版本号是 Windows 6.2 而不是 Windows 10.0
  • 我需要更新程序集清单中的
    SupportedOS
    条目吗?

简短版本:Windows 如何返回二进制文件中任何地方都不存在的版本值?

CRME 适合懒人

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 := '?.?.?.?';

    // Get the number of bytes he have to allocate for the file information structure
    dwHandle := 0;
    dwInfoLength := GetFileVersionInfoSizeW(PWideChar(Filename), {var}dwHandle);
    if dwInfoLength = 0 then
        Exit;

    // Allocate the memory needed to hold the file info
    GetMem(pInfoData, dwInfoLength);
    try
        //Put the information into the buffer we just allocated
        if not GetFileVersionInfoW(PWideChar(Filename), 0, dwInfoLength, pInfoData) then
            Exit;

        // Extract the desired data from pInfoData into the FileInformation structure
        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 版本(带有 ANSI 字符串),以防旧版 ANSI 版本具有一些与版本号相关的应用程序兼容功能。

在 Delphi 5 和 Delphi XE6 中尝试过 - 都是 32 位应用程序。

奖励阅读

delphi winapi delphi-xe6 delphi-5 sqloledb
1个回答
0
投票

是的,这是一个应用程序兼容的垫片 - 对我使用的

.dll
版本撒谎。

添加 Windows 10 条目

<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>

我的

Assembly.manifest
修复了它。

© www.soinside.com 2019 - 2024. All rights reserved.