PowerShell'de dosya sürümünü edinin


151

PowerShell'deki bir .dllveya .exedosyadan sürüm bilgilerini nasıl edinebilirsiniz ?

Özellikle ilgilenen am File Versiondiğer sürüm bilgileri (olduğunu, olsa da, Company, Language, Product Name, vb) yanı sıra yararlı olacaktır.

Yanıtlar:


144

PowerShell, .NET sınıflarını çağırabildiğinden , aşağıdakileri yapabilirsiniz:

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

Veya burada bir dosya listesinde belirtildiği gibi :

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

Veya bir komut dosyası olarak daha da güzel: https://jtruher3.wordpress.com/2006/05/14/powershell-and-file-version-information/


8
.NET nesnesi gerektirmeyen bir çözüm için @Jaykul'a bakınız. IMHO Jaykul'un cevabı cevap olarak seçilmeliydi :)
Thomas Bratt

2
Diğer yanıtlar daha kısa komutlar verse de, denediğim tüm yanıtlar çok fazla bilgi yazdırıyor ve dosya yolunu "..." şeklinde kısaltıyor. Bu yanıttaki 2. komut tam olarak ihtiyacınız olanı verir, bir dosya dizini için çalışır ve diğer bilgileri döndürmek için nasıl değiştirileceğini görmenin kolay olacağı şekilde biçimlendirir. Sadece komuttaki .LegalCopyright'ı .FileVersion olarak değiştirin.
Dennis

Bu, .NET EXE'leri için doğru sürümdür. Jaykul'un cevabı aynı versiyona sahip değil.
ashes999

Aslında bu doğru değil. get-item C:\Windows\System32\ubpm.dll | % VersionInfo | fl * -forceFilePrivatePart'a bakın ve FileVersion'ın son kısmıyla karşılaştırın. FileVersion, yamalı sürümü değil, orijinal olarak neyin gönderildiğini gösterir. Bu komut, diğer taraftan, gösterileri yamalı sürüm numarası: (get-komuta C: \ Windows \ System32 \ ubpm.dll) .Version
Jaykul

Daha iyi bir örnek yakın zamanda yamalı olacaktır \ Windows \ System32 \ Lsasrv.dll: C ... ama gerçek şu ki (Get-Command ... ).Versiondöner ProductVersion'ın değil DosyaSürümü ve bazen bu konularda. Dolayısıyla, güncellenmiş FileVersion'ı gerçekten döndüren tam bir çözüm için , aşağıdaki cevabımdaki Update-TypeData örneğine bakın.
Jaykul

176

Günümüzde FileVersionInfo dosyasını Get-Item veya Get-ChildItem'den alabilirsiniz, ancak güncellenmiş sürümü değil, gönderilen üründen orijinal FileVersion'ı gösterecektir. Örneğin:

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

İlginç bir şekilde, bunu kullanarak güncellenmiş (yamalı) ProductVersion'ı alabilirsiniz :

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

"Orijinal" ve "yamalı" arasında yaptığım ayrım, temelde FileVersion'ın hesaplanma yönteminden kaynaklanıyor ( buradaki belgelere bakın ). Temelde Vista'dan beri, Windows API GetFileVersionInfo, dilden bağımsız dosyadan (exe / dll) sürüm bilgilerinin bir kısmını ve dile özgü bir mui dosyasından (dosyalar her değiştiğinde güncellenmeyen) sabit olmayan kısmı sorgulamaktadır. ).

Dolayısıyla, lsasrv gibi bir dosyayla (Kasım 2014'te SSL / TLS / RDS'deki güvenlik sorunları nedeniyle değiştirildi) bu iki komut tarafından bildirilen sürümler (en azından bu tarihten sonra bir süre için) farklıydı ve ikincisi , daha "doğru" versiyon.

Bununla birlikte, LSASrv'de doğru olmasına rağmen, ProductVersion ve FileVersion'ın farklı olması mümkündür (aslında bu yaygındır). Dolayısıyla, güncellenmiş Fileversion'ı doğrudan montaj dosyasından almanın tek yolu, onu parçalardan kendiniz oluşturmaktır, bunun gibi bir şey:

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

Veya verileri buradan çekerek:

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

PowerShell'deki TypeData'yı güncelleyerek bunu tüm FileInfo nesnelerine kolayca ekleyebilirsiniz:

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

Şimdi her yaptığınızda Get-ChildItemveya güncellenmiş FileVersion'ı gösteren Get-Itembir FileVersionözelliğe sahip olacaksınız ...


10
Bunu Lars'ın kabul ettiği cevaba eşdeğer yapmak için şunu kullanın(Get-Command C:\Path\YourFile.Dll).FileVersionInfo.FileVersion
rand0m1

1
Get-CommandBir dll dosyasına uygulanan ilgimi çekiyor. Etkisinden biraz bahseder misiniz?
Stephane Rolland

3
Uyarı FileVersionInfo.FileVersion, güncel olmayabilir bir dize gösterimidir. FileVersionInfo.FileMajorPart, FileMinorPart, FileBuildPart, FilePrivatePart'a bakmalısınız. Bkz. GetFileVersionInfo () yanlış dosyanın sürüm bilgilerini
döndürüyor

1
@Jaykul Önceki yorumumu / sorumu açıklığa kavuşturmak için: orijinal cevap, PowerShell'de ProductVersion'ın bazı ilginç dönüşümler yoluyla nasıl elde edileceğini gösterir, çünkü ProductVersion, FileVersion'dan daha belirleyici olabilir. Orijinal yanıt VersionInfo.ProductVersion özelliğinden bahsetmez, bunun nedeni muhtemelen yanıtın önceden tarihlendirilmesidir. Mı (Get-Item C:\Windows\System32\Lsasrv.dll).VersionInfo.ProductVersioncevap belgelenen aynı ProductVersion bilgi almak için bir yeni daha basit bir yolu? Microsoft'un terimi ProductVersiontutarlı bir şekilde kullanacağına gerçekten güvenmiyorum .
Tydaeus

2
@Tydaeus Yeni değil. Belgelerde buna bakabilir ve ne kadar geriye gittiğini görebilirsiniz (.NET 1.1) 😏. Cevabım ProductVersion'dan bahsediyor, ancak tüm bu ScriptProperty koduyla hesapladığımız sürüm, ProductVersion değil, gerçek DOSYA Sürümüdür. Bazen aynıdırlar ama her zaman değil. 😔 Ve maalesef her gerçek dünya örneği ben 😉 Windows'un sonraki hizmet sürümdeki değişiklikleri ile gelip docs.microsoft.com/en-us/dotnet/api/...
Jaykul

50

'dir', bir özellik olarak VersionInfo'ya sahip dosya sisteminden çağırdığınızda System.IO.FileInfo sınıfını geri döndüren Get-ChildItem için bir takma addır. Yani ...

Tek bir dosyanın sürüm bilgisini almak için şunu yapın:

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     :

Birden fazla dosya için bu:

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

Diğer yaygın meta verileri de eklemeniz açısından yararlıdır (şirket adı ve açıklaması gibi).
David Faivre

16

PowerShell Topluluk Uzantılarını yüklemeyi ve yalnızca sağladığı Get-FileVersionInfo işlevini kullanmayı tercih ediyorum .

Şöyle:

Get-FileVersionInfo MyAssembly.dll

aşağıdaki gibi çıktılarla:

Ürün Sürümü Dosya Sürümü Dosya Adı
-------------- ----------- --------
1.0.2907.18095 1.0.2907.18095 C: \ Yol \ Kime \ MyAssembly.dll

Bunu büyük bir başarı ile bütün bir toplantılar dizinine karşı kullandım.


12

Bunun zaten yanıtlandığını biliyorum, ancak daha az karakter yazmakla ilgilenen varsa, bunun PS v3 + 'da bunu yazmanın en kısa yolu olduğuna inanıyorum:

ls application.exe | % versioninfo
  • ls için bir takma addır Get-ChildItem
  • % için bir takma addır ForEach-Object
  • versioninfo işte yazmanın kısa bir yolu {$_.VersionInfo}

lsBu şekilde kullanmanın yararı, alt klasörler içinde belirli bir dosyayı aramak için onu kolayca uyarlayabilmenizdir. Örneğin, aşağıdaki komut, application.exealt klasörlerde çağrılan tüm dosyalar için sürüm bilgilerini döndürür :

ls application.exe -r | % versioninfo
  • -r için bir takma addır -Recurse

Arayamayacağınız -ea silentlycontinueklasörlerdeki izin hataları gibi şeyleri yok saymak için ekleyerek bunu daha da hassaslaştırabilirsiniz :

ls application.exe -r -ea silentlycontinue | % versioninfo
  • -ea için bir takma addır -ErrorAction

Son olarak, sonuçlarınızda üç nokta (...) alıyorsanız | fl, bilgileri farklı bir biçimde döndürmek için ekleyebilirsiniz . Bu, sonuç başına bir satır yerine, bir listede biçimlendirilmiş olmasına rağmen çok daha fazla ayrıntı verir:

ls application.exe -r -ea silentlycontinue | % versioninfo | fl
  • fl için bir takma addır Format-List

Bunun xcud'un yanıtına çok benzediğini lsve dirher ikisinin de takma adı olduğunu anlıyorum Get-ChildItem. Ama "en kısa" yöntemimin birine yardımcı olacağını umuyorum.

Son örnek şu şekilde uzun elle yazılabilir:

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

... ama yolumun daha havalı ve bazıları için hatırlaması daha kolay olduğunu düşünüyorum. (Ama çoğunlukla daha soğuk).


11

Bunu yapmanın bir başka yolu da yerleşik dosya erişim tekniğini kullanmaktır:

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

Herhangi bir özelliği VersionInfo'dan da alabilirsiniz, böylece:

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

Bu, tekniğe oldukça yakındır.


(get-item \\ "$ bilgisayarAdı" \ "C $ \ Program Files \ Symantec AntiVirus \ VPDN_LU.exe") VersionInfo.FileVersion benim için çalıştı. Bir döngüden bir bilgisayar adı eklemem gerekiyordu.
Tequila

7

Bu, diğer cevaplara dayanıyor , ama tam olarak peşindeydim:

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

Get-CommandBir dll dosyasına uygulanan ilgimi çekiyor. Etkisi hakkında daha ayrıntılı bilgi verebilir misiniz (FileVersionInfo özelliğini aramadan önce)?
Stephane Rolland

dll dosyaları, FileVersionInfoexe dosyalarının yaptığı gibi içerir . Bu komutu yola uygulamak dosya sürümü bilgisini alacaktır!
noelicus

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

4

Bunu yararlı buluyorum:

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
}

Bu bir VBScript mi?
macetw

1
Hayır powershell
Chriseyre2000

2

EBGreen'in dediği gibi, [System.Diagnostics.FileVersionInfo] :: GetVersionInfo (path) çalışacaktır, ancak FileVersionInfo'nun tüm üyelerini de alabileceğinizi unutmayın, örneğin:

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

Burada belgelenen her FileVersionInfo üyesini kullanabilmelisiniz, bu da temelde dosya hakkında isteyebileceğiniz her şeyi size sağlayacaktır.


1

İşte alternatif bir yöntem. Sürümü seçmek için Get-WmiObject CIM_DATAFILE kullanır.

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

adında boşluklar olan bir paylaşım yolu kullanarak, "'Sürüm' özelliği bu nesnede bulunamıyor. Özelliğin var olduğunu doğrulayın."
AnneTheAgile
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.