Ferramenta de linha de comando para despejar a versão DLL do Windows?

Eu preciso de uma ferramenta de linha de comando para despejar informações de versão DLL padrão do Windows para que eu possa processá-lo por meio de um script bash (Cygwin).

Como desenvolvedor Java, não estou muito acostumado com as ferramentas de desenvolvimento da Microsoft (embora eu tenha um pouco de experiência com o Microsoft Visual Embedded C ++ 4.0 e o Microsoft Visual Basic 6.0).

A ferramenta apropriada parece ser o mt.exe , conforme indicado no SO . No entanto, a única chance que encontrei para obter esse pequeno aplicativo é baixar uma ISO de 1,29 GB do Windows SDK para Windows Server 2008 e .NET Framework . Eu não posso acreditar que esta é a única maneira de fazer isso.

Eu também encontrei um pequeno aplicativo na Internet chamado PEView , mas ele exibe informações demais (e inúteis no meu caso) e não é um aplicativo de linha de comando.

Objdump padrão incluído dentro do Cygwin também pode despejar algumas informações sobre os arquivos DLL, mas não consigo ver a opção de despejar a versão DLL. Note que MajorImageVersion, MinorImageVersion e outros campos descartados por esta ferramenta (com opção -p) não estão relacionados à própria versão da DLL.

Quaisquer alternativas sobre o que fazer? Talvez eu tenha perdido alguma opção importante de objdump? O mt.exe é a minha única escolha? Se este for o caso, é possível obtê-lo separadamente do Windows SDK?

    Você também pode olhar para filever.exe, que pode ser baixado como parte do pacote de ferramentas de suporte do Windows XP SP2 – apenas 4,7 MB de download.

    Você pode usar o PowerShell para obter as informações desejadas.

     (Get-Item C:\Path\To\MyFile.dll).VersionInfo 

    Por padrão, isso exibirá ProductVersion e FileVersion, mas o VERSIONINFO completo está disponível. Ou seja, para retornar Comentários

     (Get-Item C:\Path\To\MyFile.dll).VersionInfo.Comments 

    Use o Microsoft Sysinternals Sigcheck . Este exemplo produz apenas a versão:

     sigcheck -q -n foo.dll 

    O sigcheck.exe descompactado tem apenas 228 KB.

    Você pode escrever um script VBScript para obter as informações da versão do arquivo:

    VersionInfo.vbs

     set args = WScript.Arguments Set fso = CreateObject("Scripting.FileSystemObject") WScript.Echo fso.GetFileVersion(args(0)) Wscript.Quit 

    Você pode chamar isso da linha de comando assim:

     cscript //nologo VersionInfo.vbs C:\Path\To\MyFile.dll 

    ou você pode construir um você mesmo. Abra o VS, crie um novo aplicativo de console. Crie um projeto simples sem suporte para ATL ou MFC, deixe a opção stdafx marcada, mas não marque o ‘projeto vazio’ e chame-o de VersionInfo.

    Você obterá um projeto simples com 2 arquivos: VersionInfo.cpp e VersionInfo.h

    Abra o arquivo cpp e cole o seguinte nele, depois compile. Você poderá executá-lo, o primeiro argumento é o nome completo do arquivo, ele imprimirá “Produto: 5.6.7.8 Arquivo: 1.2.3.4” com base no bloco de resources da Versão. Se não houver recurso de versão, ele retornará -1, caso contrário, 0.

    Compila para um binário de 8k usando a dll CRT, 60k com tudo vinculado estaticamente (definido nas opções de C ++, altere “Página de geração de código, opções de tempo de execução” para “/ MT”)

    HTH.

    PS. Se você não quiser usar o Visual Studio, ele ainda irá compilar usando qualquer compilador c ++ (dedos cruzados), mas você quase certamente terá que alterar o # pragma – apenas especifique o lib nas configurações do vinculador, o pragma apenas um atalho para vincular automaticamente a essa biblioteca.


     // VersionInfo.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include  #pragma comment(lib, "version.lib") int _tmain(int argc, _TCHAR* argv[]) { DWORD handle = 0; DWORD size = GetFileVersionInfoSize(argv[1], &handle); BYTE* versionInfo = new BYTE[size]; if (!GetFileVersionInfo(argv[1], handle, size, versionInfo)) { delete[] versionInfo; return -1; } // we have version information UINT len = 0; VS_FIXEDFILEINFO* vsfi = NULL; VerQueryValue(versionInfo, L"\\", (void**)&vsfi, &len); WORD fVersion[4], pVersion[4]; fVersion[0] = HIWORD(vsfi->dwFileVersionMS); fVersion[1] = LOWORD(vsfi->dwFileVersionMS); fVersion[2] = HIWORD(vsfi->dwFileVersionLS); fVersion[3] = LOWORD(vsfi->dwFileVersionLS); pVersion[0] = HIWORD(vsfi->dwProductVersionMS); pVersion[1] = LOWORD(vsfi->dwProductVersionMS); pVersion[2] = HIWORD(vsfi->dwProductVersionLS); pVersion[3] = LOWORD(vsfi->dwProductVersionLS); printf("Product: %d.%d.%d.%d File: %d.%d.%d.%d\n", pVersion[0], pVersion[1], pVersion[2], pVersion[3], fVersion[0], fVersion[1], fVersion[2], fVersion[3]); delete[] versionInfo; return 0; } 
     C:\>wmic datafile where name="C:\\Windows\\System32\\kernel32.dll" get version Version 6.1.7601.18229 

    As ferramentas listdlls da Systernals podem fazer o trabalho: http://technet.microsoft.com/pt-br/sysinternals/bb896656.aspx

     listdlls -v -d mylib.dll 

    Essa function retorna os detalhes do arquivo ntfs do Windows para qualquer arquivo usando o Cygwin bash (real r-click-properties-info) para o termo

    Passe o caminho dos arquivos para finfo (), pode ser unix path, dos path, relative ou absolute. O arquivo é convertido em um caminho nix absoluto e, em seguida, verificado para ver se é, de fato, um arquivo regular / existente. Em seguida, convertido em um caminho absoluto do Windows e enviado para “wmic”. Então mágica, você tem detalhes do arquivo do Windows no terminal. Usos: cygwin, cygpath, sed e awk. Precisa que o Windows WMI “wmic.exe” esteja operacional. A saída é corrigida para facilitar …

     $ finfo notepad.exe $ finfo "C:\windows\system32\notepad.exe" $ finfo /cygdrive/c/Windows/System32/notepad.exe $ finfo "/cygdrive/c/Program Files/notepad.exe" $ finfo ../notepad.exe finfo() { [[ -e "$(cygpath -wa "$@")" ]] || { echo "bad-file"; return 1; } echo "$(wmic datafile where name=\""$(echo "$(cygpath -wa "$@")" | sed 's/\\/\\\\/g')"\" get /value)" |\ sed 's/\r//g;s/^M$//;/^$/d' | awk -F"=" '{print $1"=""\033[1m"$2"\033[0m" }' } 

    Existe um aplicativo de linha de comando chamado “ShowVer” no CodeProject:

    Programa de exibição de linha de comando ShowVer.exe VERSIONINFO

    Como de costume, o aplicativo vem com um exe e o código-fonte (VisualC ++ 6).

    Out produz todos os metadados disponíveis:

    Em um sistema alemão Win7, a saída para user32.dll é assim:

     VERSIONINFO for file "C:\Windows\system32\user32.dll": (type:0) Signature: feef04bd StrucVersion: 1.0 FileVersion: 6.1.7601.17514 ProductVersion: 6.1.7601.17514 FileFlagsMask: 0x3f FileFlags: 0 FileOS: VOS_NT_WINDOWS32 FileType: VFT_DLL FileDate: 0.0 LangID: 040704B0 CompanyName : Microsoft Corporation FileDescription : Multi-User Windows USER API Client DLL FileVersion : 6.1.7601.17514 (win7sp1_rtm.101119-1850) InternalName : user32 LegalCopyright : ® Microsoft Corporation. Alle Rechte vorbehalten. OriginalFilename : user32 ProductName : Betriebssystem Microsoft« Windows« ProductVersion : 6.1.7601.17514 Translation: 040704b0 

    e uma maneira com o makecab :

     ; @echo off ;;goto :end_help ;;setlocal DsiableDelayedExpansion ;;; ;;; ;;; fileinf /l list of full file paths separated with ; ;;; fileinf /f text file with a list of files to be processed ( one on each line ) ;;; fileinf /? prints the help ;;; ;;:end_help ; REM Creating a Newline variable (the two blank lines are required!) ; set NLM=^ ; set NL=^^^%NLM%%NLM%^%NLM%%NLM% ; if "%~1" equ "/?" type "%~f0" | find ";;;" | find /v "find" && exit /b 0 ; if "%~2" equ "" type "%~f0" | find ";;;" | find /v "find" && exit /b 0 ; setlocal enableDelayedExpansion ; if "%~1" equ "/l" ( ; set "_files=%~2" ; echo !_files:;=%NL%!>"%TEMP%\file.paths" ; set _process_file="%TEMP%\file.paths" ; goto :get_info ; ) ; if "%~1" equ "/f" if exist "%~2" ( ; set _process_file="%~2" ; goto :get_info ; ) ; echo incorect parameters & exit /b 1 ; :get_info ; set "file_info=" ; makecab /d InfFileName=%TEMP%\file.inf /d "DiskDirectory1=%TEMP%" /f "%~f0" /f %_process_file% /v0>nul ; for /f "usebackq skip=4 delims=" %%f in ("%TEMP%\file.inf") do ( ; set "file_info=%%f" ; echo !file_info:,=%nl%! ; ) ; endlocal ;endlocal ; del /q /f %TEMP%\file.inf 2>nul ; del /q /f %TEMP%\file.path 2>nul ; exit /b 0 .set DoNotCopyFiles=on .set DestinationDir=; .set RptFileName=nul .set InfFooter=; .set InfHeader=; .Set ChecksumWidth=8 .Set InfDiskLineFormat=; .Set Cabinet=off .Set Compress=off .Set GenerateInf=ON .Set InfDiskHeader=; .Set InfFileHeader=; .set InfCabinetHeader=; .Set InfFileLineFormat=",file:*file*,date:*date*,size:*size*,csum:*csum*,time:*time*,vern:*ver*,vers:*vers*,lang:*lang*" 

    exemplo de saída (tem uma versão de string que é uma pequena adição ao método wmic :)):

     c:> fileinfo.bat /l C:\install.exe file:install.exe date:11/07/07 size:562688 csum:380ef239 time:07:03:18a vern:9.0.21022.8 vers:9.0.21022.8 built by: RTM lang:1033 

    e mais um Usando o shell.application e o batch híbrido \ jscript.Here’s tooptipInfo.bat :

     @if (@X)==(@Y) @end /* JScript comment @echo off rem :: the first argument is the script name as it will be used for proper help message cscript //E:JScript //nologo "%~f0" %* exit /b %errorlevel% @if (@X)==(@Y) @end JScript comment */ ////// FSOObj = new ActiveXObject("Scripting.FileSystemObject"); var ARGS = WScript.Arguments; if (ARGS.Length < 1 ) { WScript.Echo("No file passed"); WScript.Quit(1); } var filename=ARGS.Item(0); var objShell=new ActiveXObject("Shell.Application"); ///// //fso ExistsItem = function (path) { return FSOObj.FolderExists(path)||FSOObj.FileExists(path); } getFullPath = function (path) { return FSOObj.GetAbsolutePathName(path); } // //paths getParent = function(path){ var splitted=path.split("\\"); var result=""; for (var s=0;s 

    usado contra o cmd.exe:

     C:\Windows\System32\cmd.exe : File description: Windows Command Processor Company: Microsoft Corporation File version: 6.3.9600.16384 Date created: ?22-?Aug-?13 ??13:03 Size: 347 KB 

    Usando o Powershell é possível obter apenas a string Version, ou seja, 2.3.4 de qualquer dll ou exe com o seguinte comando

     (Get-Item "C:\program files\OpenVPN\bin\openvpn.exe").VersionInfo.ProductVersion 

    Testado no Windows 10