Ottieni la versione del file in PowerShell


146

Come è possibile ottenere le informazioni sulla versione da un file .dllo .exein PowerShell?

Sono in particolare interessati a File Version, anche se altre informazioni sulla versione (che è, Company, Language, Product Name, etc.) sarebbe utile pure.

Risposte:


140

Poiché PowerShell può chiamare classi .NET , è possibile effettuare le seguenti operazioni:

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

O come indicato qui in un elenco di file:

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

O ancora più bello come uno script: https://jtruher3.wordpress.com/2006/05/14/powershell-and-file-version-information/


8
Vedi @Jaykul per una soluzione che non richiede un oggetto .NET. La risposta di IMHO Jaykul avrebbe dovuto essere selezionata come risposta :)
Thomas Bratt l'

2
Sebbene le altre risposte forniscano comandi più brevi, tutte quelle che ho provato hanno stampato troppe informazioni e troncato il percorso del file su "...". Il secondo comando in questa risposta fornisce esattamente ciò di cui hai bisogno, funziona per una directory di file e sta formattando in modo che sia facile vedere come modificarlo per restituire altre informazioni. Basta cambiare .LegalCopyright nel comando in .FileVersion.
Dennis,

Questa è la versione corretta per i file EXE .NET. La risposta di Jaykul non ottiene la stessa versione.
ashes999

In realtà non è giusto. Guarda get-item C:\Windows\System32\ubpm.dll | % VersionInfo | fl * -forcee confronta FilePrivatePart con l'ultima parte di FileVersion. FileVersion mostra ciò che è stato originariamente spedito e non la versione con patch. Questo comando, d'altra parte, mostra il numero di versione corretto: (get-command C: \ Windows \ System32 \ ubpm.dll) .Versione
Jaykul

Un esempio migliore potrebbe essere il C: \ Windows \ System32 \ Lsasrv.dll aggiornato di recente ... ma la verità è che (Get-Command ... ).Versionrestituisce ProductVersion non FileVersion , e talvolta è importante. Quindi, per una soluzione completa che restituisce effettivamente la FileVersion aggiornata , controlla l'esempio Update-TypeData nella mia risposta di seguito.
Jaykul,

170

Oggi puoi ottenere FileVersionInfo da Get-Item o Get-ChildItem, ma mostrerà la FileVersion originale dal prodotto spedito e non la versione aggiornata. Per esempio:

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

È interessante notare che puoi ottenere la ProductVersion aggiornata (patchata) usando questo:

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

La distinzione che sto facendo tra "originale" e "corretto" è sostanzialmente dovuta al modo in cui viene calcolata la FileVersion ( vedere i documenti qui ). Fondamentalmente sin da Vista, l'API GetFileVersionInfo di Windows esegue una query su parte delle informazioni sulla versione dal file neutro della lingua (exe / dll) e la parte non fissa da un file mui specifico della lingua (che non viene aggiornato ogni volta che i file cambiano ).

Quindi con un file come lsasrv (che è stato sostituito a causa di problemi di sicurezza in SSL / TLS / RDS nel novembre 2014) le versioni riportate da questi due comandi (almeno per un po 'dopo quella data) erano diverse, e il secondo è il versione più "corretta".

Tuttavia, sebbene sia corretto in LSASrv, è possibile che ProductVersion e FileVersion siano diversi (è comune, in effetti). Quindi l'unico modo per ottenere la Fileversion aggiornata direttamente dal file di assieme è costruirla dalle parti, in questo modo:

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

O estraendo i dati da questo:

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

Puoi facilmente aggiungerlo a tutti gli oggetti FileInfo aggiornando TypeData in PowerShell:

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

Ora ogni volta che lo fai Get-ChildItemo Get-Itemavrai una FileVersionproprietà che mostra la FileVersion aggiornata ...


10
E per rendere questo l'equivalente della risposta accettata da Lars, basta usare(Get-Command C:\Path\YourFile.Dll).FileVersionInfo.FileVersion
rand0m1 il

1
Sono incuriosito dal Get-Commandapplicato a un file DLL. Potresti approfondire il suo effetto?
Stephane Rolland,

3
Avviso FileVersionInfo.FileVersion è una rappresentazione di stringhe che potrebbe non essere aggiornata. Dovresti guardare FileVersionInfo.FileMajorPart, FileMinorPart, FileBuildPart, FilePrivatePart. Vedi GetFileVersionInfo () restituisce informazioni sulla versione del file errate
bdeem

1
@Jaykul Per chiarire il mio precedente commento / domanda: la risposta originale dimostra come ottenere la ProductVersion in PowerShell attraverso alcune convoluzioni interessanti, perché ProductVersion potrebbe essere più indicativo di FileVersion. La risposta originale non menziona la proprietà VersionInfo.ProductVersion, probabilmente perché la risposta la precede. È (Get-Item C:\Windows\System32\Lsasrv.dll).VersionInfo.ProductVersionun modo più semplice di ottenere le stesse informazioni sulla versione del prodotto documentate nella risposta? Non mi fido davvero che Microsoft usi il termine in modo ProductVersioncoerente.
Tydaeus,

2
@Tydaeus Non è nuovo. Puoi cercarlo su documenti e vedere quanto tempo fa (.NET 1.1) 😏. La mia risposta menziona ProductVersion, ma la versione che stiamo calcolando con tutto quel codice ScriptProperty è la vera versione FILE, non ProductVersion. A volte sono uguali, ma non sempre. 😔 E sfortunatamente, ogni esempio del mondo reale che mi viene in mente cambia nella prossima versione di servizio di Windows 😉 docs.microsoft.com/en-us/dotnet/api/…
Jaykul,

50

'dir' è un alias per Get-ChildItem che restituirà una classe System.IO.FileInfo quando la si chiama dal filesystem che ha VersionInfo come proprietà. Così ...

Per ottenere le informazioni sulla versione di un singolo file, procedere come segue:

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     :

Per più file questo:

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

È utile in quanto includi anche altri metadati comuni (come il nome e la descrizione dell'azienda).
David Faivre,

16

Preferisco installare le estensioni della community di PowerShell e utilizzare semplicemente la funzione Get-FileVersionInfo fornita.

Così:

Get-FileVersionInfo MyAssembly.dll

con output come:

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

L'ho usato contro un'intera directory di assiemi con grande successo.


12

Mi rendo conto che è già stata data una risposta, ma se qualcuno è interessato a digitare meno caratteri, credo che questo sia il modo più breve di scrivere questo in PS v3 +:

ls application.exe | % versioninfo
  • ls è un alias per Get-ChildItem
  • % è un alias per ForEach-Object
  • versioninfo ecco un modo abbreviato di scrivere {$_.VersionInfo}

Il vantaggio di utilizzare lsin questo modo è che puoi facilmente adattarlo per cercare un determinato file all'interno delle sottocartelle. Ad esempio, il comando seguente restituirà le informazioni sulla versione per tutti i file richiamati application.exenelle sottocartelle:

ls application.exe -r | % versioninfo
  • -r è un alias per -Recurse

Puoi perfezionare ulteriormente ciò aggiungendo -ea silentlycontinueper ignorare elementi come errori di autorizzazione nelle cartelle che non puoi cercare:

ls application.exe -r -ea silentlycontinue | % versioninfo
  • -ea è un alias per -ErrorAction

Infine, se si ottengono ellissi (...) nei risultati, è possibile aggiungere | flper restituire le informazioni in un formato diverso. Ciò restituisce molti più dettagli, sebbene formattati in un elenco, piuttosto che su una riga per risultato:

ls application.exe -r -ea silentlycontinue | % versioninfo | fl
  • fl è un alias per Format-List

Mi rendo conto che questo è molto simile alla risposta di xcud in questo lse dirsono entrambi alias per Get-ChildItem. Ma spero che il mio metodo "più breve" possa aiutare qualcuno.

L'esempio finale potrebbe essere scritto a lungo nel modo seguente:

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

... ma penso che la mia strada sia più fresca e, per alcuni, più facile da ricordare. (Ma soprattutto più fresco).


11

Un altro modo per farlo è utilizzare la tecnica di accesso ai file integrata:

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

Puoi anche ottenere qualsiasi proprietà particolare da VersionInfo, quindi:

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

Questo è abbastanza vicino alla tecnica dir.


(get-item \\ "$ computerName" \ "C $ \ Programmi \ Symantec AntiVirus \ VPDN_LU.exe"). VersionInfo.FileVersion ha funzionato per me. Avevo bisogno di aggiungere un nome computer da un loop.
Tequila,

7

Questo si basa sulle altre risposte, ma è esattamente quello che cercavo:

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

Sono incuriosito dal Get-Commandapplicato a un file DLL. Potresti approfondire il suo effetto (prima ancora di chiamare la proprietà FileVersionInfo)?
Stephane Rolland,

i file DLL contengono FileVersionInfoesattamente come fanno i file exe. Applicando questo comando al percorso otterrai le informazioni sulla versione del file!
Noelico

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

4

Lo trovo utile:

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
}

È un VBScript?
macetw,

1
No è powershell
Chriseyre2000,

2

Come ha detto EBGreen, [System.Diagnostics.FileVersionInfo] :: GetVersionInfo (path) funzionerà, ma ricorda che puoi anche ottenere tutti i membri di FileVersionInfo, ad esempio:

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

Dovresti essere in grado di utilizzare tutti i membri di FileVersionInfo documentati qui, che ti daranno praticamente tutto ciò che potresti desiderare sul file.


1

Ecco un metodo alternativo. Utilizza Get-WmiObject CIM_DATAFILE per selezionare la versione.

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

utilizzando un percorso di condivisione con spazi nel nome, ho ottenuto "Impossibile trovare la proprietà 'Versione' su questo oggetto. Verificare che la proprietà esista."
AnneTheAgile,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.