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.