Pobierz wersję pliku w programie PowerShell


146

Jak uzyskać informacje o wersji z pliku .dlllub .exew programie PowerShell?

Jestem szczególnie zainteresowany File Version, chociaż inne informacje o wersji (czyli Company, Language, Product Name, itd.) Byłby pomocny.

Odpowiedzi:


140

Ponieważ PowerShell może wywoływać klasy .NET , możesz wykonać następujące czynności:

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

Lub jak zaznaczono tutaj na liście plików:

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

Lub nawet ładniejszy jako skrypt: https://jtruher3.wordpress.com/2006/05/14/powershell-and-file-version-information/


8
Zobacz @Jaykul, aby zapoznać się z rozwiązaniem, które nie wymaga obiektu .NET. Odpowiedź IMHO Jaykula powinna zostać wybrana jako odpowiedź :)
— Thomas Bratt,

2
Chociaż inne odpowiedzi dają krótsze polecenia, wszystkie z nich, które próbowałem, wypisują za dużo informacji i skracają ścieżkę do pliku do „...”. Drugie polecenie w tej odpowiedzi podaje dokładnie to, czego potrzebujesz, działa dla katalogu plików i formatuje w taki sposób, że łatwo jest zobaczyć, jak je zmodyfikować, aby zwrócić inne informacje. Po prostu zmień .LegalCopyright w poleceniu na .FileVersion.
— Dennis

To jest poprawna wersja dla plików .NET EXE. Odpowiedź Jaykula nie ma tej samej wersji.
— popioły 999

To właściwie nie w porządku. Przyjrzyj się get-item C:\Windows\System32\ubpm.dll | % VersionInfo | fl * -forcei porównaj FilePrivatePart z ostatnią częścią FileVersion. FileVersion pokazuje, co zostało pierwotnie wysłane, a nie poprawioną wersję. Z drugiej strony to polecenie pokazuje numer poprawionej wersji: (get-command C: \ Windows \ System32 \ ubpm.dll).
— Wersja

Lepszym przykładem może być niedawno załatany C: \ Windows \ System32 \ Lsasrv.dll ... ale prawda jest taka, że (Get-Command ... ).Versionzwraca ProductVersion, a nie FileVersion , i czasami ma to znaczenie. Aby uzyskać pełne rozwiązanie, które faktycznie zwraca zaktualizowaną wersję pliku, zapoznaj się z przykładem Update-TypeData w mojej odpowiedzi poniżej.
— Jaykul

170

Obecnie możesz pobrać FileVersionInfo z Get-Item lub Get-ChildItem, ale pokaże on oryginalny plik FileVersion z dostarczonego produktu, a nie zaktualizowaną wersję. Na przykład:

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

Co ciekawe, zaktualizowaną (załataną) wersję ProductVersion można pobrać za pomocą tego:

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

Rozróżnienie, które robię między „oryginalnym” i „załatanym”, wynika zasadniczo ze sposobu obliczania FileVersion ( zobacz dokumentację tutaj ). Zasadniczo od czasu Vista, GetFileVersionInfo API systemu Windows odpytuje część informacji o wersji z pliku neutralnego językowo (exe / dll), a nie naprawioną część z pliku mui specyficznego dla języka (który nie jest aktualizowany za każdym razem, gdy zmieniają się pliki ).

Tak więc w przypadku pliku takiego jak lsasrv (który został zastąpiony z powodu problemów z bezpieczeństwem w SSL / TLS / RDS w listopadzie 2014 r.) Wersje zgłaszane przez te dwie komendy (przynajmniej przez chwilę po tej dacie) były różne, a druga to bardziej „poprawna” wersja.

Jednak chociaż jest to poprawne w LSASrv, możliwe jest, że ProductVersion i FileVersion będą różne (w rzeczywistości jest to powszechne). Tak więc jedynym sposobem uzyskania zaktualizowanej wersji Fileversion bezpośrednio z pliku zespołu jest samodzielne zbudowanie jej z części, coś takiego:

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

Lub pobierając dane z tego:

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

Możesz łatwo dodać to do wszystkich obiektów FileInfo, aktualizując TypeData w PowerShell:

Update-TypeData -TypeName System.IO.FileInfo -MemberName FileVersion -MemberType ScriptProperty -Value {
   [System.Diagnostics.FileVersionInfo]::GetVersionInfo($this.FullName) | % {
      [Version](($_.FileMajorPart, $_.FileMinorPart, $_.FileBuildPart, $_.FilePrivatePart)-join".") 
   }
}

Teraz za każdym razem, gdy to zrobisz, Get-ChildItemlub Get-Itembędziesz mieć FileVersionwłaściwość, która pokazuje zaktualizowaną wersję pliku ...


10
Aby to było odpowiednikiem zaakceptowanej odpowiedzi Larsa, po prostu użyj(Get-Command C:\Path\YourFile.Dll).FileVersionInfo.FileVersion
— rand0m1,

1
Jestem zaintrygowany Get-Commandzastosowanym do pliku dll. Czy mógłbyś wyjaśnić jego efekt?
— Stephane Rolland

3
Ostrzeżenie FileVersionInfo.FileVersion to ciąg znaków, który może nie być aktualny. Powinieneś spojrzeć na FileVersionInfo.FileMajorPart, FileMinorPart, FileBuildPart, FilePrivatePart. Zobacz GetFileVersionInfo () zwraca informacje o błędnej wersji pliku
— bdeem,

1
@Jaykul Aby wyjaśnić mój wcześniejszy komentarz / pytanie: oryginalna odpowiedź pokazuje, jak uzyskać wersję produktu w PowerShell poprzez kilka interesujących rozwiązań, ponieważ ProductVersion może być bardziej orientacyjna niż FileVersion. Oryginalna odpowiedź nie wspomina o właściwości VersionInfo.ProductVersion, prawdopodobnie dlatego, że odpowiedź jest przed nią. Czy (Get-Item C:\Windows\System32\Lsasrv.dll).VersionInfo.ProductVersionnowszy, prostszy sposób na uzyskanie tych samych informacji o ProductVersion, jak opisano w odpowiedzi? Nie ufam firmie Microsoft w ProductVersionkonsekwentnym używaniu tego terminu .
— Tydaeus

2
@Tydaeus To nie jest nowe. Możesz sprawdzić to w dokumentach i zobaczyć, jak daleko sięga wstecz (.NET 1.1) 😏. Moja odpowiedź wspomina o ProductVersion, ale wersja, którą obliczamy z całym tym kodem ScriptProperty, jest prawdziwą wersją PLIKU, a nie wersją produktu. Czasami są takie same, ale nie zawsze. 😔 I niestety, każdy przykład ze świata rzeczywistego, który wymyślam ze zmianami w następnej wersji usługi systemu Windows 😉 docs.microsoft.com/en-us/dotnet/api/…
— Jaykul

50

„dir” jest aliasem dla Get-ChildItem, który zwróci klasę System.IO.FileInfo, gdy wywołujesz ją z systemu plików, który ma VersionInfo jako właściwość. Więc ...

Aby uzyskać informacje o wersji pojedynczego pliku, wykonaj następujące czynności:

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     :

W przypadku wielu plików:

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

Pomocne jest to, że dołączasz również inne popularne metadane (takie jak nazwa i opis firmy).
— David Faivre

16

Wolę zainstalować rozszerzenia społeczności PowerShell i po prostu użyć funkcji Get-FileVersionInfo, którą zapewnia.

Tak jak to:

Get-FileVersionInfo MyAssembly.dll

z wyjściem takim jak:

ProductVersion FileVersion FileName
-------------- ----------- --------
1.0.2907.18095 1.0.2907.18095 C: \ Path \ To \ MyAssembly.dll

Użyłem go przeciwko całemu katalogowi zestawów z wielkim sukcesem.


12

Zdaję sobie sprawę, że już na to odpowiedziano, ale jeśli ktoś jest zainteresowany wpisaniem mniejszej liczby znaków, uważam, że jest to najkrótszy sposób napisania tego w PS v3 +:

ls application.exe | % versioninfo
  • ls jest aliasem dla Get-ChildItem
  • % jest aliasem dla ForEach-Object
  • versioninfo tutaj jest skrótowy sposób pisania {$_.VersionInfo}

Zaletą używania lsw ten sposób jest to, że można go łatwo dostosować do wyszukiwania danego pliku w podfolderach. Na przykład poniższe polecenie zwróci informacje o wersji dla wszystkich plików wywoływanych application.exew podfolderach:

ls application.exe -r | % versioninfo
  • -r jest aliasem dla -Recurse

Możesz to dodatkowo uściślić, dodając, -ea silentlycontinueaby ignorować takie rzeczy, jak błędy uprawnień w folderach, których nie możesz przeszukiwać:

ls application.exe -r -ea silentlycontinue | % versioninfo
  • -ea jest aliasem dla -ErrorAction

Wreszcie, jeśli otrzymujesz wielokropki (...) w wynikach, możesz dołączyć, | flaby zwrócić informacje w innym formacie. Zwraca to znacznie więcej szczegółów, mimo że jest sformatowane w formie listy, a nie w jednym wierszu na wynik:

ls application.exe -r -ea silentlycontinue | % versioninfo | fl
  • fl jest aliasem dla Format-List

Zdaję sobie sprawę, że jest to bardzo podobne do odpowiedzi xcud pod tym względem lsi diroba są aliasami dla Get-ChildItem. Ale mam nadzieję, że moja „najkrótsza” metoda komuś pomoże.

Ostatni przykład można napisać odręcznie w następujący sposób:

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

... ale myślę, że moja droga jest fajniejsza i dla niektórych łatwiejsza do zapamiętania. (Ale głównie fajniejsze).


11

Innym sposobem jest użycie wbudowanej techniki dostępu do plików:

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

Możesz również pobrać określoną właściwość z VersionInfo, a zatem:

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

Jest to dość zbliżone do techniki reż.


(get-item \\ "$ computerName" \ "C $ \ Program Files \ Symantec AntiVirus \ VPDN_LU.exe"). VersionInfo.FileVersion działało dla mnie. Musiałem dodać nazwę komputera z pętli.
— Tequila

7

Jest to oparte na innych odpowiedziach, ale dokładnie o to mi chodziło:

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

Jestem zaintrygowany Get-Commandzastosowanym do pliku dll. Czy mógłbyś bardziej szczegółowo opisać jego efekt (jeszcze przed wywołaniem właściwości FileVersionInfo)?
— Stephane Rolland

Pliki dll zawierają FileVersionInfotak samo, jak pliki exe. Zastosowanie tego polecenia do ścieżki spowoduje uzyskanie informacji o wersji pliku!
— noelicus

4
[System.Diagnostics.FileVersionInfo]::GetVersionInfo("Path\To\File.dll")

4

Uważam, że to przydatne:

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
}

Czy to jest VBScript?
— macetw

1
Nie, to powershell
— Chriseyre2000

2

Jak powiedział EBGreen, [System.Diagnostics.FileVersionInfo] :: GetVersionInfo (ścieżka) będzie działać, ale pamiętaj, że możesz również pobrać wszystkie elementy członkowskie FileVersionInfo, na przykład:

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

Powinieneś być w stanie użyć każdego członka FileVersionInfo udokumentowanego tutaj, co da ci w zasadzie wszystko, czego możesz chcieć w pliku.


1

Tutaj alternatywna metoda. Używa Get-WmiObject CIM_DATAFILE do wyboru wersji.

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

używając ścieżki udziału ze spacjami w nazwie, otrzymałem informację „Nie można znaleźć właściwości„ Wersja ”w tym obiekcie. Sprawdź, czy właściwość istnieje.”
— AnneTheAgile
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.