我需要一个命令行工具来转储标准的Windows DLL版本信息,以便我可以通过bash脚本(Cygwin)处理它。
作为一名Java开发人员,我不太熟悉Microsoft开发工具(尽管我对Microsoft Visual Embedded C ++ 4.0和Microsoft Visual Basic 6.0有一点经验。)
相应的工具似乎是mt.exe,stated on SO。然而,我发现获得这个小应用程序的唯一机会是下载Windows SDK for Windows Server 2008 and .NET Framework的1.29 GB ISO。我无法相信这是唯一的方法。
我还在互联网上找到了一个名为PEView的小应用程序,但它显示的信息太多(在我的情况下无用),而且它不是命令行应用程序。
Cygwin中捆绑的标准objdump也可以转储有关DLL文件的一些信息,但我看不到转储DLL版本的选项。请注意,此工具转储的MajorImageVersion,MinorImageVersion和其他字段(使用-p选项)与自己的DLL版本无关。
关于该怎么做的任何替代方案?也许我错过了一些重要的objdump选项? mt.exe是我唯一的选择吗?如果是这种情况,是否可以单独从Windows SDK获取它?
答案 0 :(得分:99)
您可以使用PowerShell获取所需的信息。
(Get-Item C:\Path\To\MyFile.dll).VersionInfo
默认情况下,这将显示ProductVersion和FileVersion 但是完整的VERSIONINFO可用。即返回评论
(Get-Item C:\Path\To\MyFile.dll).VersionInfo.Comments
答案 1 :(得分:58)
答案 2 :(得分:46)
您可以编写VBScript脚本来获取文件版本信息:
<强> VersionInfo.vbs 强>
set args = WScript.Arguments
Set fso = CreateObject("Scripting.FileSystemObject")
WScript.Echo fso.GetFileVersion(args(0))
Wscript.Quit
您可以从命令行中调用此方法:
cscript //nologo VersionInfo.vbs C:\Path\To\MyFile.dll
答案 3 :(得分:10)
您还可以查看filever.exe,它可以作为Windows XP SP2 Support Tools包的一部分下载 - 仅下载4.7MB。
答案 4 :(得分:10)
或者你可以自己建造一个。打开VS,创建一个新的控制台应用程序。创建一个没有ATL或MFC支持的简单项目,保持选中stdafx选项但不检查'empty project'并将其命名为VersionInfo。
您将获得一个包含2个文件的简单项目:VersionInfo.cpp和VersionInfo.h
打开cpp文件并将以下内容粘贴到其中,然后进行编译。你将能够运行它,第一个参数是完整的文件名,它将根据版本资源块打印出“产品:5.6.7.8文件:1.2.3.4”。如果没有版本资源,它将返回-1,否则返回0。
使用dll CRT编译为8k二进制文件,静态链接的所有内容为60k(在C ++选项中设置,将“代码生成页面,运行时选项”更改为“/ MT”)
HTH。
PS。如果您不想使用Visual Studio,它仍然可以使用任何c ++编译器进行编译(手指交叉),但您几乎肯定必须更改#pragma - 只需在链接器设置中指定lib,pragma的只是一个自动链接到该库的简写。
// 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;
}
答案 5 :(得分:10)
C:\>wmic datafile where name="C:\\Windows\\System32\\kernel32.dll" get version
Version
6.1.7601.18229
答案 6 :(得分:3)
Systernals的listdlls工具可以完成这项工作:http://technet.microsoft.com/en-us/sysinternals/bb896656.aspx
listdlls -v -d mylib.dll
答案 7 :(得分:3)
此函数返回使用Cygwin bash(实际r-click-properties-info)到术语
的任何文件的ntfs Windows文件详细信息将文件路径传递给finfo(),可以是unix路径,dos路径,相对或绝对路径。该文件将转换为绝对nix路径,然后检查它是否实际上是常规/现有文件。然后转换为绝对的Windows路径并发送到“wmic”。然后魔法,你在终端有Windows文件的详细信息。用途:cygwin,cygpath,sed和awk。需要Windows WMI“wmic.exe”才能运行。输出已经过修正,很容易......
$ 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" }'
}
答案 8 :(得分:3)
使用Powershell可以使用以下命令从任何dll或exe获取Version字符串,即2.3.4
(Get-Item "C:\program files\OpenVPN\bin\openvpn.exe").VersionInfo.ProductVersion
在Windows 10上测试
答案 9 :(得分:1)
在CodeProject上有一个名为“ShowVer”的命令行应用程序:
ShowVer.exe command-line VERSIONINFO display program
像往常一样,应用程序附带了exe和源代码(VisualC ++ 6)。
Out输出所有可用的元数据:
在德国Win7系统上,user32.dll的输出如下:
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
答案 10 :(得分:0)
和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*"
示例输出(它有一个字符串版本,这是对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
还有一个使用 shell.application 和混合批处理\ jscript.Here的 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();
用于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
答案 11 :(得分:0)
对于某些DLL,我在.rsrc中使用objdump
手动找到了版本信息。使用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.............