【问题标题】:How might I retrieve the version number of a Windows EXE or DLL?如何检索 Windows EXE 或 DLL 的版本号?
【发布时间】:2010-10-10 23:59:51
【问题描述】:

如何在运行时检索存储在 Windows exe/dll 中的版本信息?此信息是使用资源文件手动设置的。

【问题讨论】:

    标签: c++ windows winapi version


    【解决方案1】:

    这是使用标准 Windows API 函数的 C++ 方法:

    try
    {
        TCHAR szFileName[ MAX_PATH ];
        if( !::GetModuleFileName( 0, szFileName, MAX_PATH ) )
            throw __LINE__;
    
        DWORD nParam;
        DWORD nVersionSize = ::GetFileVersionInfoSize( szFileName, &nParam );
        if( !nVersionSize )
            throw __LINE__;
    
        HANDLE hMem = ::GetProcessHeap();
        if( !hMem )
            throw __LINE__;
    
        LPVOID lpVersionData = ::HeapAlloc( hMem, 0, nVersionSize );
        if( !lpVersionData )
            throw __LINE__;
    
        if( !::GetFileVersionInfo( szFileName, 0, nVersionSize, lpVersionData ) )
            throw __LINE__;
    
        LPVOID pVersionInfo;
        UINT nSize;
        if( !::VerQueryValue( lpVersionData, _T("\\"), &pVersionInfo, &nSize ) )
            throw __LINE__;
    
        VS_FIXEDFILEINFO *pVSInfo = (VS_FIXEDFILEINFO *)pVersionInfo;
        CString strVersion;
        strVersion.Format( _T(" version %i.%i.%i.%i"),
            pVSInfo->dwProductVersionMS >> 16,
            pVSInfo->dwProductVersionMS & 0xFFFF,
            pVSInfo->dwProductVersionLS >> 16,
            pVSInfo->dwProductVersionLS & 0xFFFF
            );
        GetDlgItem( IDC_ABOUT_VERSION )->SetWindowText( strAppName + strVersion );
    
        if( !HeapFree( hMem, 0, lpVersionData ) )
            throw __LINE__;
    }
    catch( int err )
    {
        ASSERT( !err ); // always break on debug builds to inspect error codes and such
    
        DWORD dwErr = ::GetLastError();
    
        // handle memory cleanup...
    }
    

    请注意,catch 部分纯粹是教育性的 - 在实际情况下,您将在内存分配后正确清理并实际使用错误代码!

    【讨论】:

    • 如果在你调用 ::HeapAlloc 之后有一个 throw,这将导致内存泄漏。
    【解决方案2】:

    要检查 .NET 程序集,在 C# 中:

    System.Reflection.Assembly.LoadFile(@"c:\windows\Microsoft.NET\Framework\v2.0.50727\system.data.dll").GetName().Version.ToString();

    【讨论】:

      【解决方案3】:

      这是一个 Delphi 7 版本:

      uses Windows, SysUtils;
      
      function GetEXEVersion(exename: string; const Fmt : string = '%d.%d.%d.%d'): string;
      {
          credit to martinstoeckli@gmx.ch 
        ( http://martinstoeckli.ch/delphi/delphi.html#AppVersion )
      }
      var
        iBufferSize, iDummy : dword;
        pBuffer, pFileInfo : Pointer;
        iVer : array[1..4] of word;
      begin
        Result := '';
        iBufferSize := GetFileVersionInfoSize(PChar(exename), iDummy);
        if iBufferSize > 0 then begin
          GetMem(pBuffer, iBufferSize);
          try
            GetFileVersionInfo(PChar(exename), 0, iBufferSize, pBuffer);
            VerQueryValue(pBuffer, '\', pFileInfo, iDummy);
            iVer[1] := HiWord(PVSFixedFileInfo(pFileInfo)^.dwFileVersionMS);
            iVer[2] := LoWord(PVSFixedFileInfo(pFileInfo)^.dwFileVersionMS);
            iVer[3] := HiWord(PVSFixedFileInfo(pFileInfo)^.dwFileVersionLS);
            iVer[4] := LoWord(PVSFixedFileInfo(pFileInfo)^.dwFileVersionLS);
            finally FreeMem(pBuffer);
          end;
          Result := Format(Fmt, [iVer[1],iVer[2],iVer[3],iVer[4]] );
        end;
      end;
      

      【讨论】:

        【解决方案4】:

        Valentin 的回答是正确的,但请注意评论者 plinth 关于内存泄漏可能性的警告。

        我也不确定你为什么要在这个时代使用 ::HeapAlloc。

        这是一个 sn-p,它使用 new 和 boost::shared_array 来做同样的事情,恕我直言,这是一种更安全、更清洁的方式。

        #include <boost/shared_array.hpp> 
        
        //.....
        
        DWORD   dwHandle;
        DWORD   dwFileVersionInfoSize = GetFileVersionInfoSize((LPTSTR)lpszFileName, &dwHandle);
        
        if (!dwFileVersionInfoSize)
                 return FALSE;
        
        // ensure our data will be deleted
        boost::shared_array<BYTE> data(new BYTE[dwFileVersionInfoSize]); 
        LPVOID const lpData = data.get(); 
        
        //party on with lpData.... 
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-09-01
          • 2010-10-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-01-02
          相关资源
          最近更新 更多