用于转储Windows DLL版本的命令行工具?

74
我需要一个命令行工具来转储标准的Windows DLL版本信息,以便我可以通过bash脚本(Cygwin)进行处理。
作为一名Java开发人员,我不太习惯使用Microsoft开发工具(尽管我有一点使用Microsoft Visual Embedded C++ 4.0和Microsoft Visual Basic 6.0的经验)。
适当的工具似乎是mt.exe,如SO上所述。然而,我找到的唯一获取这个小应用程序的机会是下载一个1.29 GB的Windows Server 2008和.NET Framework的Windows SDK ISO。我无法相信这是唯一的方法。
我还在互联网上找到了一个叫做PEView的小应用程序,但它显示了太多(在我的情况下无用)的信息,并且它不是一个命令行应用程序。
Cygwin中捆绑的标准objdump也可以转储有关DLL文件的一些信息,但我看不到转储DLL版本的选项。请注意,此工具(使用-p选项)转储的MajorImageVersion、MinorImageVersion和其他字段与自己的DLL版本无关。

有没有其他替代方案?也许我错过了一些重要的objdump选项?mt.exe是我的唯一选择吗?如果是这样,是否可以从Windows SDK单独获取它?

13个回答

137
你可以使用PowerShell获取所需信息。
(Get-Item C:\Path\To\MyFile.dll).VersionInfo

默认情况下,这将显示ProductVersion和FileVersion。但是完整的VERSIONINFO可用。例如,返回Comments。
(Get-Item C:\Path\To\MyFile.dll).VersionInfo.Comments

8
这应该是答案。它是唯一一个不依赖于现成工具的答案。 - V Maharajh
13
使用管道操作符“|”将所有的VersionInfo属性输出到fl命令中:PS C:> (Get-Item C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe).VersionInfo | fl * - Glenn
使用这个方法,我得到了版本号为0和所有Is*属性都为false。 - NobleUplift
4
普通批处理文件中的命令:powershell -command (Get-Item C:\Path\To\MyFile.dll).VersionInfo - Stefan Bormann
那并没有提供完整的版本信息。例如,对于我来说,c:\windows\system32\termsrv.dll 的版本是10.0.18362.657,可以通过右键单击文件并转到属性来查看,或者将鼠标悬停在上面。而(Get-Item C:\Path\To\MyFile.dll).VersionInfo只显示10.0.18362.1。我可以尝试Glenn的建议,但它会显示更多信息。 - barlop

63

8
五年后的 349 KB,仍值得吗? ;) - Ben
1
2021年x86版本为811 KB,x64版本为1121 KB。我在想它何时才能达到10 MB :) - Alexander Malakhov

48

您可以编写一个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

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

1
你必须在管理员组中才能运行它。 - neves

10
或者您可以自己构建一个。打开Visual Studio,创建一个新的控制台应用程序。创建一个简单的项目,不要使用ATL或MFC支持,保留stdafx选项的勾选状态,但是不要勾选“空项目”,并将其命名为VersionInfo。
您将得到一个包含2个文件的简单项目:VersionInfo.cpp和VersionInfo.h。
打开cpp文件并将以下内容粘贴到其中,然后进行编译。您将能够运行它,第一个参数是完整的文件名,它将基于版本资源块打印出“Product: 5.6.7.8 File: 1.2.3.4”。如果没有版本资源,则它将返回-1,否则返回0。
使用dll CRT编译为8k二进制文件,使用静态链接时为60k(在C++选项中设置,“代码生成页面,运行时选项”更改为“/MT”)
希望对你有帮助。
PS. 如果您不想使用Visual Studio,它仍然可以使用任何C++编译器进行编译(手指交叉),但您几乎肯定需要更改#pragma - 只需在链接器设置中指定该库即可,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;
}

虽然不完全符合我的期望,但是开发一个小程序来实现这个功能还是很有趣的。谢谢。 - Fernando Miguélez
1
不是?您想要哪个版本信息?据我所知,Windows只在资源块中存储版本信息 - 这些是您在资源管理器中打开属性时看到的内容。 - gbjbaanb
1
太棒了!我也喜欢开发轮子 :) - divinci

9

3
该命令只列出文件版本,而不包括其他版本信息。通常你也需要产品版本信息。如uvts_cvs所提到的,sigcheck可以显示这些信息,并且它的下载文件要小得多。 - Jeroen Wiert Pluimers
"这里"的链接已损坏。 - youcantexplainthat
这是一件好事。我不确定是谁添加的,但我永远不会建议人们从互联网上的随机位置下载可执行文件... :-) - Franci Penov
2
@FranciPenov,你可以在编辑历史记录中查看是谁添加了那个链接(不是我,也不是你),但是没有什么神秘的,你可以检查一下。但无论如何,值得注意的是,该链接现在指向 microsoft.com,而不是一个随机的地方。并且该微软链接有效。 - barlop

5

使用Powershell可以通过以下命令从任何dll或exe文件中获取版本号字符串,例如2.3.4:

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

在Windows 10上进行测试


3

2
该函数使用Cygwin bash(实际上是右键属性信息)返回任何文件的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" }'
}

FYI,这将返回 Version=####,所以只需使用类似于“finfo file.dll | awk -F"=" '/Version/ {print $2}'”或“grep Version | cut -d '=' -f 2”之类的方法过滤掉它。或者更好的是添加传递选项的功能。即“finfo -V file.dll”。 - jonretting
1
当 OP 要求 Cygwin bash 时,为什么要踩他呢?这里是函数形式,清理 DOS 位,正确格式化,并为给定的任何文件提供“wmic datafile”级别的信息。 - jonretting

2

对于一些DLL,我使用objdump.rsrc中手动查找版本信息。使用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.............


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接