Strumento da riga di comando per scaricare la versione di Windows DLL?

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).

Come sviluppatore Java non sono molto abituato agli strumenti di sviluppo di 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 indicato su SO . Tuttavia, l’unica possibilità che ho trovato per ottenere questa piccola applicazione è scaricare un ISO da 1,29 GB di Windows SDK per Windows Server 2008 e .NET Framework . Non posso credere che questo sia l’unico modo per farlo.

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

L’ objdump standard in bundle all’interno di Cygwin può anche scaricare alcune informazioni sui file DLL, ma non riesco a vedere 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, è ansible ottenerlo separatamente da Windows SDK?

Puoi anche guardare filever.exe, che può essere scaricato come parte del pacchetto Strumenti di supporto di Windows XP SP2 : solo 4,7 MB di download.

È ansible utilizzare PowerShell per ottenere le informazioni desiderate.

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

Per impostazione predefinita, questo mostrerà ProductVersion e FileVersion. Ma il VERSIONINFO completo è disponibile. Vale a dire per restituire i commenti

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

Utilizzare Microsoft Sysinternals Sigcheck . Questo esempio mostra solo la versione:

 sigcheck -q -n foo.dll 

Sigcheck.exe decompresso è solo 228 KB.

È ansible 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 

Puoi chiamare questo dalla riga di comando in questo modo:

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

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.

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

Apri il file cpp e incolla quanto segue, quindi compila. 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.

Compilare ad un binario 8k usando la dll CRT, 60k con tutto collegato staticamente (impostato nelle opzioni C ++, cambia “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  #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 

Gli strumenti di listdll di Systernals potrebbero eseguire il lavoro: http://technet.microsoft.com/en-us/sysinternals/bb896656.aspx

 listdlls -v -d mylib.dll 

Questa funzione restituisce i dettagli del file NT di Windows per qualsiasi file utilizzando Cygwin bash (effettivo r-click-properties-info) al termine

Passa il percorso dei file a finfo (), può essere unix path, dos path, 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’output è corretto per 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" }' } 

C’è un’applicazione a riga di comando chiamata “ShowVer” in CodeProject:

Programma di visualizzazione VERSIONINFO della riga di comando ShowVer.exe

Come al solito l’applicazione viene fornita con un exe e il codice sorgente (VisualC ++ 6).

Out restituisce tutti i metadati disponibili:

Su un sistema tedesco Win7 l’output per user32.dll è simile al seguente:

 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 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 di output (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 un’altra ancora Usando shell.application e il batch ibrido \ jscript. Ecco 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 

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 

Usando Powershell è ansible ottenere solo la stringa Version, ovvero 2.3.4 da qualsiasi dll o exe con il seguente comando

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

Testato su Windows 10