2009-03-02 11 views
53

Ich brauche ein Kommandozeilen-Tool, um Standard-Windows-DLL-Versionsinformationen auszugeben, damit ich es mit einem Bash-Skript (Cygwin) verarbeiten kann.Befehlszeilen-Tool zum Dump Windows DLL-Version?

Als Java-Entwickler bin ich nicht sehr an Microsoft-Entwicklungstools gewöhnt (obwohl ich ein wenig Erfahrung mit Microsoft Visual Embedded C++ 4.0 und Microsoft Visual Basic 6.0 habe).

Das entsprechende Tool scheint mt.exe zu sein, wie stated on SO. Die einzige Chance, die ich gefunden habe, um diese kleine Anwendung zu bekommen, ist, eine 1,29 GB ISO von der Windows SDK for Windows Server 2008 and .NET Framework herunterzuladen. Ich kann nicht glauben, dass dies der einzige Weg ist, es zu tun.

Ich habe auch eine kleine Anwendung im Internet namens PEView gefunden, aber es zeigt zu viel (und nutzlos in meinem Fall) Informationen und es ist keine Befehlszeilenanwendung.

Standard objdump gebündelt in Cygwin kann auch einige Informationen über die DLL-Dateien ausgeben, aber ich kann die Option zum Dumpen der DLL-Version nicht sehen. Beachten Sie, dass MajorImageVersion, MinorImageVersion und andere Felder, die von diesem Tool (mit der Option -p) ausgegeben werden, nicht mit der eigenen DLL-Version zusammenhängen.

Irgendwelche Alternativen, was zu tun ist? Vielleicht habe ich eine wichtige objdump Option verpasst? Ist mt.exe meine einzige Wahl? Wenn dies der Fall ist, ist es möglich, es getrennt von Windows SDK zu erhalten?

Antwort

9

Sie können sich auch Dateiver.exe ansehen, die als Teil des Windows XP SP2 Support Tools Paket heruntergeladen werden kann - nur 4,7 MB Download (oder direkt von here).

+2

, die nur die Dateiversion auflistet, nicht die anderen Versionsaspekte. Oft benötigen Sie auch die Produktversion. 'sigcheck' (wie uvts_cvs erwähnt) zeigt dies auch und ist ein viel kleinerer Download. –

45

Sie können einen VBScript-Skript schreiben, die Dateiversion Informationen zu erhalten:

VersionInfo.vbs

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

Sie können diesen Anruf aus der Befehlszeile wie folgt:

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

Scheinbar realisierbar mit einem Befehlszeilenskript. Danke –

10

oder Sie können selbst eine bauen. Öffnen Sie VS, erstellen Sie eine neue Konsolenanwendung. Erstellen Sie ein einfaches Projekt ohne ATL- oder MFC-Unterstützung, lassen Sie die Option stdafx aktiviert, überprüfen Sie jedoch nicht "leeres Projekt" und nennen Sie es VersionInfo.

Sie werden ein einfaches Projekt mit 2-Dateien erhalten: VersionInfo.cpp und VersionInfo.h

Öffnen Sie die CPP-Datei und die folgenden in sie einfügen, dann kompilieren. Sie können es ausführen, erstes Argument ist der vollständige Dateiname, es wird "Produkt: 5.6.7.8 Datei: 1.2.3.4" basierend auf dem Ressourcenblock Version ausgegeben. Wenn es keine Versionsressource gibt, gibt es -1 zurück, sonst 0.

Kompiliert zu einer 8k-Binärdatei mit der DLL-CRT, 60k mit allem statisch verknüpft (in den C++ - Optionen festgelegt, ändern "Code Generation Seite, Laufzeitoptionen" zu "/ MT")

HTH.

PS. Wenn Sie Visual Studio nicht verwenden möchten, kompiliert es immer noch mit einem beliebigen C++ - Compiler (Daumen drücken), aber Sie müssen fast sicher das # pragma ändern - geben Sie stattdessen nur die lib in den Linker-Einstellungen an, das Pragma nur eine Abkürzung, um automatisch mit dieser Bibliothek zu verknüpfen.


// VersionInfo.cpp : Defines the entry point for the console application. 
// 

#include "stdafx.h" 
#include <windows.h> 

#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; 
} 
+0

Nicht genau, was ich suchte, aber noch interessant, ein kleines Programm zu entwickeln, um es zu tun. Vielen Dank. –

+1

nein? Welche Versionsinformationen wollten Sie haben? AFAIK Windows hat nur Versionsinformationen, die in den Ressourcenblöcken gespeichert sind - das sehen Sie, wenn Sie Eigenschaften im Explorer öffnen. – gbjbaanb

+1

Bravo! Auch ich mag es, Räder zu entwickeln :) – divinci

55

Verwendung Microsoft Sysinternals Sigcheck. Dieses Beispiel gibt nur die Version:

sigcheck -q -n foo.dll 

Entpackte sigcheck.exe ist nur 228 KB.

+3

349 KB fünf Jahre später ... lohnt es sich noch? ;) – Ben

1

Es gibt eine Kommandozeilen-Anwendung "ShowVer" bei Codeproject genannt:

ShowVer.exe command-line VERSIONINFO display program

Wie üblich die Anwendung mit einer exe kommt und den Quellcode (VisualC++ 6).

Out-Ausgänge alle Meta-Daten zur Verfügung:

Auf einem deutschen System Win7 der Ausgang für user32.dll ist wie folgt:

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 
77

Sie Powershell verwenden können, um die gewünschten Informationen zu erhalten.

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

Standardmäßig wird dies angezeigt Product und Fileversion Aber die volle VERSIONINFO zur Verfügung steht. I.e. Kommentare zurückzukehren

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

Das sollte die Antwort sein. Es ist die einzige Antwort, die nicht auf Out-of-Box-Tools angewiesen ist. –

+7

Pipe to fl *, um alle VersionInfo-Eigenschaften abzurufen: PS C: \> (Get-Element C: \ Windows \ System32 \ WindowsPowerShell \ v1.0 \ powershell.exe) .VersionInfo | fl * – Glenn

+0

Mit diesem habe ich 0 für die Versionsnummer und falsch für alle Is * Eigenschaften. – NobleUplift

9
C:\>wmic datafile where name="C:\\Windows\\System32\\kernel32.dll" get version 
Version 
6.1.7601.18229 
+0

Dies funktioniert nur bei Instanzen = dll muss geladen werden. –

+0

Und Sie müssen in der Administratorgruppe sein, um es auszuführen. – neves

3

dieser Funktion werden die ntfs Windows-Dateidetails für jede Datei gibt mit Cygwin bash (Ist-r-Klick -properties-info) zum Begriff

Übergeben Sie den Dateipfad an finfo(), kann Unix-Pfad, DOS-Pfad, relativ oder absolut sein. Die Datei wird in einen absoluten Nix-Pfad konvertiert und dann überprüft, ob es sich um eine normale/existierende Datei handelt. Dann in einen absoluten Windows-Pfad konvertiert und an "wmic" gesendet. Dann Magie, Sie haben Windows-Datei-Details direkt im Terminal. Verwendet: Cygwin, Cygpath, sed und awk. Benötigt Windows WMI "wmic.exe", um betriebsbereit zu sein. Die Ausgabe ist für die einfache korrigiert ...

$ 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 "[email protected]")" ]] || { echo "bad-file"; return 1; } 
    echo "$(wmic datafile where name=\""$(echo "$(cygpath -wa "[email protected]")" | sed 's/\\/\\\\/g')"\" get /value)" |\ 
    sed 's/\r//g;s/^M$//;/^$/d' | awk -F"=" '{print $1"=""\033[1m"$2"\033[0m" }' 
} 
+0

FYI das wird zurück Version = #### also filter das mit etwas wie: 'finfo file.dll | awk -F = "'/ Version/{print $ 2}' 'oder' grep Version | cut -d '=' -f 2' Oder besser noch fügen Sie die Funktionalität hinzu, um Optionen zu übergeben. ie 'finfo -V file.dll' – jonretting

+1

Warum runterwinken, wenn Sie nach Cygwin Bash gefragt haben. Hier ist es in Funktionsform, räumt DOS-Bits auf, formatiert es korrekt und liefert "wmic datafile" -Ebeneninformationen für jede Datei, die es erhält. – jonretting

0

und ein Weg mit 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*" 

Ausgabe (eine Zeichenfolge Version hat, die eine kleine neben wmic Methode ist :)):

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 

und ein weitere Verwendung Shell.Application und hybrides batch \ jscript.Her e des 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<splitted.length-1;s++){ 
     if (s==0) { 
      result=splitted[s]; 
     } else { 
      result=result+"\\"+splitted[s]; 
     } 
    } 
    return result; 
} 


getName = function(path){ 
    var splitted=path.split("\\"); 
    return splitted[splitted.length-1]; 
} 
// 

function main(){ 
    if (!ExistsItem(filename)) { 
     WScript.Echo(filename + " does not exist"); 
     WScript.Quit(2); 
    } 
    var fullFilename=getFullPath(filename); 
    var namespace=getParent(fullFilename); 
    var name=getName(fullFilename); 
    var objFolder=objShell.NameSpace(namespace); 
    var objItem=objFolder.ParseName(name); 
    //https://msdn.microsoft.com/en-us/library/windows/desktop/bb787870(v=vs.85).aspx 
    WScript.Echo(fullFilename + " : "); 
    WScript.Echo(objFolder.GetDetailsOf(objItem,-1)); 

} 

main(); 

gegen cmd verwendet.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