在 Windows 10 之前,可以通过右键单击文件并执行属性来获取所有字符串VersionInfo
。现在这行不通了。就好像有人决定只显示几十年来获得标准含义的字符串。但 GUI 并不重要,除非注意到它不起作用,因此对属性页的 COM 调用不会有帮助。无论如何,我们想知道如何从命令行进行操作。
尝试过:
PS> get-childitem .\execautablename | FormatList VersionInfo
PS> (get-item .\execautablename | format-list -force)
PS> get-childitem .\execautablename | ? {$_.VersionInfo.Xyz}
cmd> wmic datafile where Name="C:\\Full\\Path\\to\\executablename.exe" list full
第三个命令只能获取一些版本字符串,但不能获取我知道的其他版本字符串。
就像现在所有的方法都知道一个“标准”列表(关于标准列表有两种或三种想法),但它们都不知道如何枚举所有 VersionInfo 字符串。我有一个二进制文件,其中包含字符串“ProductHash”,这是用于编译它的相应源代码的 git 提交哈希。
我不断得到涉及的答案{$_.VersionInfo}
。这条路永远不会奏效,因为VersionInfo
相信要检索的版本信息属性的固定列表。rc
编译器和VERSIONINFO
PE 结构相信不同。而 wmic 有一个不同的它检索的固定列表。
这是属性。它只在应用 Fish 的VersInfoEx 外壳扩展链接自发帖。
源码片段(Windows 资源):
#include <windows.h>
1 VERSIONINFO
FILEVERSION 10, 0, 0, 0
PRODUCTVERSION 10, 0, 0, 0
FILEFLAGSMASK 0
FILEFLAGS 0
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_APP
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904E4"
BEGIN
VALUE "FileDescription", "Hello RC"
VALUE "FileVersion", "10.0.0.0"
VALUE "LegalCopyright", "Copyright (C) Cedaron Medical, Inc. 2018"
VALUE "InternalName", "hellorc"
VALUE "ProductHash", "Hello_World_abcdefgh" /* this is the value I'm after */
VALUE "ProductName", "Hello RC"
VALUE "ProductVersion", "10.0.0.0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1252
END
END
我得到了一个真正可怕且令人不满意的答案,它对 VERSIONINFO 一无所知,并且以兆字节为单位读取文件,并且依赖于太多正在安装的内容。
cmd> c:\cygwin64\bin\tr -d \0 < filename.exe | c:\cygwin64\bin\strings | c:\cygwin64\bin\grep ^^ProductHash. | c:\cygwin64\bin\sed s/ProductHash//
只要被搜索的 VERSIONINFO 字符串名称不在二进制文件中的其他地方,这种方法就有效。我希望一个糟糕的答案足以更好地解释这个问题。
尝试按照 Pimp Juice IT 的建议使用 powershell 做同样的事情,但没有成功:
PS> Get-Content ".\executablename.exe" | % { if($_ -match "ProductHash") { write-host $_}}
PS>
它与可行的想法非常接近,因此我能够确定它为什么没有输出。我将 cygwintr
重新放入管道中,命令运行了很长时间,我以为它挂了,但最终我得到了一些输出。
PS> Get-Content ".\executablename.exe" | c:\cygwin64\bin\tr.exe -d \0 | % { if($_ -match "ProductHash") { write-host $_}}
InternalNameexecutablenameh$ProductNameMyProductPProductVersion10.0.591.927r)ProductHash50acd7cedb99dddab69c5de9b2f021ef72d64ca0DVarFileInfo$Translation ????<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
PS>
我已经制作了一个最小的二进制文件你好.zip(1313 字节,解压后为 4096 字节)。版本信息键“ProductHash”的值为“Hello_World_abcdefgh”。
不要被欺骗。ProductHash 不是二进制文件的哈希值。它是源代码存储库中的哈希键,用于查找二进制文件编译的源代码。这个想法是,如果有人最终得到一些奇怪的版本,我们可以追踪它并确定他们拥有的确切代码。我们宁愿向他们发送一个小命令来从中获取值,而不是让客户向我们发送一个大文件。
答案1
最终工作解决方案逻辑
该脚本考虑了 versioninfo 结构的实际布局,并使用一个额外参数(靠近末尾的 1 或 2)来对输入字符串进行奇偶校验。
$versioninfostate = 0
(Get-Content "hello.exe" -Encoding Unicode) -split {$_ -lt " "} | % { if ($versioninfostate -eq 1) { write-host $_ } if ($versioninfostate -gt 0) { $versioninfostate = $versioninfostate - 1} if ($_ -match "ProductHash$") { $versioninfostate = 2 }}
最终解决方案路径的开发
- “最后一条命令只能获取部分版本字符串,但无法获取其他我知道的版本字符串”
使用
Select *
获取未显示的附加属性Format-List
- “从 .exe 文件中获取所有 VersionInfo 字符串”
将 exe 管道传输到要
% {$_.VersionInfo}
使用的目录Foreach-Object
,而不是Where-Object
只$_.VersionInfo
关注一个列表/记录集中的属性- “无法解析任意属性名称”
- “根据您的最新更新,您安装了某人在评论中向您推荐的第三方实用程序;该软件似乎是 2010 年的,专为 Windows 7 设计。无论如何,它似乎添加了一个附加属性,
ProductHash
如您最新的更新屏幕截图所示。”
然后使用
Get-FileHash
这种方式明确获取 exe 的哈希值
下面是一些 PowerShell 逻辑...
- 使用
%
而不是?
将可执行文件通过Foreach 对象而不是Where-Object
- 使用
Select *
而不是Format-List
确保变量对象是System.Object
基类而不是像创建的System.Array
那样Format-List
VersionInfo
使用您从列表中指定的显式属性值设置变量- 用途获取文件哈希获取 exe 哈希值
电源外壳
$t = get-childitem ".\executablename" | % {$_.VersionInfo} | Select *
$Hash = (Get-FileHash $Exe).Hash
$t.<Property>, $Hash
输出示例
Coolest - www.CoolTool.com
30E14E358DD76EC712CCC6B5FD1E79DDEAA653E682E968DA0229BE13BED2B991
VersionInfo 列表对象
PS C:\WINDOWS\system32> get-childitem ".\executablename" | % {$_.VersionInfo} | Select *
FileVersionRaw : 1.80.0.0
ProductVersionRaw : 1.80.0.0
Comments :
CompanyName : Coolest - www.CoolTool.com
FileBuildPart : 0
FileDescription : Program - Cool memory analyzer
FileMajorPart : 1
FileMinorPart : 80
FileName : C:\Users\User\Desktop\Coolio.exe
FilePrivatePart : 0
FileVersion : 1.80
InternalName : TooCool
IsDebug : False
IsPatched : False
IsPrivateBuild : False
IsPreRelease : False
IsSpecialBuild : False
Language : English (United States)
LegalCopyright : Copyright © 1985-2099 Michael Jordan
LegalTrademarks :
OriginalFilename : Coolio
PrivateBuild :
ProductBuildPart : 0
ProductMajorPart : 1
ProductMinorPart : 80
ProductName : TooCool
ProductPrivatePart : 0
ProductVersion : 1.80
SpecialBuild :
搜索二进制字符串内容
笔记: 就像cygwin
cli string
、grep
和其他命令搜索文件的二进制文件以匹配字符串一样"ProductHash"
,您也可以从类似的 PowerShell 命令中读取它。
$Match = (Get-Content ".\executablename") -replace "`0", "" | % {if($_ -match "(ProductHash)") {$Matches[0]}}
$Line = (Get-Content ".\executablename") -replace "`0", "" | % {if($_ -match "(ProductHash)") {$_}} | % {if($_ -match "(ProductHash).*$") {$Matches[0]}}
$Line = $Line -replace "[\W]", "`r`n" | % {if($_ -match "(ProductHash).*\s") {$Matches[0]}}
$MisMatch = $Line.Replace($Match, "")
Write-Output "$Match`: $MisMatch"
示例输出
ProductHash: Hello_World_abcdefgh2
更多资源
答案2
我刚刚在可执行文件上执行了此操作,并在“详细信息”选项卡上看到了版本信息。所以,我有点不明白你的意思。
此 PS 方法也记录在此处:
在我的 Win10 客户端上
(Get-CimInstance -CimInstance Win32_OperatingSystem).Caption
Microsoft Windows 10 Pro
$PSVersionTable
Name Value
---- -----
PSVersion 5.1.17134.228
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0, 5.0, 5.1.17134.228}
BuildVersion 10.0.17134.228
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
(Get-Item -Path 'F:\Downloads\WindowsAzureADRightsManagementAdministration_x64.exe').VersionInfo | Format-List -Force
OriginalFilename : setup.exe
FileDescription : Software Installer
ProductName : Windows Azure AD Rights Management Administration
Comments :
CompanyName : Microsoft Corporation
FileName : F:\Downloads\WindowsAzureADRightsManagementAdministration_x64.exe
FileVersion : 1.0.594.1
ProductVersion : 1.0.594.1
IsDebug : False
IsPatched : False
IsPreRelease : False
IsPrivateBuild : False
IsSpecialBuild : False
Language : English (United States)
LegalCopyright : Copyright (c) Microsoft Corporation. All rights reserved.
LegalTrademarks : Microsoft and Windows are either registered trademarks or trademarks of Microsoft Corporation in the U.S. and/or other countries.
PrivateBuild : **************************************
SpecialBuild :
FileVersionRaw : 1.0.594.1
ProductVersionRaw : 1.0.594.1
答案3
Firefox.exe 有一个特殊的资源:建筑编号.Java.exe还有一个特殊的Resource:完整版。
Powershell 的 FileVersion 无法解析这些。
谢谢 @呕吐 - Chunky Mess 风格命令,我可以获得版本号。
在CMD上;
对于 Firefox.exe:
powershell -c "(Get-Content 'Firefox.exe' -Encoding Unicode) -split {$_ -lt ' '} | % { if ($versioninfostate -eq 1) { write-host $_ } if ($versioninfostate -gt 0) { $versioninfostate = $versioninfostate - 1} if ($_ -match 'BuildID$') { $versioninfostate = 2 } }"
对于 Java.exe:
powershell -c "(Get-Content 'java.exe' -Encoding Unicode) -split {$_ -lt '-'} | % { if ($versioninfostate -eq 1) { write-host $_ } if ($versioninfostate -gt 0) { $versioninfostate = $versioninfostate - 1} if ($_ -match 'Full Version$') { $versioninfostate = 1 } }"