问题
I need a command line tool to dump standard Windows DLL version info so I can process it by means of a bash script (Cygwin).
As a Java developer I am not very used to Microsoft development tools (though I have a little bit of experience with Microsoft Visual Embedded C++ 4.0 and Microsoft Visual Basic 6.0).
The appropriate tool seems to be mt.exe, as stated on SO. However the only chance I have found to get this little application is to download a 1.29 GB ISO of the Windows SDK for Windows Server 2008 and .NET Framework. I can not believe this is the only way to do it.
I have also found a little application on the Internet called PEView, but it displays too much (and useless in my case) information and it is not a command line application.
Standard objdump bundled inside Cygwin can also dump some information about the DLL files, but I can not see the option to dump DLL version. Note that MajorImageVersion, MinorImageVersion and other fields dumped by this tool (with -p option) are not related to own DLL version.
Any alternatives about what to do? Maybe I missed some important objdump option? Is mt.exe my only choice? If this is the case, is it possible to get it separately from Windows SDK?
回答1:
You can also look at filever.exe, which can be downloaded as part of the Windows XP SP2 Support Tools package - only 4.7MB of download.
回答2:
You can use PowerShell to get the information you want.
(Get-Item C:\Path\To\MyFile.dll).VersionInfo
By default this will display ProductVersion and FileVersion But the full VERSIONINFO is available. I.e. to return Comments
(Get-Item C:\Path\To\MyFile.dll).VersionInfo.Comments
回答3:
Use Microsoft Sysinternals Sigcheck. This sample outputs just the version:
sigcheck -q -n foo.dll
Unpacked sigcheck.exe is only 228 KB.
回答4:
You can write a VBScript script to get the file version info:
VersionInfo.vbs
set args = WScript.Arguments
Set fso = CreateObject("Scripting.FileSystemObject")
WScript.Echo fso.GetFileVersion(args(0))
Wscript.Quit
You can call this from the command line like this:
cscript //nologo VersionInfo.vbs C:\Path\To\MyFile.dll
回答5:
C:\>wmic datafile where name="C:\\Windows\\System32\\kernel32.dll" get version
Version
6.1.7601.18229
回答6:
or you can build one yourself. Open VS, create a new console application. Create a simple project with no ATL or MFC support, leave the stdafx option checked but do not check 'empty project' and call it VersionInfo.
You'll get a simple project with 2 files: VersionInfo.cpp and VersionInfo.h
Open the cpp file and paste the following into it, then compile. You'll be able to run it, first argument is the full filename, it'll print out "Product: 5.6.7.8 File: 1.2.3.4" based on the Version resource block. If there's no version resource it'll return -1, otherwise 0.
Compiles to an 8k binary using the dll CRT, 60k with everything linked statically (set in the C++ options, change "Code Generation page, Runtime options" to "/MT")
HTH.
PS. If you don't want to use Visual Studio, it'll still compile using any c++ compiler (fingers crossed), but you'll almost certainly have to change the #pragma - just specify that lib in the linker settings instead, the pragma's just a shorthand to automatically link with that library.
// 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;
}
回答7:
The listdlls tools from Systernals might do the job: http://technet.microsoft.com/en-us/sysinternals/bb896656.aspx
listdlls -v -d mylib.dll
回答8:
This function returns the ntfs Windows file details for any file using Cygwin bash (actual r-click-properties-info) to the term
Pass the files path to finfo(), can be unix path, dos path, relative or absolute. The file is converted into an absolute nix path, then checked to see if it is in-fact a regular/existing file. Then converted into an absolute windows path and sent to "wmic". Then magic, you have windows file details right in the terminal. Uses: cygwin, cygpath, sed, and awk. Needs Windows WMI "wmic.exe" to be operational. The output is corrected for easy...
$ 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" }'
}
回答9:
Using Powershell it is possible to get just the Version string, i.e. 2.3.4 from any dll or exe with the following command
(Get-Item "C:\program files\OpenVPN\bin\openvpn.exe").VersionInfo.ProductVersion
Tested on Windows 10
回答10:
There is an command line application called "ShowVer" at CodeProject:
ShowVer.exe command-line VERSIONINFO display program
As usual the application comes with an exe and the source code (VisualC++ 6).
Out outputs all the meta data available:
On a German Win7 system the output for user32.dll is like this:
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
回答11:
and one way with 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*"
example output (it has a string version which is a small addition to wmic method :) ):
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
and one more Using shell.application and hybrid batch\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<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();
used against 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
回答12:
For some DLLs I found version info manually with objdump
in .rsrc. With objdump -s -j .rsrc zlib1.dll
:
zlib1.dll: file format pei-x86-64
Contents of section .rsrc:
62e9e000 00000000 00000000 00000000 00000100 ................
62e9e010 10000000 18000080 00000000 00000000 ................
62e9e020 00000000 00000100 01000000 30000080 ............0...
62e9e030 00000000 00000000 00000000 00000100 ................
62e9e040 09040000 48000000 58e00100 34030000 ....H...X...4...
62e9e050 00000000 00000000 34033400 00005600 ........4.4...V.
62e9e060 53005f00 56004500 52005300 49004f00 S._.V.E.R.S.I.O.
62e9e070 4e005f00 49004e00 46004f00 00000000 N._.I.N.F.O.....
62e9e080 bd04effe 00000100 02000100 00000b00 ................
62e9e090 02000100 00000b00 3f000000 00000000 ........?.......
62e9e0a0 04000000 02000000 00000000 00000000 ................
62e9e0b0 00000000 94020000 01005300 74007200 ..........S.t.r.
62e9e0c0 69006e00 67004600 69006c00 65004900 i.n.g.F.i.l.e.I.
62e9e0d0 6e006600 6f000000 70020000 01003000 n.f.o...p.....0.
62e9e0e0 34003000 39003000 34004500 34000000 4.0.9.0.4.E.4...
62e9e0f0 64001e00 01004600 69006c00 65004400 d.....F.i.l.e.D.
62e9e100 65007300 63007200 69007000 74006900 e.s.c.r.i.p.t.i.
62e9e110 6f006e00 00000000 7a006c00 69006200 o.n.....z.l.i.b.
62e9e120 20006400 61007400 61002000 63006f00 .d.a.t.a. .c.o.
62e9e130 6d007000 72006500 73007300 69006f00 m.p.r.e.s.s.i.o.
62e9e140 6e002000 6c006900 62007200 61007200 n. .l.i.b.r.a.r.
62e9e150 79000000 2e000700 01004600 69006c00 y.........F.i.l.
62e9e160 65005600 65007200 73006900 6f006e00 e.V.e.r.s.i.o.n.
62e9e170 00000000 31002e00 32002e00 31003100 ....1...2...1.1.
62e9e180 00000000 34000a00 01004900 6e007400 ....4.....I.n.t.
62e9e190 65007200 6e006100 6c004e00 61006d00 e.r.n.a.l.N.a.m.
62e9e1a0 65000000 7a006c00 69006200 31002e00 e...z.l.i.b.1...
62e9e1b0 64006c00 6c000000 7c002c00 01004c00 d.l.l...|.,...L.
62e9e1c0 65006700 61006c00 43006f00 70007900 e.g.a.l.C.o.p.y.
62e9e1d0 72006900 67006800 74000000 28004300 r.i.g.h.t...(.C.
62e9e1e0 29002000 31003900 39003500 2d003200 ). .1.9.9.5.-.2.
62e9e1f0 30003100 37002000 4a006500 61006e00 0.1.7. .J.e.a.n.
62e9e200 2d006c00 6f007500 70002000 47006100 -.l.o.u.p. .G.a.
62e9e210 69006c00 6c007900 20002600 20004d00 i.l.l.y. .&. .M.
62e9e220 61007200 6b002000 41006400 6c006500 a.r.k. .A.d.l.e.
62e9e230 72000000 3c000a00 01004f00 72006900 r...<.....O.r.i.
62e9e240 67006900 6e006100 6c004600 69006c00 g.i.n.a.l.F.i.l.
62e9e250 65006e00 61006d00 65000000 7a006c00 e.n.a.m.e...z.l.
62e9e260 69006200 31002e00 64006c00 6c000000 i.b.1...d.l.l...
62e9e270 2a000500 01005000 72006f00 64007500 *.....P.r.o.d.u.
62e9e280 63007400 4e006100 6d006500 00000000 c.t.N.a.m.e.....
62e9e290 7a006c00 69006200 00000000 32000700 z.l.i.b.....2...
62e9e2a0 01005000 72006f00 64007500 63007400 ..P.r.o.d.u.c.t.
62e9e2b0 56006500 72007300 69006f00 6e000000 V.e.r.s.i.o.n...
62e9e2c0 31002e00 32002e00 31003100 00000000 1...2...1.1.....
62e9e2d0 78003000 01004300 6f006d00 6d006500 x.0...C.o.m.m.e.
62e9e2e0 6e007400 73000000 46006f00 72002000 n.t.s...F.o.r. .
62e9e2f0 6d006f00 72006500 20006900 6e006600 m.o.r.e. .i.n.f.
62e9e300 6f007200 6d006100 74006900 6f006e00 o.r.m.a.t.i.o.n.
62e9e310 20007600 69007300 69007400 20006800 .v.i.s.i.t. .h.
62e9e320 74007400 70003a00 2f002f00 77007700 t.t.p.:././.w.w.
62e9e330 77002e00 7a006c00 69006200 2e006e00 w...z.l.i.b...n.
62e9e340 65007400 2f000000 44000000 01005600 e.t./...D.....V.
62e9e350 61007200 46006900 6c006500 49006e00 a.r.F.i.l.e.I.n.
62e9e360 66006f00 00000000 24000400 00005400 f.o.....$.....T.
62e9e370 72006100 6e007300 6c006100 74006900 r.a.n.s.l.a.t.i.
62e9e380 6f006e00 00000000 0904e404 00000000 o.n.............
来源:https://stackoverflow.com/questions/602802/command-line-tool-to-dump-windows-dll-version