Отримайте версію файлу в PowerShell


146

Як можна отримати інформацію про версію з файлу .dllабо .exeфайлу в PowerShell?

Я спеціально зацікавлені в File Version, хоча інша інформація про версії (тобто Company, Language, Product Nameі т.д.) було б корисно , як добре.

Відповіді:


140

Оскільки PowerShell може викликати .NET- класи, ви можете зробити наступне:

[System.Diagnostics.FileVersionInfo]::GetVersionInfo("somefilepath").FileVersion

Або як зазначено тут у списку файлів:

get-childitem * -include *.dll,*.exe | foreach-object { "{0}`t{1}" -f $_.Name, [System.Diagnostics.FileVersionInfo]::GetVersionInfo($_).FileVersion }

Або навіть приємніше як сценарій: https://jtruher3.wordpress.com/2006/05/14/powershell-and-file-version-information/


8
Дивіться @Jaykul для рішення, яке не потребує .NET-об’єкта. Відповідь ІМХО Джейкула мала бути обрана як відповідь :)
Томас Братт

2
Хоча в інших відповідях даються більш короткі команди, всі ті, що я спробував роздрукувати надто багато інформації та обрізати шлях до файлу до "...". 2-а команда у цій відповіді дає саме те, що потрібно, працює для каталогу файлів і форматує таким чином, що легко зрозуміти, як її змінити, щоб повернути іншу інформацію. Просто змініть .LegalCopyright в команді на .FileVersion.
Денніс

Це правильна версія для .NET EXE. Відповідь Джейкула не має тієї ж версії.
ashes999

Це насправді неправильно. Подивіться get-item C:\Windows\System32\ubpm.dll | % VersionInfo | fl * -forceта порівняйте FilePrivatePart з останньою частиною FileVersion. FileVersion показує, що оригінально постачалася, а не виправлена ​​версія. Ця команда, з іншого боку, показує номер виправленої версії: (get-command C: \ Windows \ System32 \ ubpm.dll) .Version
Jaykul

Кращим прикладом може бути нещодавно виправлений C: \ Windows \ System32 \ Lsasrv.dll ... але правда полягає в тому, (Get-Command ... ).Versionщо ProductVersion повертає не FileVersion , а іноді це має значення. Отже, для повного рішення, яке фактично повертає оновлений FileVersion, ознайомтеся з прикладом Update-TypeData в моїй відповіді нижче.
Джейкуль

170

Сьогодні ви можете отримати FileVersionInfo від Get-Item або Get-ChildItem, але він покаже оригінальний FileVersion від поставленого продукту, а не оновлену версію. Наприклад:

(Get-Item C:\Windows\System32\Lsasrv.dll).VersionInfo.FileVersion

Цікаво, що ви можете отримати оновлений (виправлений) ProductVersion , скориставшись цим:

(Get-Command C:\Windows\System32\Lsasrv.dll).Version

Відмінність, яку я роблю між "оригінальним" і "виправленим", в основному обумовлена ​​способом обчислення FileVersion ( див. Документи тут ). В основному з моменту Vista, API Windows GetFileVersionInfo запитує частину інформації про версію з файлу нейтральної мови (exe / dll) та нефіксованої частини з файлу mui, що відповідає мові (який не оновлюється щоразу, коли файли змінюються ).

Так що з таким файлом, як lsasrv (який замінили через проблеми безпеки в SSL / TLS / RDS у листопаді 2014 року), версії, які повідомлялися цими двома командами (принаймні на деякий час після цієї дати), були різними, а друга - більш "правильна" версія.

Однак, хоча це правильно в LSASrv, можливо, ProductVersion і FileVersion можуть бути різними (насправді це звичайно). Тож єдиний спосіб отримати це оновлений Fileversion прямо з асемблерного файлу - це створити його самостійно з частин, приблизно так:

Get-Item C:\Windows\System32\Lsasrv.dll | ft FileName, File*Part

Або витягнувши дані з цього:

[System.Diagnostics.FileVersionInfo]::GetVersionInfo($this.FullName)

Ви можете легко додати це до всіх об'єктів FileInfo, оновивши TypeData в PowerShell:

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 ...


10
І щоб зробити це еквівалентом прийнятої відповіді Ларса, просто використовуйте(Get-Command C:\Path\YourFile.Dll).FileVersionInfo.FileVersion
rand0m1

1
Мене заінтригує Get-Commandзастосований до dll-файл. Не могли б ви детальніше розглянути його ефект?
Стефан Ролланд

3
Попередження FileVersionInfo.FileVersion - це рядкове представлення, яке може не бути оновленим. Ви повинні подивитися на FileVersionInfo.FileMajorPart, FileMinorPart, FileBuildPart, FilePrivatePart. Див. GetFileVersionInfo () повертає неправильну інформацію про версію файлу
bdeem

1
@Jaykul Щоб уточнити свій попередній коментар / запитання: оригінальна відповідь демонструє, як отримати ProductVersion в PowerShell шляхом цікавих згортків, тому що ProductVersion може бути більш показовим, ніж FileVersion. Оригінальна відповідь не згадує властивість VersionInfo.ProductVersion, можливо тому, що відповідь заздалегідь його датує. Чи (Get-Item C:\Windows\System32\Lsasrv.dll).VersionInfo.ProductVersionє більш новий простіший спосіб отримати ту саму інформацію про ProductVersion, яку зафіксовано у відповіді? Я не дуже довіряю Microsoft постійно використовувати цей термін ProductVersion.
Тидей

2
@Tydaeus Це не нове. Ви можете переглянути його на документах і побачити, як далеко йде назад (.NET 1.1) 😏. У моїй відповіді згадується ProductVersion, але версія, яку ми обчислюємо з усім цим кодом ScriptProperty, є справжньою версією FILE, а не ProductVersion. Вони іноді однакові, але не завжди. 😔 І, на жаль, кожен приклад із реального світу я придумую зміни в наступному випуску сервісів Windows 😉 docs.microsoft.com/en-us/dotnet/api/…
Jaykul

50

'dir' - псевдонім для Get-ChildItem, який поверне клас System.IO.FileInfo, коли ви викликаєте його з файлової системи, яка має VersionInfo як властивість. Так ...

Щоб отримати інформацію про версію одного файлу, зробіть це:

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     :

Для кількох файлів це:

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\notepad.exe
6.1.7600.16385   6.1.7600.1638... C:\Windows\regedit.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

Корисно тим, що ви включаєте й інші поширені метадані (наприклад, назва компанії та опис).
David Faivre

16

Я вважаю за краще встановити розширення спільноти PowerShell і просто використовувати функцію Get-FileVersionInfo, яку він надає.

Так:

Get-FileVersionInfo MyAssembly.dll

з виходом типу:

ProductVersion FileVersion FileName
-------------- ----------- --------
1.0.2907.18095 1.0.2907.18095 C: \ Шлях \ До \ MyAssembly.dll

Я з великим успіхом використовував його для цілого каталогу збірок.


12

Я усвідомлюю, що на це вже відповіли, але якщо хтось зацікавлений у введенні меншої кількості символів, я вважаю, що це найкоротший спосіб написання цього в PS v3 +:

ls application.exe | % versioninfo
  • ls псевдонім для Get-ChildItem
  • % псевдонім для ForEach-Object
  • versioninfo ось короткий спосіб написання {$_.VersionInfo}

Перевага використання lsцього способу полягає в тому, що ви можете легко адаптувати його до пошуку заданого файлу в підпапках. Наприклад, наступна команда поверне інформацію про версію для всіх файлів, викликаних application.exeу підпапках:

ls application.exe -r | % versioninfo
  • -r псевдонім для -Recurse

Ви можете додатково уточнити це, додавши -ea silentlycontinueдо ігнорування таких речей, як помилки дозволу в папках, які ви не можете шукати:

ls application.exe -r -ea silentlycontinue | % versioninfo
  • -ea псевдонім для -ErrorAction

Нарешті, якщо ви отримуєте еліпси (...) у своїх результатах, ви можете додати, | flщоб повернути інформацію в іншому форматі. Це повертає набагато більше деталей, хоча вони відформатовані у списку, а не в одному рядку за результатом:

ls application.exe -r -ea silentlycontinue | % versioninfo | fl
  • fl псевдонім для Format-List

Я розумію , що це дуже схоже на відповідь xcud в тому , що lsі dirобидва синоніма Get-ChildItem. Але я сподіваюся, що мій "найкоротший" метод комусь допоможе.

Остаточний приклад може бути написаний з довгих рук наступним чином:

Get-ChildItem -Filter application.exe -Recurse -ErrorAction SilentlyContinue | ForEach-Object {$_.VersionInfo} | Format-List

... але я думаю, що мій спосіб крутіший і, для деяких, простіше запам'ятати. (Але в основному крутіше).


11

Ще один спосіб зробити це - використовувати вбудовану техніку доступу до файлів:

(get-item .\filename.exe).VersionInfo | FL

Ви також можете отримати будь-яке певне майно від VersionInfo, таким чином:

(get-item .\filename.exe).VersionInfo.FileVersion

Це досить близько до техніки dir.


(get-item \\ "$ computerName" \ "C $ \ Program Files \ Symantec AntiVirus \ VPDN_LU.exe"). Для мене працювала VersionInfo.FileVersion. Мені потрібно було додати ім’я комп’ютера з циклу.
Текіла

7

Це ґрунтується на інших відповідях, але саме я був після:

(Get-Command C:\Path\YourFile.Dll).FileVersionInfo.FileVersion

Мене заінтригує Get-Commandзастосований до dll-файл. Чи можете ви детальніше розглянути його ефект (перш ніж навіть зателефонувати за властивістю FileVersionInfo)?
Стефан Ролланд

DLL-файли містять так FileVersionInfoсамо, як і файли EXE. Застосувавши цю команду до шляху, ви отримаєте інформацію про версію файлу!
noelicus


4

Я вважаю це корисним:

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
}

Це VBScript?
macetw

1
Ні, це повноваження
Chriseyre2000

2

Як сказав EBGreen, [System.Diagnostics.FileVersionInfo] :: GetVersionInfo (шлях) буде працювати, але пам’ятайте, що ви також можете отримати всіх членів FileVersionInfo, наприклад:

[System.Diagnostics.FileVersionInfo]::GetVersionInfo(path).CompanyName

Ви повинні мати можливість використовувати кожного документа FileVersionInfo, який тут задокументований, і ви отримаєте в основному все, що ви могли хотіти про файл.


1

Тут альтернативний метод. Для вибору версії використовується Get-WmiObject CIM_DATAFILE.

(Get-WmiObject -Class CIM_DataFile -Filter "Name='C:\\Windows\\explorer.exe'" | Select-Object Version).Version

використовуючи шлях спільного доступу з пробілами в імені, я отримав "Властивість" Версія "неможливо знайти на цьому об'єкті. Перевірте, чи існує властивість."
AnneTheAgile
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.