¿Cómo puedo encontrar el Código de actualización para un archivo MSI instalado?

En ciertos casos , puede surgir la necesidad de recuperar códigos de actualización de MSI para paquetes implementados .

Escenarios comunes:

  • Me hice cargo del proyecto MSI de otra persona, y necesito determinar qué códigos de actualización se usaron para versiones anteriores que ya están en libertad. Esto es necesario para manejar escenarios de actualización. No tengo ningún archivo de versiones en ningún lado .
  • Accidentalmente cambié el código de actualización para mi paquete de WiX varias veces durante el desarrollo y necesito encontrar todas las versiones de Upgrade Code “in the wild”. No sabía que los códigos de actualización deberían permanecer estables entre versiones .

Esta es una pregunta de estilo Q / A.

Esta pregunta ha aparecido antes en varias encarnaciones, pero esto no es un duplicado . Estoy publicando una forma de hacerlo que utiliza la interfaz de automatización MSI principal (o hablando estrictamente WMI). Debería ser más confiable que los enfoques basados ​​en registro de respuestas anteriores. Esta respuesta también intenta resumir otros enfoques de recuperación.

Recuperación de código de actualización MSI (a través de PowerShell / WMI)

El siguiente script de PowerShell debe recuperar todos los códigos de productos relacionados , códigos de actualización y nombres de productos instalados en su máquina (salida de la tabla).

Captura de pantalla del resultado (guión completo a continuación):

salida powershell

Estos son los valores reales en vivo directamente desde la base de datos de Windows Installer en la máquina en cuestión. No hay necesidad de ninguna conversión o interpretación. Estamos pasando por las API adecuadas.

¡Nota tecnica! : Tenga en cuenta que comprobar propiedades directamente en su archivo MSI original (tabla de propiedades) o archivo fuente WiX puede no coincidir con los valores reales instalados, ya que las propiedades pueden anularse en el momento de la instalación mediante transformaciones (más información a continuación) o valores de propiedad especificados en el comando línea. La moraleja de la historia: recupera los valores de las propiedades directamente del sistema cuando puedas.

Descargo de responsabilidad rápido : en casos excepcionales, ejecutar el script puede desencadenar una reparación automática de Windows Installer. Lea más en la “sección de descargo” a continuación. Solo una molestia potencial, pero lea el descargo de responsabilidad por favor.

Como digresión, también hay un comando de una línea de PowerShell que solo recuperará códigos de productos y códigos de actualización, sin incluir el nombre del paquete. En realidad, esto podría ser suficiente para algunos usuarios (sin embargo, recomendaría la secuencia de comandos completa a continuación). Hay una captura de pantalla de la salida de este one-liner en la sección a continuación. Nota : este comando aparece mucho más rápido que el script más grande (el campo “Valor” es el código de actualización). También tenga en cuenta: los códigos de productos sin códigos de actualización asociados no aparecerán por lo que yo sé; lo harán en el script más grande:

gwmi -Query "SELECT ProductCode,Value FROM Win32_Property WHERE Property='UpgradeCode'" | Format-Table ProductCode,Value 

Para ejecutar el script completo de PowerShell a continuación:

  1. Inicie PowerShell ( mantenga presionada la tecla de Windows, toque R, suelte la tecla de Windows, escriba “powershell” y presione OK o presione enter ).
  2. Copie la secuencia de comandos a continuación en su totalidad, y luego haga clic derecho dentro de la ventana de PowerShell .
  3. Esto debería iniciar el script, y llevará bastante tiempo ejecutarlo .
  4. Por favor reporte cualquier problema. No soy un experto en PowerShell. Soy un especialista en implementación, no un progtwigdor, pero el script debería hacer el trabajo.
  5. Nota de rendimiento : Acabo de obtener todo el objeto Win32_Product WMI
    • Las propiedades de selección de cerezas parecían hacer que fuera marginalmente más lento (prueba de VBScript).
    • Supongo que tenemos que obtener todas las filas de todos modos, ¿y las columnas de recolección de cerezas es solo levantar más?
    • Para Win32_Property filtramos tanto filas como columnas (el código de actualización es solo uno de muchos tipos de filas). Prepárate para una operación lenta, WMI es muy lento.
 $wmipackages = Get-WmiObject -Class win32_product $wmiproperties = gwmi -Query "SELECT ProductCode,Value FROM Win32_Property WHERE Property='UpgradeCode'" $packageinfo = New-Object System.Data.Datatable [void]$packageinfo.Columns.Add("Name") [void]$packageinfo.Columns.Add("ProductCode") [void]$packageinfo.Columns.Add("UpgradeCode") foreach ($package in $wmipackages) { $foundupgradecode = $false # Assume no upgrade code is found foreach ($property in $wmiproperties) { if ($package.IdentifyingNumber -eq $property.ProductCode) { [void]$packageinfo.Rows.Add($package.Name,$package.IdentifyingNumber, $property.Value) $foundupgradecode = $true break } } if(-Not ($foundupgradecode)) { # No upgrade code found, add product code to list [void]$packageinfo.Rows.Add($package.Name,$package.IdentifyingNumber, "") } } $packageinfo | Format-table ProductCode, UpgradeCode, Name # Enable the following line to export to CSV (good for annotation). Set full path in quotes # $packageinfo | Export-Csv "[YourFullWriteablePath]\MsiInfo.csv" # copy this line as well 

Corriendo en máquinas remotas

  • Debería ser relativamente fácil extender el script anterior para ejecutar en máquinas remotas, pero no estoy configurado para probarlo correctamente en este momento.
  • La información a continuación se ha vuelto un poco complicada, avíseme si no es comprensible o no está clara.
  • En un dominio real de Windows debería (en teoría) simplemente ser una cuestión de agregar las máquinas remotas a las llamadas de WMI por sí mismas (y recorrer una lista de máquinas – ver maqueta a continuación). Y lo más importante: debes usar una cuenta de administrador de dominio real para ejecutar la consulta . Es posible que los cambios que enumero a continuación para hacer que WMI funcione en entornos de grupos de trabajo también puedan ser necesarios para algunos dominios, no sé (regla de firewall y ajuste de registro UAC). Sin embargo, supongo que una cuenta de administrador de dominio real debería tener los privilegios y el acceso requeridos.
  • Las conexiones remotas en WMI se ven afectadas por (al menos) Firewall de Windows , configuraciones de DCOM , configuración de CIMOM y control de cuentas de usuario (UAC) (además de factores adicionales que no son de Microsoft, como firewalls reales, firewalls de software de terceros, software de seguridad de varios tipos, etc …). Aquí hay algunos detalles:
    • Configuración de una conexión WMI remota
    • Conexión a WMI de forma remota con PowerShell
  • En las redes que no son de dominio (oficina pequeña, hogar, etc.) probablemente tenga que agregar credenciales de usuario directamente a las llamadas WMI para que funcionen. Y probablemente deba tener “derechos reales de administrador” en las máquinas en cuestión para que las consultas se ejecuten de forma remota en una red doméstica (grupo de trabajo). He oído que la cuenta de administrador integrada no tiene ningún problema de UAC, pero nunca lo he intentado. En mi opinión: no use esta cuenta.
    • En mis pruebas tuve que ( 1 ) actualizar las reglas de firewall de Windows y ( 2 ) desactivar el filtro de token de acceso remoto UAC y usar una cuenta de administrador real y local en el sistema remoto. Tenga en cuenta que no recomiendo ninguno de estos cambios , solo informando lo que funcionó para mí.
    • Cambio 1 : Firewall de Windows, ejecute el comando (cmd.exe, ejecute como admin): netsh advfirewall firewall set rule group="windows management instrumentation (wmi)" new enable=yes ( fuente – vea este enlace para la línea de comando para deshabilitar esta nueva gobierna nuevamente si solo estás probando. Esencialmente solo configura enable = no). Consulte la fuente vinculada para conocer las reglas potencialmente más restrictivas que también podrían funcionar.
    • Cambio 2 : deshabilitar el filtrado de token de acceso UAC remoto: debe establecer el siguiente valor de registro: HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\ LocalAccountTokenFilterPolicy = 1 ( fuente – página intermedia, segunda mitad). Configuré un DWORD de 32 bits.

Con esos cambios en el sistema remoto, también agregué credenciales de usuario a cada llamada al $Cred = Get-Credential al usuario $Cred = Get-Credential . También hay opciones más avanzadas para definir las credenciales del usuario, como se explica aquí: Pasar contraseña a -credential (y aquí ). Para probar la ejecución, aquí hay un pequeño script de prueba. Copie todas las líneas a continuación, modifique el nombre del equipo remoto y pegue en PowerShell haciendo clic con el botón derecho (se le solicitarán las credenciales):

 $Cred = Get-Credential gwmi -ComputerName RemoteMachineName -credential $Cred -Query "SELECT ProductCode,Value FROM Win32_Property WHERE Property='UpgradeCode'" | Format-Table ProductCode,Value # copy this line too 

Para la secuencia de comandos de PowerShell anterior, las adiciones básicas para la ejecución remota en varias máquinas en un dominio de Windows podrían ser algo como esto (no actualizaré la secuencia de comandos anterior ya que no puedo probar esto correctamente). Recuerde actualizar la lista de nombres de equipos remotos en la parte superior de la secuencia de comandos y ejecutarla con una cuenta de administrador de dominio:

 # DOMAIN NETWORK: mock-up / pseudo snippet ONLY - lacks testing, provided "as is" $ArrComputers = "Computer1", "Computer2", "Computer3" foreach ($Computer in $ArrComputers) { # here we modify the WMI calls to add machine name $wmipackages = Get-WmiObject -Class win32_product -ComputerName $Computer $wmiproperties = gwmi -ComputerName $Computer -Query "SELECT ProductCode,Value FROM Win32_Property WHERE Property='UpgradeCode'" # the rest of the above, large script here (minus the first 2 WMI lines) } 

Para adaptar el mismo bucle de máquina para una red que no sea de dominio , puede agregar credenciales a las llamadas de WMI. Algo como esto (se le solicitarán credenciales para cada máquina, lo que puede ser confuso). Recuerde actualizar la lista de nombres de equipos remotos en la parte superior del script y use una cuenta con derechos de administrador local en el cuadro de destino:

 # WORKGROUP NETWORK: mock-up / pseudo snippet ONLY - lacks testing, provided "as is" $ArrComputers = "Computer1", "Computer2", "Computer3" foreach ($Computer in $ArrComputers) { $Cred = Get-Credential # here we modify the WMI calls to add machine name AND credentials $wmipackages = Get-WmiObject -Class win32_product -ComputerName $Computer -credential $cred $wmiproperties = gwmi -ComputerName $Computer -credential $cred -Query "SELECT ProductCode,Value FROM Win32_Property WHERE Property='UpgradeCode'" # the rest of the above, large script here (minus the first 2 WMI lines) } 

La respuesta real termina aquí . Creo que el script más reciente debe cubrir la mayoría de los casos de uso, pero también dejaré el contenido a continuación, ya que no es obsoleto, probablemente sea menos eficiente que el script anterior. Leerlo probablemente sea repetitivo.

Los scripts a continuación para la recuperación de códigos de actualización únicos en lugar de toda la lista, podrían ser de interés si desea recuperar un código de actualización único desde su propia aplicación en tiempo de ejecución. Dejaré ese contenido anterior en.

Descargo de responsabilidad : La secuencia de comandos anterior utiliza WMI, y cuando accede a la clase Win32_Product desencadena una verificación de integridad de los paquetes instalados . Esto es bastante lento y, en casos muy especiales, puede desencadenar una auto reparación de MSI. Esto no es bueno si te diriges a una reunión importante :-). Afortunadamente, debería poder cancelar cualquier auto reparación reparada (pero su consulta probablemente no se completará hasta que termine la reparación). Enlace de contexto rápido (para su custodia).

En mi humilde opinión: no dejes que esto te impida usar WMI, es solo una molestia. Nota: los enfoques de PowerShell y VBScript que se describen a continuación usan WMI y también pueden desencadenar este problema.


Recuperar códigos de actualización para archivos MSI que no están instalados

Si necesita el código de actualización para un paquete MSI que no está instalado en su máquina, lea la sección ” Recuperación manual de códigos de actualización ” en la parte inferior para ver varias opciones (básicamente busque en el archivo MSI o en su archivo fuente utilizado para comstackrlo).

No es seguro obtener el código de actualización de los paquetes instalados del archivo de instalación MSI original o de las fonts (WiX) utilizadas para comstackr el MSI, ya que los códigos de actualización pueden anularse en el momento de la instalación usando transformaciones (detalles en el texto a continuación: transformaciones hay pequeños fragmentos de bases de datos aplicados en el momento de la instalación; consulte el enlace de Symantec para obtener más información).

La recuperación programática de los códigos de actualización se basa en WMI , y puede usar PowerShell o VBScript para invocar WMI . Ambos métodos se presentan a continuación. Esencialmente, la siguiente consulta de WMI se ejecuta para recuperar el código de actualización de un código de producto específico:

 SELECT * FROM Win32_Property WHERE Property='UpgradeCode' AND ProductCode='{YourProdGuid}' 

Es la misma consulta utilizada tanto para VBScript como para PowerShell. También puede ejecutarlo como una consulta WMI directa utilizando una herramienta como WMIExplorer.exe . Una herramienta muy útil, muy recomendable. Creo que este es su sitio: https://github.com/vinaypamnani/wmie2/releases


Recuperar el código de actualización único a través de PowerShell / WMI

En lugar de generar una tabla completa con todos los códigos de productos y códigos de actualización, puede recuperar un código de actualización único para un código de producto específico. Esto es bueno si está intentando realizar la recuperación desde dentro de su propio código de aplicación (entonces es solo una consulta WMI estándar y no tiene nada que ver con PowerShell).

A continuación se muestra la recuperación del código de actualización única realizada a través de PowerShell (para iniciar PowerShell: mantenga presionada la tecla de Windows, toque R, suelte la tecla de Windows, escriba “powershell” y presione OK o presione enter ):

 gwmi -Query "SELECT Value FROM Win32_Property WHERE Property='UpgradeCode' AND ProductCode='{YourGuid}'" | Format-Table Value 

La salida debería ser algo como esto (tal vez un poco difícil de leer, debería haber usado fonts más grandes):

Recuperando el código de actualización usando PowerShell - anotado

El código de producto especificado en la consulta anterior es para ” Windows SDK Intellidocs “. Obviamente debe reemplazarlo con su propio código de producto guid. Para encontrar el código del producto que debe ingresar, también puede usar una consulta de PowerShell como se describe aquí: ¿Cómo puedo encontrar el GUID del producto de una instalación de MSI instalada?

El código de actualización devuelto procede directamente de la base de datos de registro de Windows Installer real. No requiere más procesamiento o interpretación o pasos de conversión manual . También será correcto, incluso si una transformación cambió el código de actualización original cuando se instaló el MSI (detalles sobre los problemas de transformación a continuación).

Actualización, aviso especial : sin complicar las cosas innecesariamente, creo que he encontrado un error en WMI que es muy específico. Cuando un MSI original no tiene un conjunto de códigos de actualización, y usted agrega uno a través de una transformación, entonces WMI no parece informar el código de actualización en absoluto. Sin embargo, si el MSI original tiene un código de actualización y lo sobrescribe en una transformación, WMI informa el código de actualización de la transformación (que se espera). Definitivamente vi esto, pero necesitaré verificar con un paquete de prueba más para estar seguro. La moraleja de la historia : ¡siempre establezca un código de actualización en su MSI! Entonces evitas todo el problema permanentemente. Y no lo genere automáticamente: codifíquelo (lea “Recuperación manual de los códigos de actualización” a continuación para obtener una explicación).


Recupere el código de actualización único usando VBScript / WMI (Legacy Approach)

No hay nada de malo con la solución de VBScript que se encuentra a continuación, incluso tiene algunos beneficios sobre PowerShell , a pesar de que VBScript ya es una tecnología heredada. Los beneficios son que debería funcionar en todas las máquinas, incluso cuando .NET Framework falta (o está bloqueado) y en máquinas donde PowerShell falta (o está bloqueado). Es una solución anticuada pero viable que es bastante flexible (a menos que VBScript también esté bloqueado, pero todas las versiones modernas del SO son totalmente compatibles con VBScript).

Para hacer que sea lo más simple posible recuperar su código de actualización, he creado un ” VBScript desnudo ” que debería ser el truco. No se ha probado su orientación a computadoras remotas, incluso si WMI debería poder hacerlo por diseño. El script está destinado a ejecutarse en el sistema donde está instalado su MSI misterioso con el código de actualización desconocido.

Este VBScript requiere un código de entrada de producto (se muestra el cuadro de diálogo de entrada cuando se ejecuta el script), y luego buscará el código de actualización correspondiente (si corresponde). Como se indicó anteriormente, para ubicar el código de producto para su MSI, puede utilizar este enfoque: ¿Cómo puedo encontrar el GUID del producto de una instalación de MSI instalada? . Una vez que tenga el código de producto (guid), puede ejecutar este VBScript en la máquina de destino y deberá obtener el código de actualización que le devolvieron en unos segundos. La recuperación de WMI puede ser muy lenta.

 ' ' Purpose: Barebone / minimal VBScript implementation to allow retrieval of MSI UpgradeCodes via WMI. ' ' Version: 0.2, September.2017 - Stein Åsmul. ' ' Notes: ' ' - As it stands, this script is intended to be run interactively (WScript). ' - Conversion to run via CScript should be trivial (nothing ever is...) ' - The script will ask the user to provide a valid product GUID for an installed MSI. ' - To find a valid product GUID for your system, perhaps see this SO answer: https://stackoverflow.com/a/29937569/129130 ' - The script does not RegEx anything to check for valid GUID format (this is barebone - as terse as possible, ' with as little as possible included that can break). ' ' UPDATE: for information on remote running, check "Running on remote machines" section here: ' https://stackoverflow.com/a/46637095/129130 (firewall and registry change seems to be needed). strComputer = "." ' Remote connections was NOT tested for this script. In principle you should just add the machine name to "strComputer" above. ' AFAIK you must have "real" admin rights on the box you try to connect to. Many users report intermittent problems running remote WMI. ' Remote connections in WMI are affected by the Windows Firewall, DCOM settings, and User Account Control (UAC). ' - Setting up a Remote WMI Connection: https://msdn.microsoft.com/en-us/library/aa822854(v=vs.85).aspx ' - Connecting to WMI on a Remote Computer: https://msdn.microsoft.com/en-us/library/aa389290(v=vs.85).aspx ' - Perhaps useful: https://social.technet.microsoft.com/Forums/lync/en-US/05205b52-0e43-4ce3-a8b8-58ec4c2edea5/wmi-generic-failure-when-accessing-win32product-remotely?forum=winserverManagement ' - Maybe it is also worth noting that I think WMI queries can be slow enough to trigger timeouts, ' and then you have the old favorite: intermittent bugs. Set owmi = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") ' User interaction productcode = InputBox("Please paste or type in the product code for the product whose upgrade code you want " + _ "to retrieve (not case sensitive, a blank product code will abort the script)." + vbNewLine + vbNewLine + _ "Please note that the script can take up to a minute to run due to WMI's slowness.", "UpgradeCode retrieval:") If productcode = vbCancel Or Trim(productcode) = "" Then WScript.Quit(0) End If ' Run WMI call and verify that it completes successfully. On Error Resume Next Set upgradecode = owmi.ExecQuery("SELECT Value FROM Win32_Property WHERE Property='UpgradeCode' AND ProductCode='" & productcode & "'") If (Err.number <> 0) Then MsgBox "The WMI query failed, this is a critical error - aborting.", vbCritical, "Fatal error." WScript.Quit(2) ' Following exit code "standard" from MSI SDK automation samples End If On Error GoTo 0 ' Report results. Select Case upgradecode.count Case 0 ' We have to provide a separate message for this state, since some packages may not have an UpgradeCode. ' However, the product GUID could also have been misspelled. MsgBox "No UpgradeCode was found, are you sure you entered the correct product GUID?" & vbNewLine & vbNewLine & _ "Note: It is possible for a product to NOT have an UpgradeCode.", vbInformation, "No UpgradeCode found." Case 1 ' The "default state" - should cover almost all normal packages. ' Only one upgrade code should have been retrieved, and it can be referenced by upgradecode.ItemIndex(0).Value on newer systems ' (Vista and later), but on XP this apparently does not work (never tested by me), for compatibility we use a standard For Each ' enumeration instead. Source: https://stackoverflow.com/questions/2378723/get-first-record-from-wmi-execquery For Each u in upgradecode Msgbox "The Upgrade Code is: " & u.Value & vbNewLine & vbNewLine & _ "Just press CTRL + C to copy all text in this dialog (then paste to notepad or similar to extract the GUID).", _ vbInformation, "UpgradeCode found." ' Exit For Next Case Else ' Should never get here - let us know if you do get this message. MsgBox "An error occurred, the query returned more than one result. There can only be one UpgradeCode. " & _ "Please report this error on StackOverflow", vbInformation, "Error while retrieving UpgradeCode." End Select 

Recuperar todos los códigos de actualización y el código del producto en una máquina

Debo mencionar que tengo un VBScript grande que generará un informe HTML completo para todos los paquetes MSI instalados en la máquina en la que se ejecuta . Esto incluye todos los códigos de actualización y una lista de códigos de productos relacionados (códigos de productos que comparten el mismo código de actualización). Sin embargo, no estoy muy contento con el código (soy un especialista en implementación, no un codificador). La secuencia de comandos es demasiado grande, demasiado lenta y no está probada para su uso , por lo que creo el VBScript básico descubierto anteriormente para hacer la recuperación de un solo paquete. Este script es mucho más fácil de probar y modificar para su propio uso. Puedo proporcionar este gran VBScript para probar si es de interés. Es de solo lectura aparte de un único archivo HTML que se envía a “Mis documentos”. Debería ser posible adaptar este script para su uso en computadoras remotas también.

Hay un comando de una línea de PowerShell para recuperar todos los códigos de productos y códigos de actualización relacionados, pero este relleno de salida no tiene el nombre de los productos. Lo incluyo aquí para completarlo:

 gwmi -Query "SELECT ProductCode,Value FROM Win32_Property WHERE Property='UpgradeCode'" | Format-Table ProductCode,Value 

La salida será similar a esto (el campo “Valor” es el código de actualización; los códigos de productos sin los códigos de actualización asociados no aparecerán por lo que yo sé):

salida de todos los códigos de actualización y productos


Recuperación manual de códigos de actualización

Esta sección enumera algunas “formas manuales” para recuperar códigos de actualización que no necesitan ninguna línea de encoding o de comando. Estos enfoques manuales no son los recomendados. Los incluyo solo porque esto intenta ser una ” respuesta de referencia “. Se deben proporcionar varias opciones diferentes. Mi recomendación es usar PowerShell o VBScript provistos arriba.

Una vez dicho esto, los códigos de actualización generalmente nunca cambian en las versiones de su producto, por lo que es probable que intente con el que encuentre en el archivo MSI, o en la fuente utilizada para comstackrlo tal como se describe a continuación. El problema que ya se ha mencionado varias veces es que una transformación puede cambiar los códigos de actualización en el momento de la instalación, por lo que debe recuperar el código de actualización programáticamente si desea asegurarse de encontrar el correcto. A menos que intente obtener el código de actualización de un MSI que no está instalado en su sistema. Entonces solo necesita un visor de archivos MSI como se describe a continuación en el punto 1.

Una transformación es solo un fragmento de base de datos con cambios que se aplican al MSI original en el momento de la instalación . Es una herramienta utilizada principalmente para empaquetar aplicaciones corporativas para modificar instaladores sin modificar los archivos MSI directamente. Las transformaciones tienen la extensión .mst . Cambiar el código de actualización a través de una transformación es inusual, pero no desconocido, especialmente para el reempaquetado corporativo. En casos excepcionales , los empaquetadores de aplicaciones pueden cambiar intencionalmente el GUID de actualización para permitirles entregar sus propias actualizaciones a los paquetes instalados (en lugar de confiar directamente en las actualizaciones del proveedor). Raro, pero lo he visto hecho. Si esto es algo bueno o no es muy discutible.

Maneras fáciles y manuales de encontrar códigos de actualización MSI:

  1. Aunque ofensivamente obvio, la forma más fácil de encontrar el código de actualización es abrir el MSI original utilizado para instalar el producto y encontrar el código de actualización en la tabla de propiedades . Todo lo que necesita es una herramienta capaz de abrir archivos MSI. Aquí hay algunas herramientas: ¿Qué producto de instalación usar? InstallShield, WiX, Wise, instalador avanzado, etc. Probablemente su apuesta más rápida sea Orca si tiene instalado Visual Studio (busque Orca-x86_en-us.msi e instálelo – este es el propio visor y editor oficial de MSI de Microsoft), o Super Orca si no tiene Visual Studio instalado (siga el enlace de arriba para encontrarlo).

  2. Si es un desarrollador que usa WiX (o cualquier otra herramienta de implementación), obviamente puede encontrar el código de actualización fácilmente en su archivo fuente de WiX que utilizó para comstackr su MSI (o fuente de Installshield, fuente de instalación avanzada o cualquier herramienta de implementación que sea utilizando).

    • No nos salgamos de control aquí con demasiados consejos bien intencionados que atestan el problema principal, pero obviamente debe codificar el código de actualización en su fuente, ¡y nunca lo autogenere !
    • Los códigos de actualización definen ” familias de productos relacionados ” y deben permanecer estables en todas las versiones (versiones). En la mayoría de los casos, también debe permanecer estable en todas las versiones de idiomas. La configuración exacta depende de los requisitos de implementación.
    • Si los productos deben poder existir uno al lado del otro, normalmente tiene diferentes códigos de actualización para los productos que necesitan coexistir.
    • Regla general : mantenga los códigos de actualización estables durante el mayor tiempo posible, siempre que sea posible. Cámbialos cuando los requisitos lo exijan absolutamente.
    • Para concluir: nunca use el mismo código de actualización para diferentes productos que tengan su propio ” ciclo de vida ” y no tengan una relación real entre sí. Ellos no están relacionados. Esto es tan importante como mantener estable el código de actualización para productos relacionados. Piense en los requisitos de ” ciclo de vida ” y ” relación familiar ” y ” coexistencia “.
    • Esa fue una gran digresión, volviendo al tema en cuestión: encontrar códigos de actualización.
  3. Incluso si no tiene el MSI original, incluso es posible ubicar el MSI en caché de la instalación original en la %SystemRoot%\Installer . Los archivos MSI aquí tienen un misterioso nombre hexadecimal, pero son solo copias de los archivos MSI originales utilizados para instalar los diferentes productos, almacenados en un lugar seguro para estar disponibles para las operaciones de modificación, reparación y desinstalación. Hagas lo que hagas, no te metas en esta carpeta. Nunca, nunca borres nada . Puede encontrar el MSI que instaló su producto seleccionando el primer archivo MSI y comprobando la barra de estado del Explorador de Windows cuál es el nombre del producto para la versión anterior de Windows. En Windows 10, parece que puede pasar el puntero sobre una MSI y obtener una ventana emergente con algunos detalles de MSI. A continuación, haga clic en la lista hasta encontrar el producto correcto, abra el MSI y busque el código de actualización en la tabla de propiedades .

  4. Algunas personas usan el registro para leer los códigos de actualización: ¿Cómo puedo encontrar el código de actualización para una aplicación instalada en C #? . En mi opinión, este no es un buen enfoque, hay mejores formas, como usar PowerShell como se explicó anteriormente. No es necesario realizar toda esta conversión e interpretación de GUID empaquetados (que es el formato GUID utilizado en la base de datos de registro de Windows Installer).

Eso debería completar los “métodos manuales” primarios para recuperar un código de actualización rápidamente. Solo algunos métodos para el arsenal que a veces son lo suficientemente buenos. Probablemente haya varias formas más que he olvidado.

Prefiere los enfoques programáticos , pero si tiene prisa y trabaja sin todas sus herramientas disponibles, algunas opciones manuales son buenas. Sin embargo, algunos de estos métodos manuales requieren más herramientas que la línea de comandos de PowerShell (necesita un visor de archivos MSI que no siempre está disponible en la caja si se encuentra en una “misión de soporte” a la máquina de alguien). Ha llegado el momento de usar PowerShell (sí, me siento desactualizado también).

A propósito, los archivos MSI son esencialmente desmantelados en bases de datos SQL Server almacenadas como archivos de almacenamiento estructurados por COM (formato de archivo MS Office). Esencialmente un sistema de archivos dentro de un archivo con flujos de almacenamiento de varios tipos.

Si está atascado en una máquina sin un visor MSI, puede consultar bases de datos MSI en caché directamente desde PowerShell: