如何从PowerShell中的.dll或.exe文件获取版本信息?
我对File Version特别感兴趣,尽管其他版本信息(即Company,Language,Product Name等)也将有所帮助。
现在,您可以从Get-Item或Get-ChildItem获取FileVersionInfo,但是它将显示出厂产品的原始FileVersion,而不是更新的版本。例如:
1
| (Get-Item C:\Windows\System32\Lsasrv.dll).VersionInfo.FileVersion |
有趣的是,您可以使用以下命令获取更新的(已修补的)ProductVersion:
1
| (Get-Command C:\Windows\System32\Lsasrv.dll).Version |
我对"原始"和"修补"之间的区别基本上是由于FileVersion的计算方式(请参阅此处的文档)。从Vista基本上开始,Windows API GetFileVersionInfo会从语言中性文件(exe / dll)查询部分版本信息,并从特定于语言的mui文件中查询非固定部分(每次文件更改时不会更新) )。
因此,对于lsasrv之类的文件(由于SSL / TLS / RDS中的安全性问题,该文件已在2014年11月被替换),这两个命令报告的版本(至少在该日期之后的一段时间内)有所不同,第二个命令是更多"正确"版本。
但是,尽管在LSASrv中是正确的,但ProductVersion和FileVersion可能会有所不同(实际上很常见)。因此,直接从装配文件中获取更新的Fileversion的唯一方法是从零件中自行构建它,如下所示:
1
| Get-Item C:\Windows\System32\Lsasrv.dll | ft FileName, File*Part |
或者从中提取数据:
1
| [System.Diagnostics.FileVersionInfo]::GetVersionInfo($this.FullName) |
您可以通过在PowerShell中更新TypeData轻松地将其添加到所有FileInfo对象:
1 2 3 4 5
| Update-TypeData -TypeName System.IO.FileInfo -MemberName FileVersion -MemberType ScriptProperty -Value {
[System.Diagnostics.FileVersionInfo]::GetVersionInfo($this.FullName) | % {
[Version](($_.FileMajorPart, $_.FileMinorPart, $_.FileBuildPart, $_.FilePrivatePart)-join".")
}
} |
现在,每次执行Get-ChildItem或Get-Item时,都有一个FileVersion属性,该属性显示更新的FileVersion ...
由于PowerShell可以调用.NET类,因此您可以执行以下操作:
1
| [System.Diagnostics.FileVersionInfo]::GetVersionInfo("somefilepath").FileVersion |
或如此处文件列表中所述:
1
| get-childitem * -include *.dll,*.exe | foreach-object {"{0}`t{1}" -f $_.Name, [System.Diagnostics.FileVersionInfo]::GetVersionInfo($_).FileVersion } |
甚至更好地作为脚本:http://jtruher.spaces.live.com/blog/cns!7143DA6E51A2628D!125.entry
" dir"是Get-ChildItem的别名,当您从具有VersionInfo作为属性的文件系统中调用它时,它将返回System.IO.FileInfo类。所以...
要获取单个文件的版本信息,请执行以下操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| PS C:\Windows> (dir .\write.exe).VersionInfo | fl
OriginalFilename : write
FileDescription : Windows Write
ProductName : Microsoft? Windows? Operating System
Comments :
CompanyName : Microsoft Corporation
FileName : C:\Windows\write.exe
FileVersion : 6.1.7600.16385 (win7_rtm.090713-1255)
ProductVersion : 6.1.7600.16385
IsDebug : False
IsPatched : False
IsPreRelease : False
IsPrivateBuild : False
IsSpecialBuild : False
Language : English (United States)
LegalCopyright : ? Microsoft Corporation. All rights reserved.
LegalTrademarks :
PrivateBuild :
SpecialBuild : |
对于多个文件,这是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| PS C:\Windows> dir *.exe | %{ $_.VersionInfo }
ProductVersion FileVersion FileName
-------------- ----------- --------
6.1.7600.16385 6.1.7600.1638... C:\Windows\bfsvc.exe
6.1.7600.16385 6.1.7600.1638... C:\Windows\explorer.exe
6.1.7600.16385 6.1.7600.1638... C:\Windows\fveupdate.exe
6.1.7600.16385 6.1.7600.1638... C:\Windows\HelpPane.exe
6.1.7600.16385 6.1.7600.1638... C:\Windows\hh.exe
6.1.7600.16385 6.1.7600.1638... C:\Windows
otepad.exe
6.1.7600.16385 6.1.7600.1638... C:\Windows
egedit.exe
6.1.7600.16385 6.1.7600.1638... C:\Windows\splwow64.exe
1,7,0,0 1,7,0,0 C:\Windows\twunk_16.exe
1,7,1,0 1,7,1,0 C:\Windows\twunk_32.exe
6.1.7600.16385 6.1.7600.1638... C:\Windows\winhlp32.exe
6.1.7600.16385 6.1.7600.1638... C:\Windows\write.exe |
我更喜欢安装PowerShell社区扩展,仅使用它提供的Get-FileVersionInfo函数。
像这样:
1
| Get-FileVersionInfo MyAssembly.dll |
输出如下:
1 2 3
| ProductVersion FileVersion FileName
-------------- ----------- --------
1.0.2907.18095 1.0.2907.18095 C:\Path\To\MyAssembly.dll |
我已经在整个程序集目录中成功使用了它。
做到这一点的另一种方法是使用内置的文件访问技术:
1
| (get-item .\filename.exe).VersionInfo | FL |
您还可以从VersionInfo获得任何特定的属性,因此:
1
| (get-item .\filename.exe).VersionInfo.FileVersion |
这与dir技术非常接近。
我知道已经解决了这个问题,但是如果有人想输入更少的字符,我相信这是在PS v3 +中编写此文字的最短方法:
1
| ls application.exe | % versioninfo |
-
ls是Get-ChildItem的别名
-
%是ForEach-Object的别名
-
versioninfo这是编写{$_.VersionInfo}的简写方式
以这种方式使用ls的好处是您可以轻松调整它以在子文件夹中查找给定的文件。例如,以下命令将返回子文件夹中所有名为application.exe的文件的版本信息:
1
| ls application.exe -r | % versioninfo |
您可以通过添加-ea silentlycontinue来进一步优化,以忽略诸如无法搜索的文件夹中的权限错误之类的内容:
1
| ls application.exe -r -ea silentlycontinue | % versioninfo |
最后,如果结果中出现省略号(...),则可以附加| fl以其他格式返回信息。尽管返回的格式是列表格式,但返回的结果更多得多,而不是每个结果一行:
1
| ls application.exe -r -ea silentlycontinue | % versioninfo | fl |
我意识到这与xcud的回复非常相似,因为ls和dir都是Get-ChildItem的别名。但我希望我的"最短"方法能对某人有所帮助。
最终的示例可以通过以下方式长时间编写:
1
| Get-ChildItem -Filter application.exe -Recurse -ErrorAction SilentlyContinue | ForEach-Object {$_.VersionInfo} | Format-List |
...但是我认为我的方法更酷,而且在某些情况下更容易记住。 (但大多凉爽)。
这是基于其他答案的,但正是我所追求的:
1
| (Get-Command C:\Path\YourFile.Dll).FileVersionInfo.FileVersion |
1
| [System.Diagnostics.FileVersionInfo]::GetVersionInfo("Path\To\File.dll") |
我发现这很有用:
1 2 3 4 5 6
| function Get-Version($filePath)
{
$name = @{Name="Name";Expression= {split-path -leaf $_.FileName}}
$path = @{Name="Path";Expression= {split-path $_.FileName}}
dir -recurse -path $filePath | % { if ($_.Name -match"(.*dll|.*exe)$") {$_.VersionInfo}} | select FileVersion, $name, $path
} |
这里是一种替代方法。它使用Get-WmiObject CIM_DATAFILE选择版本。
1
| (Get-WmiObject -Class CIM_DataFile -Filter"Name='C:\\Windows\\explorer.exe'" | Select-Object Version).Version |
正如EBGreen所说,[System.Diagnostics.FileVersionInfo] :: GetVersionInfo(path)可以使用,但是请记住,您还可以获取FileVersionInfo的所有成员,例如:
1
| [System.Diagnostics.FileVersionInfo]::GetVersionInfo(path).CompanyName |
您应该能够使用此处记录的FileVersionInfo的每个成员,这基本上可以为您提供有关该文件的任何所需信息。