2012-01-05 12 views

Respuesta

23

Esto debe de sido una respuesta fácil ... Para empezar instalador de Windows tiene un COM object puede utilizar:

ProgID: WindowsInstaller.Installer

Sin embargo, cuando se crea un objeto de la PowerShell usted no recibe ninguna de las propiedades o métodos:

$object = New-Object -Com WindowsInstaller.Installer 
$object | gm 

... sin :-(

Aparentemente, este es un problema con PowerShell y su sistema de adaptación de tipo. Vea esta publicación en el blog para un trabajo completo.

http://www.snowland.se/2010/02/21/read-msi-information-with-powershell/

Si utiliza VBScript que no debería tener este problema.

EDIT:

He aquí algunos de VBScript que hará que la versión que found:

Const msiOpenDatabaseModeReadOnly = 0 
Dim msi, db, view 

Set msi = CreateObject("WindowsInstaller.Installer") 
Set db = msi.OpenDataBase("C:\Users\andy\Desktop\Module.msi", msiOpenDatabaseModeReadOnly) 
Set view = db.OpenView("SELECT `Value` FROM `Property` WHERE `Property` = 'ProductVersion'") 
Call view.Execute() 

GetVersion = view.Fetch().StringData(1) 
Wscript.Echo GetVersion 

Puede llamar esto desde PowerShell:

$version = & cscript.exe /nologo GetVersion.vbs 

actualización! Este tipo de problema de adaptación me estaba frustrando y no estaba contento con la solución VBS. Después de investigar un poco encontré una forma de hacer esto en PowerShell propiamente dicha. Adapte el código de su blog entry. ¡Disfrutar!

function Get-MsiDatabaseVersion { 
    param (
     [IO.FileInfo] $FilePath 
    ) 

    try { 
     $windowsInstaller = New-Object -com WindowsInstaller.Installer 

     $database = $windowsInstaller.GetType().InvokeMember(
       "OpenDatabase", "InvokeMethod", $Null, 
       $windowsInstaller, @($FilePath.FullName, 0) 
      ) 

     $q = "SELECT Value FROM Property WHERE Property = 'ProductVersion'" 
     $View = $database.GetType().InvokeMember(
       "OpenView", "InvokeMethod", $Null, $database, ($q) 
      ) 

     $View.GetType().InvokeMember("Execute", "InvokeMethod", $Null, $View, $Null) 

     $record = $View.GetType().InvokeMember(
       "Fetch", "InvokeMethod", $Null, $View, $Null 
      ) 

     $productVersion = $record.GetType().InvokeMember(
       "StringData", "GetProperty", $Null, $record, 1 
      ) 

     $View.GetType().InvokeMember("Close", "InvokeMethod", $Null, $View, $Null) 

     return $productVersion 

    } catch { 
     throw "Failed to get MSI file version the error was: {0}." -f $_ 
    } 
} 

Get-MsiDatabaseVersion "C:\Installer.msi" 
+0

Gracias por el comentario en mi respuesta, me quita basado en tu información – JNK

+0

No funciona, aparece un error: Llamada de excepción "InvokeMethod" con "3" argumento (s): "Llamada de excepción" InvokeMember "con" 5 "argumento (s):" OpenDatabase, DatabasePath, OpenMode "" – LeBleu

+0

El código contenía 'citas inteligentes' que pueden haber atrapado a algunas personas, habrás visto el error que tenía @LeBleu, he actualizado el fragmento de código. –

2

(Lo siento, no tienen representante simplemente agregar un comentario a la respuesta aceptada)

La respuesta de @davidmartin fue super útil para mí.

Sólo poco que tenía que añadir era para cerrar el objeto antes de devolver la versión de otro modo un mango se mantiene abierta en el MSI y el acceso posterior puede fallar:

$View.GetType().InvokeMember("Close", "InvokeMethod", $Null, $View, $Null) 

return $productVersion 
Cuestiones relacionadas