Skip to content

Comment trouver le code de mise à niveau d'un fichier MSI installé ?

Cette division a été évaluée par des experts pour garantir l'exactitude de notre examen.

Solution :

Récupération du code de mise à niveau MSI (via PowerShell / WMI).

Désinstallation ?: Via Upgrade Code, Via Product Code, Via Product Name, etc...

Le site script PowerShell ci-dessous devrait récupérer tous les codes de produits, codes de mise à niveau et noms de produits installés sur votre machine (sortie tableau).

Capture d'écran de sortie (script complet ci-dessous) :

Sortie PowerShell

Ce sont les valeurs réelles, vivantes directement de la base de données de Windows Installer sur la machine en question. Il n'y a pas besoin de conversion ou d'interprétation. Nous passons par les API appropriées.

Note technique !: Soyez conscient que la vérification des propriétés directement dans votre fichier MSI d'origine (table des propriétés) ou dans le fichier source WiX, peut ne pas correspondre aux valeurs réelles installées puisque les propriétés peuvent être remplacées au moment de l'installation via des transformations (plus d'infos ci-dessous) - ou des valeurs de propriétés spécifiées à la ligne de commande. La morale de l'histoire : récupérez les valeurs de propriété directement à partir du système quand vous le pouvez.

Avertissement rapide: Dans de rares cas, l'exécution du script peut déclencher une auto-réparation de Windows Installer. Lire la suite dans la section "disclaimer"
ci-dessous. Juste une nuisance potentielle, mais lisez le disclaimer s'il vous plaît.

En guise de digression, il y a également une commande PowerShell en une ligne qui récupérera les codes de produit et les codes de mise à niveau uniquement - sans le nom du paquet inclus. Cela pourrait en fait suffire pour certains utilisateurs (je recommanderais cependant le script complet ci-dessous). Il y a une capture d'écran de la sortie de ce one-liner dans une section ci-dessous. Note: cette commande apparaît beaucoup plus rapide que le script plus grand (le champ "Valeur" est le code de mise à niveau). A noter également : les codes produits sans codes de mise à niveau associés n'apparaîtront pas, pour autant que je sache - ils apparaîtront dans le script plus grand :

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

Pour exécuter le script PowerShell complet ci-dessous :

  1. Lancez PowerShell (maintenez la touche Windows enfoncée, tapez sur R, relâchez la touche Windows, tapez "powershell" et appuyez sur OK ou tapez sur entrée.).
  2. Copiez le script ci-dessous dans son intégralité, puis juste un clic droit à l'intérieur de la fenêtre PowerShell.
  3. Cela devrait démarrer le script, et il prendra un certain temps pour s'exécuter.
  4. Veuillez signaler tout problème. Je ne suis pas un expert de PowerShell - je suis un spécialiste du déploiement pas un codeur, mais le script devrait faire le travail.
  5. Note sur les performances: J'ai juste l'ensemble Win32_Produit Objet WMI
    • Le cherry picking des propriétés semblait en fait le rendre marginalement plus lent (test VBScript).
    • Je suppose que nous devons obtenir toutes les lignes de toute façon, et cherry picking colonnes est juste une levée supplémentaire ?
    • Pour Win32_Property nous filtrons à la fois les lignes et les colonnes (le code de mise à niveau n'est qu'un des nombreux types de lignes). Préparez-vous à une opération lente, WMI est très lent.
$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 | Sort-Object -Property Name | 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

Exécution sur des machines distantes

  • Il devrait être relativement facile d'étendre le script ci-dessus pour l'exécuter sur des machines distantes, mais je ne suis pas configuré pour le tester correctement pour le moment.
  • L'information ci-dessous est devenue un peu désordonnée, faites-moi savoir si elle n'est pas compréhensible ou pas claire.
  • Dans un vrai domaine Windows il devrait (en théorie) suffire d'ajouter les machines distantes aux appels WMI eux-mêmes (et de boucler sur une liste de machines - voir la maquette ci-dessous). Et de manière cruciale : vous devez utiliser un vrai compte admin de domaine pour exécuter la requête.. Il est possible que les modifications que j'énumère ci-dessous pour que WMI fonctionne dans les environnements de groupe de travail soient également nécessaires pour certains domaines, je ne sais pas (règle de pare-feu et tweak de registre UAC). Je suppose qu'un véritable compte administrateur de domaine devrait avoir les privilèges et l'accès requis cependant.
  • Les connexions à distance dans WMI sont affectées par (au moins) le système de gestion de la sécurité. Pare-feu Windows, paramètres DCOM, Paramètres CIMOM et Contrôle de compte d'utilisateur (UAC) (plus tous les facteurs supplémentaires non-Microsoft - par exemple les vrais pare-feu, les pare-feu logiciels tiers, les logiciels de sécurité de diverses sortes, etc...). Voici quelques détails :
    • Configuration d'une connexion WMI à distance
    • Se connecter à WMI à distance avec PowerShell
  • Dans réseaux non-domaines (petit bureau, domicile, etc...), vous devez probablement ajouter les informations d'identification des utilisateurs directement aux appels WMI pour que cela fonctionne. Et vous devez probablement avoir des "droits d'administrateur réels" sur les machines en question pour que les requêtes s'exécutent à distance dans un réseau domestique (groupe de travail). J'ai entendu dire que le compte Administrateur intégré n'avait pas de problèmes d'UAC, mais je ne l'ai jamais essayé. A mon avis : n'utilisez pas ce compte.
    • Dans mes tests J'ai dû (1) mettre à jour les règles du pare-feu de Windows et (2) désactivez le filtrage des jetons d'accès UAC à distance et utilisez un vrai compte administrateur local sur le système distant. Notez que Je ne recommande aucun de ces changements, je ne fais que rapporter ce qui a fonctionné pour moi.
    • Changement 1: Pare-feu Windows, exécuter la commande (cmd.exe, exécuter en tant qu'admin) : netsh advfirewall firewall set rule group="windows management instrumentation (wmi)" new enable=yes (source - voir ce lien pour la ligne de commande pour désactiver cette nouvelle règle à nouveau si vous êtes juste en train de tester. Essentiellement, il suffit de définir enable=no). Voir la source liée pour des règles potentiellement plus restrictives qui pourraient également fonctionner.
    • Changement 2: Désactiver le filtrage des jetons d'accès UAC à distance : vous devez définir la valeur de registre suivante : HKLMSOFTWAREMicrosoftWindowsCurrentVersionPoliciesSystem LocalAccountTokenFilterPolicy = 1 (source - milieu de page, dernière moitié). J'ai défini un DWORD de 32 bits.

Avec ces changements en place sur le système distant, j'ai également ajouté les informations d'identification de l'utilisateur à chaque appel en invitant l'utilisateur. $Cred = Get-Credential. Il existe également des options plus avancées pour définir les informations d'identification de l'utilisateur, comme expliqué ici : Passer le mot de passe dans -credential (et ici). Pour tester l'exécution, voici un petit script de test. Copiez toutes les lignes ci-dessous, modifiez le nom de la machine distante et collez dans PowerShell en faisant un clic droit (vous serez invité à fournir des informations d'identification) :

$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

Pour le grand script PowerShell ci-dessus, les ajouts de base pour l'exécution à distance sur plusieurs machines dans un... domaine Windows, pourrait être quelque chose comme ceci (je ne mettrai pas à jour le script ci-dessus car je ne peux pas vraiment tester cela correctement). N'oubliez pas de mettre à jour la liste des noms d'ordinateurs distants en haut du script et de l'exécuter avec un compte administrateur de domaine :

# 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)
}

Pour adapter la même boucle de machine pour un réseau sans domaine vous pouvez ajouter des informations d'identification aux appels WMI. Quelque chose comme ceci (vous serez invité à fournir des informations d'identification pour chaque machine - ce qui pourrait être déroutant). N'oubliez pas de mettre à jour la liste des noms d'ordinateurs distants en haut du script et d'utiliser un compte avec des droits d'administrateur local sur la machine cible :

# 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 vraie réponse se termine ici. Je pense que le script plus récent ci-dessus devrait couvrir la plupart des cas d'utilisation, mais je vais laisser le contenu ci-dessous ainsi car il n'est pas obsolète, juste probablement moins efficace que le script ci-dessus. Le lire sera probablement répétitif.

Les scripts ci-dessous pour la récupération de codes de mise à niveau uniques plutôt que la liste entière, pourraient être intéressants si vous voulez récupérer un seul code de mise à niveau à partir de votre propre application au moment de l'exécution. Je laisse ce contenu plus ancien.

Disclaimer: Le script ci-dessus utilise WMI, et lorsque vous accédez à la classe Win32_Produit il déclenche un
vérification de l'intégrité des paquets installés. Ceci est assez lent, et peut dans
cas très particuliers déclencher une auto-réparation de MSI. Ce n'est pas une bonne chose si vous vous
une réunion importante :-). Heureusement, vous devriez pouvoir
d'annuler les autoréparations déclenchées (mais votre requête ne sera probablement pas
que vous avez laissé la réparation se terminer). Lien contextuel rapide (à conserver précieusement).

IMHO : ne laissez pas cela vous empêcher d'utiliser WMI - c'est juste une
gêne. Remarque : les deux approches PowerShell et VBScript décrites ci-dessous utilisent WMI et peuvent également déclencher ce problème.


Récupération des codes de mise à niveau pour les fichiers MSI qui ne sont pas installés.

Si vous avez besoin du code de mise à niveau d'un paquet MSI qui est... pas installé sur votre machine, veuillez lire le "Récupération manuelle des codes de mise à niveau" vers le bas pour plusieurs options (essentiellement regarder dans le fichier MSI lui-même, ou son fichier source utilisé pour le compiler).

Il n'est pas sûr d'obtenir le code de mise à niveau pour... paquets installés à partir du fichier d'installation MSI original lui-même ou à partir des sources (WiX) utilisées pour compiler le MSI, car les codes de mise à niveau peuvent être remplacés au moment de l'installation à l'aide de transformations. (détails dans le texte ci-dessous - les transformations sont de petits fragments de base de données appliqués au moment de l'installation, voir ce lien Symantec pour plus de détails).

La récupération programmatique des codes de mise à niveau s'appuie sur... WMI et vous pouvez utiliser soit PowerShell ou VBScript pour invoquer WMI. Les deux méthodes sont présentées ci-dessous. Pour l'essentiel, il s'agit de Requête WMI est exécutée pour récupérer le code de mise à niveau pour un code produit spécifié :

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

Il s'agit de la même requête utilisée à la fois pour VBScript et PowerShell. Vous pouvez également l'exécuter en tant que requête WMI directe à l'aide d'un outil tel que . WMIExplorer.exe. Un outil très utile - fortement recommandé. Je crois que c'est leur site : https://github.com/vinaypamnani/wmie2/releases


Récupérer le code de mise à niveau unique via PowerShell / WMI.

Plutôt que de sortir un tableau entier avec tous les codes de produits et les codes de mise à niveau, vous pouvez... récupérer un seul code de mise à niveau. pour un code produit donné. C'est une bonne chose si vous essayez d'effectuer la récupération à partir de votre propre code d'application (il s'agit alors simplement d'une requête WMI standard et cela n'a rien à voir avec PowerShell).

Ci-dessous, la récupération du code de mise à niveau unique effectuée via PowerShell (pour lancer PowerShell : maintenez la touche Windows enfoncée, appuyez sur R, relâchez la touche Windows, tapez "powershell" et appuyez sur OK ou tapez sur entrée.):

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

La sortie devrait être quelque chose comme ceci (peut-être un peu difficile à lire, j'aurais dû utiliser des polices plus grandes) :

Récupération du code de mise à niveau à l'aide de PowerShell - Annoted

Le code produit spécifié dans la requête ci-dessus est pour "Windows SDK Intellidocs". Vous devez évidemment le remplacer par votre propre guide de code produit. Pour trouver le code produit que vous devez transmettre, vous pouvez également utiliser une requête PowerShell comme décrit ici : Comment puis-je trouver le GUID du produit d'une installation MSI installée ?

Le code de mise à niveau renvoyé provient directement de la véritable base de données du registre Windows Installer. Il ne nécessite aucun autre traitement ou interprétation ou étape de conversion manuelle.. Il sera également correct, même si une transformation a modifié le code de mise à niveau d'origine lors de l'installation du MSI (détails sur les problèmes de transformation ci-dessous).

Mise à jour, avis spécial: Sans compliquer inutilement les choses, je crois avoir trouvé un bug dans WMI qui est très spécifique. Lorsqu'un MSI original n'a pas de code de mise à niveau défini, et que vous en ajoutez un via une transformation, alors WMI ne semble pas du tout signaler le code de mise à niveau. Cependant, si le MSI d'origine possède un code de mise à niveau et que vous le remplacez par une transformation, WMI signale le code de mise à niveau de la transformation (ce qui est attendu). J'ai définitivement vu cela, mais devra vérifier avec un autre paquet de test pour être sûr. La morale de l'histoire: toujours définir un code de mise à niveau dans votre MSI ! Ensuite, vous évitez tout le problème de façon permanente. Et ne le générez pas automatiquement - codez-le en dur (lisez "Récupération manuelle des codes de mise à niveau" ci-dessous pour une explication).


Récupérer un code de mise à niveau unique en utilisant VBScript / WMI (approche héritée).

Il n'y a rien de mal avec la solution VBScript trouvée ci-dessous - elle présente même certains avantages par rapport à PowerShell. - bien que VBScript soit désormais une technologie héritée. Les avantages sont qu'elle devrait fonctionner sur toutes les machines, même lorsque le cadre .NET est absent (ou verrouillé), et sur les machines où PowerShell est absent (ou verrouillé). C'est une solution datée, mais viable et assez flexible (à moins que VBScript ne soit également verrouillé, mais toutes les versions modernes de l'OS supportent pleinement VBScript).

Afin de rendre aussi simple que possible la récupération de votre code de mise à niveau, j'ai créé un "bare-bone VBScript" qui devrait faire l'affaire. Il n'a pas été testé pour cibler des ordinateurs distants, même si WMI devrait être capable de le faire par conception. Le script est destiné à être exécuté sur le système où votre MSI mystère avec le code de mise à niveau inconnu est installé.

Ce VBScript nécessite un code produit en entrée (dialogue de saisie affiché lors de l'exécution du script), et il procédera ensuite à la recherche du code de mise à niveau correspondant (le cas échéant). Comme indiqué ci-dessus, pour localiser le code produit de votre MSI, vous pouvez utiliser cette approche : Comment puis-je trouver le GUID du produit d'une installation MSI installée ?. Une fois que vous avez le code produit (guid), vous pouvez exécuter ce VBScript sur la machine cible et vous devriez obtenir le code de mise à niveau retourné en quelques secondes. La récupération de WMI peut être très lente.

'
' 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 & "rootcimv2")

' 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

Récupération de tous les codes de mise à niveau et du code produit sur une machine.

Je dois mentionner que j'ai un grand VBScript qui va générer un
rapport HTML complet pour tous les paquets MSI installés sur la
machine sur laquelle il s'exécute
. Cela comprend tous les code de mise à niveau et une liste de
codes produits (codes produits qui partagent le même code de mise à niveau). Cependant, je ne suis pas trop satisfait du code (je suis un spécialiste du déploiement, pas un codeur). Le script
est trop volumineux, trop lent et trop peu testé pour être utilisé donc je crée
le VBScript de base trouvé ci-dessus pour faire la récupération d'un seul paquet.
paquet seulement. Ce script est beaucoup plus facile à tester et à modifier pour votre
propre utilisation.
Je peux fournir ce grand VBScript pour le tester si cela vous intéresse. Il est en lecture seule à l'exception d'un seul fichier HTML sorti dans "Mes documents". Il devrait être possible d'adapter ce script pour l'utiliser également sur des ordinateurs distants.

Il y a un commande PowerShell en une ligne pour récupérer tous les codes de produits et les codes de mise à niveau associés, mais ce remplissage de sortie manque le nom des produits. Je l'inclus ici par souci d'exhaustivité :

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

La sortie sera similaire à ceci (le champ "Value" est le code de mise à niveau - les codes de produits sans codes de mise à niveau associés n'apparaîtront pas, pour autant que je puisse dire) :

Sortie de tous les codes de mise à niveau et codes de produit


Récupération manuelle des codes de mise à niveau

Cette section énumère quelques "méthodes manuelles" pour récupérer les codes de mise à niveau qui ne nécessitent aucun codage ou ligne de commande. Ces approches manuelles sont pas celles qui sont recommandées. Je les inclus seulement parce que ceci tente d'être une "réponse de référence". Plusieurs options différentes devraient être fournies. Ma recommandation est d'utiliser le PowerShell ou le VBScript fourni ci-dessus.

Cela étant dit, les codes de mise à niveau ne devraient généralement jamais changer d'une version à l'autre de votre produit, il y a donc de fortes chances que vous puissiez essayer celui que vous trouvez dans le fichier MSI lui-même, ou dans la source utilisée pour le compiler, comme décrit ci-dessous. Le problème qui a déjà été mentionné à plusieurs reprises est qu'une transformation peut changer les codes de mise à niveau au moment de l'installation, vous devez donc récupérer le code de mise à niveau par programme si vous voulez être sûr de trouver le bon. À moins que vous n'essayiez d'obtenir le code de mise à niveau à partir d'un MSI qui n'est pas installé sur votre système. Dans ce cas, vous avez juste besoin d'un visualiseur de fichiers MSI comme décrit ci-dessous au point 1.

A transformer est juste une fragment de base de données avec des changements qui sont appliqués au MSI original au moment de l'installation.. C'est un outil principalement utilisé pour le packaging d'applications d'entreprise pour modifier les installateurs sans modifier directement les fichiers MSI. Les transformations ont l'extension .mst. La modification du code de mise à niveau via une transformation est inhabituelle, mais pas inédite - notamment pour le reconditionnement d'entreprise. Dans rares cas les empaqueteurs d'applications peuvent intentionnellement modifier le guide de mise à niveau pour leur permettre de livrer leurs propres mises à niveau aux paquets installés (au lieu de s'appuyer directement sur les mises à jour du fournisseur). C'est rare, mais je l'ai vu faire. Que ce soit une bonne chose ou non est très discutable.

Facile, moyens manuels pour trouver les codes de mise à jour MSI :

  1. Bien qu'offensivement évidente, la façon la plus simple de trouver le code de mise à niveau est de... ouvrir le MSI original utilisé pour installer le produit et trouver le code de mise à niveau dans le tableau des propriétés. Tout ce dont vous avez besoin est un outil capable d'ouvrir les fichiers MSI. Voici quelques outils : Quel produit d'installation utiliser ? InstallShield, WiX, Wise, Advanced Installer, etc. Votre pari le plus rapide est probablement Orca si vous avez Visual Studio d'installé (chercher Orca-x86_en-us.msi et installez-le - il s'agit du visualiseur et éditeur MSI propre et officiel de Microsoft), ou Super Orca si vous n'avez pas Visual Studio installé (suivez le lien ci-dessus pour le trouver).

  2. Si vous êtes un développeur utilisant WiX (ou tout autre outil de déploiement), vous pouvez évidemment... trouver facilement le code de mise à niveau dans votre fichier source WiX. que vous avez utilisé pour compiler votre MSI (ou source Installshield, source Advanced Installer, ou tout autre outil de déploiement que vous utilisez).

    • Ne nous envolons pas ici avec trop de conseils bien intentionnés qui encombrent la question principale, mais vous devriez évidemment... coder en dur le code de mise à niveau dans votre source, et ne jamais l'auto-générer!
    • Les codes de mise à niveau définissent "des familles de produits apparentés" et devraient rester stables d'une version à l'autre (versions). Dans la plupart des cas, ils devraient également rester stables entre les versions linguistiques. La configuration exacte dépend des exigences de déploiement.
    • Si les produits doivent pouvoir exister côte à côte, vous avez généralement des codes de mise à niveau différents pour les produits qui doivent coexister.
    • Règle de base: gardez les codes de mise à niveau stables aussi longtemps que possible, chaque fois que c'est possible. Changez-les lorsque les besoins l'exigent absolument.
    • Pour conclure : n'utilisez jamais le même code de mise à niveau pour différents produits qui ont leurs propres "cycle de vie" et aucune relation réelle entre eux. Ils ne sont pas liés. C'est tout aussi important que de garder votre code de mise à niveau stable pour les produits connexes. Pensez "cycle de vie" et "relation de famille" et "coexistence".
    • C'était une grande digression, revenons à la question qui nous occupe : trouver les codes de mise à niveau.
  3. Même si vous n'avez pas le MSI original, il est même possible de localiser le code de mise à niveau. MSI en cache de l'installation originale dans le répertoire %SystemRoot%Installer dossier. Les fichiers MSI ici ont un nom hexagonal mystérieux, mais ils ne sont que des copies des fichiers MSI originaux utilisés pour installer les différents produits - mis en cache dans un endroit sûr pour être disponibles pour les opérations de modification, de réparation et de désinstallation. Quoi que vous fassiez, ne faites pas n'importe quoi dans ce dossier. Ne supprimez jamais, jamais rien. Vous pouvez trouver le MSI qui a installé votre produit en sélectionnant le premier fichier MSI, et en vérifiant dans la barre d'état de l'Explorateur Windows quel est le nom du produit pour les anciennes versions de Windows. Dans Windows 10, il semble que vous pouvez survoler un MSI avec le pointeur et vous obtenez une fenêtre contextuelle avec certains détails du MSI. Il suffit ensuite de cliquer dans la liste jusqu'à ce que vous trouviez le bon produit, d'ouvrir le MSI et de trouver le code de mise à niveau dans le champ Tableau des propriétés.

  4. Certaines personnes utilisent le registre pour lire les codes de mise à niveau : Comment trouver le code de mise à niveau d'une application installée en C# ? À mon avis, ce n'est pas une bonne approche, il y a de meilleures façons - comme simplement utiliser PowerShell comme expliqué ci-dessus. Il n'y a pas besoin de toute cette conversion et interprétation de GUIDs emballés (qui est le format GUID utilisé dans la base de données du registre de Windows Installer).

Voilà qui devrait compléter les principales "méthodes manuelles" pour récupérer rapidement un code de mise à niveau. Juste quelques méthodes pour l'arsenal qui sont parfois assez bonnes. Il y a probablement plusieurs autres façons que j'ai oubliées.

Préférez-vous les approches programmatiques, mais si vous êtes pressé et que vous travaillez sans tous vos outils disponibles, certaines options manuelles sont bonnes. Cependant, certaines de ces méthodes manuelles nécessitent plus d'outils que la ligne de commande PowerShell (vous avez besoin d'un visualiseur de fichiers MSI qui n'est pas toujours disponible sur la machine si vous êtes en "mission de support" sur la machine de quelqu'un). Le temps est venu d'utiliser PowerShell (oui, je me sens aussi dépassé).

Incidemment, les fichiers MSI sont essentiellement des bases de données SQL Server dépouillées stockées en tant que fichiers de stockage structurés COM (format de fichier MS Office). Essentiellement, un système de fichiers dans un fichier avec des flux de stockage de différents types.

Si vous êtes coincé sur une machine sans visionneur MSI, vous pouvez interroger les bases de données MSI mises en cache directement à partir de PowerShell :

  • https://gallery.technet.microsoft.com/scriptcenter/Get-MsiDatabaseProperties-09d9c87c
  • http://www.adamtheautomator.com/powershell-windows-installer-msi-properties/

Si vous vous sentez invité, vous pouvez laisser un avis sur ce que vous ajouteriez à cet essai.



Utilisez notre moteur de recherche

Ricerca
Generic filters

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.