Como extrair ProductCode do pacote msi?
-
14-11-2019 - |
Pergunta
Como extrair ProductCode do pacote msi?Quero usá-lo mais tarde para desinstalar o msi via msiexec conforme descrito aqui
Solução
Posso pensar em dezenas de maneiras de fazer isso.Quais linguagens de programação você usa atualmente e/ou com as quais se sente confortável?
Dê uma olhada
Você poderia usar WiRunSQL.vbs (fornecido no Platform SDK) para executar o comando:
cscript /nologo WiRunSQL.vbs FOO.msi "SELECT Value FROM Property WHERE Property = 'ProductCode'"
Outras dicas
Você poderia obter um efeito semelhante fazendo o seguinte no PowerShell com base nos programas instalados:
Get-WmiObject -Class Win32_Product -Filter "Vendor LIKE 'The Company%' AND Name LIKE '%The Product%'" | %{
Write-Host "Uninstalling $($_.IdentifyingNumber)"
$_.Uninstall()
}
(Obviamente, quanto mais precisa a consulta, mais rápido ela será executada - o LIKE acima é muito caro)
Ou você pode se inscrever a técnica geral aqui na sua pilha.
Eu escrevi uma função Powershell que uso ao gerar pacotes Chocolatey baseados em MSI no trabalho, para detectar se nosso pacote interno está instalando um programa que já foi instalado por outros meios:
function Get-MsiProductCode {
[CmdletBinding()]
param (
[Parameter(Mandatory=$true)]
[ValidateScript({$_ | Test-Path -PathType Leaf})]
[string]$Path
)
function Get-Property ( $Object, $PropertyName, [object[]]$ArgumentList ) {
return $Object.GetType().InvokeMember($PropertyName, 'Public, Instance, GetProperty', $null, $Object, $ArgumentList)
}
function Invoke-Method ( $Object, $MethodName, $ArgumentList ) {
return $Object.GetType().InvokeMember( $MethodName, 'Public, Instance, InvokeMethod', $null, $Object, $ArgumentList )
}
$ErrorActionPreference = 'Stop'
Set-StrictMode -Version Latest
#http://msdn.microsoft.com/en-us/library/aa369432(v=vs.85).aspx
$msiOpenDatabaseModeReadOnly = 0
$Installer = New-Object -ComObject WindowsInstaller.Installer
$Database = Invoke-Method $Installer OpenDatabase $Path, $msiOpenDatabaseModeReadOnly
$View = Invoke-Method $Database OpenView "SELECT Value FROM Property WHERE Property='ProductCode'"
[void]( Invoke-Method $View Execute )
$Record = Invoke-Method $View Fetch
if ( $Record ) {
Get-Property $Record StringData 1
}
[void]( Invoke-Method $View Close @() )
Remove-Variable -Name Record, View, Database, Installer
}