2009-03-02 14 views
53

Ho bisogno di uno strumento da riga di comando per scaricare informazioni standard sulla versione di Windows DLL in modo che possa elaborarlo tramite uno script bash (Cygwin).Strumento da riga di comando per eseguire il dump della versione di Windows DLL?

Come sviluppatore Java non sono molto abituato agli strumenti di sviluppo Microsoft (anche se ho un po 'di esperienza con Microsoft Visual Embedded C++ 4.0 e Microsoft Visual Basic 6.0).

Lo strumento appropriato sembra essere mt.exe, come stated on SO. Tuttavia, l'unica possibilità che ho trovato per ottenere questa piccola applicazione è scaricare un ISO da 1,29 GB dello Windows SDK for Windows Server 2008 and .NET Framework. Non posso credere che questo sia l'unico modo per farlo.

Ho trovato anche una piccola applicazione su Internet chiamata PEView, ma mostra troppe informazioni (e inutili nel mio caso) e non è un'applicazione a riga di comando.

Standard objdump in bundle all'interno di Cygwin è inoltre possibile scaricare alcune informazioni sui file DLL, ma non riesco a visualizzare l'opzione per eseguire il dump della versione DLL. Notare che MajorImageVersion, MinorImageVersion e altri campi scaricati da questo strumento (con l'opzione -p) non sono correlati alla propria versione DLL.

Qualche alternativa su cosa fare? Forse ho perso qualche opzione objdump importante? Mt.exe è la mia unica scelta? Se questo è il caso, è possibile ottenerlo separatamente da Windows SDK?

risposta

9

Puoi anche guardare filever.exe, che può essere scaricato come parte del pacchetto Windows XP SP2 Support Tools - solo 4,7 MB di download (o direttamente da here).

+2

che elenca solo la fileversion, non gli altri aspetti della versione. Spesso hai bisogno anche della versione del prodotto. 'sigcheck' (come menziona uvts_cvs) mostra anche quelli, ed è un download molto più piccolo. –

45

È possibile scrivere uno script VBScript per ottenere le informazioni sulla versione del file:

VersionInfo.vbs

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

È possibile chiamare questo dalla riga di comando in questo modo:

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

Sembra fattibile per mezzo di uno script da riga di comando. Grazie –

10

oppure puoi costruirne uno tu stesso. Apri VS, crea una nuova applicazione per console. Crea un progetto semplice senza supporto ATL o MFC, lascia selezionata l'opzione stdafx ma non spuntare 'progetto vuoto' e chiamalo VersionInfo.

Otterrete un semplice progetto con 2 file: VersionInfo.cpp e VersionInfo.h

aprire il file cpp e incollare il seguente in esso, quindi compilare. Sarai in grado di eseguirlo, il primo argomento è il nome file completo, verrà stampato "Prodotto: 5.6.7.8 File: 1.2.3.4" basato sul blocco di risorse Versione. Se non ci sono risorse di versione restituirà -1, altrimenti 0.

Compila un binario 8k utilizzando la dll CRT, 60k con tutto collegato in modo statico (impostato nelle opzioni C++, modifica "Pagina Generazione codice, Opzioni runtime" a "/ MT")

HTH.

PS. Se non si desidera utilizzare Visual Studio, verrà comunque compilato utilizzando qualsiasi compilatore C++ (dita incrociate), ma sarà quasi certamente necessario modificare il #pragma - basta specificare tale lib nelle impostazioni del linker, invece, il pragma solo una scorciatoia per collegarsi automaticamente con quella libreria.


// 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

Non esattamente quello che stavo cercando, ma ancora interessante per sviluppare un piccolo programma per farlo. Grazie. –

+1

no? Quali informazioni sulla versione volevi? AFAIK Windows ha solo informazioni sulla versione memorizzate nei blocchi di risorse: queste sono le cose che vedi quando apri le proprietà in explorer. – gbjbaanb

+1

Bravo! Mi piace anche sviluppare ruote :) – divinci

55

Usa Microsoft Sysinternals Sigcheck. uscite Questo esempio solo la versione:

sigcheck -q -n foo.dll 

sigcheck.exe disimballato solo 228 KB.

+3

349 KB cinque anni dopo ... ne vale la pena? ;) – Ben

1

V'è una domanda riga di comando chiamato "ShowVer" a CodeProject:

ShowVer.exe command-line VERSIONINFO display program

Come al solito l'applicazione è dotata di un exe e il codice sorgente (VisualC++ 6).

Out uscite tutti i meta-dati disponibili:

Su un sistema Win7 tedesco l'uscita per user32.dll è come questo:

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

È possibile utilizzare PowerShell per ottenere le informazioni desiderate.

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

Di default questo verrà visualizzato ProductVersion e FileVersion Ma la piena VERSIONINFO è disponibile. Cioè per tornare Commenti

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

Questa dovrebbe essere la risposta. È l'unica risposta che non si basa su strumenti predefiniti. –

+7

Da pipe a fl * per ottenere tutte le proprietà VersionInfo: PS C: \> (Get-Item C: \ Windows \ System32 \ WindowsPowerShell \ v1.0 \ powershell.exe) .VersionInfo | fl * – Glenn

+0

Usando questo ho ottenuto 0 per il numero di versione e false per tutte le proprietà Is *. – NobleUplift

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

Funziona solo su instance = dll deve essere caricato. –

+0

E devi essere nel gruppo Administrator per eseguirlo. – neves

3

Questa funzione restituisce i NTFS di Windows dettagli di file per qualsiasi file usando Cygwin bash (attuale R-CLICK -proprietà-informazioni) al termine

Passare il percorso dei file a finfo(), può essere percorso unix, percorso dos, relativo o assoluto. Il file viene convertito in un percorso assoluto nix, quindi controllato per vedere se è in realtà un file normale/esistente. Quindi convertito in un percorso di Windows assoluto e inviato a "wmic". Quindi magia, hai i dettagli del file di Windows direttamente nel terminale. Usi: cygwin, cygpath, sed e awk. È necessario che WMI di Windows "wmic.exe" sia operativo. L'uscita viene corretta per un facile ...

$ 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 questo wil restituisce Version = #### quindi basta filtrare con qualcosa del tipo: 'finfo file.dll | awk -F "=" '/ Version/{print $ 2}' 'o' grep Version | cut -d '=' -f 2' O meglio ancora aggiungi la funzionalità per passare le opzioni. cioè 'finfo -V file.dll' – jonretting

+1

Perché downvotare quando op ha chiesto Cygwin bash. Qui è in forma di funzione, pulisce i bit dos, lo formatta correttamente e fornisce informazioni di livello "wmic datafile" per qualsiasi file fornito. – jonretting

0

e un modo con 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*" 

esempio uscita (ha una versione stringa che è una piccola aggiunta al metodo 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 uno più Utilizzando Shell.Application in lotti e ibrido \ jscript.Her di e 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(); 

usato contro 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