Un fichier .msi peut-il s’installer lui-même (probablement via une action personnalisée)?

StackOverflow https://stackoverflow.com/questions/88078

  •  01-07-2019
  •  | 
  •  

Question

Je souhaite construire un fichier MSI qui, lors de son processus d'installation, se déploiera lui-même avec ses fichiers / composants contenus dans le répertoire cible.

Ainsi, MyApp.msi contient MyApp.exe et MyAppBootstrapperEmpty.exe (sans ressources) dans sa table de fichiers.

L'utilisateur lance un fichier MyAppBootstrapperPackaged.exe (contenant MyApp.msi en tant que ressource, obtenue quelque part sur Internet, par courrier électronique ou autrement). MyAppBootStrapperPackaged.exe extrait MyApp.msi dans un dossier temporaire et l’exécute via msiexec.exe.

Une fois le processus msiexec.exe terminé, je souhaite utiliser MyApp.msi, MyBootstrapperEmpty.exe (ET MyApp.exe dans le dossier% ProgramFiles% \ MyApp afin de garantir à MyApp.exe l'accès à MyApp.msi lors de son exécution (pour la création). contenu emballé mentionné ci-dessous).

MyAppBootstrapper * .exe pourrait essayer de copier MyApp.msi dans le dossier% ProgramFiles% \ MyApp, mais aurait besoin d'une élévation pour le faire et ne permettrait pas sa suppression via le processus de désinstallation de Windows Installer (depuis Ajout / Suppression de programmes ou autre ), qui devrait être préservé.

Évidemment (je pense que c'est évident - est-ce que je me trompe?) Je ne peux pas inclure l'IDM en tant que fichier dans mon dossier Media / CAB (scénario de la poule et de l'œuf). Je pense donc que cela devrait se faire via une action personnalisée. avant le processus d'installation, ajoutez le MSI d'origine au support / CAB de la base de données MSI et à l'entrée appropriée dans la table des fichiers à la volée. Cela peut-il être fait et si oui comment?

Imaginez un modèle de distribution de contenu dans lequel les fichiers de contenu ne doivent être distribués qu’avec l'application. Le contenu est produit par l'utilisateur final via l'application au moment de l'exécution, puis intégré dans un fichier EXE distribuable comprenant à la fois l'application et le contenu.

Le programme d'installation de MyApp doit rester un MSI, mais peut être exécuté par un EXE Bootstrapper. MyApp.exe installé doit avoir accès à MyApp.msi et le fichier EXE doit être "assemblé". au moment de l'exécution par l'application à partir d'une base (vide) MyAppBootstrapper.exe, qui est également installée par le MSI, ainsi que du contenu créé par l'utilisateur final. Le MSI de la ressource EXE doit être identique à celui utilisé pour installer l’application qui exécute le packaging.

WIX ne doit pas être installé avec MyApp.

Il ne peut y avoir de dépendance du réseau au moment de l'exécution / de l'emballage (c'est-à-dire que l'empaquetage ne peut pas être effectué via un Webservice - doit être effectué localement).

Je connais (et utilise) les actions personnalisées (gérées et non gérées, via DTF ou autre).

Était-ce utile?

La solution

Ajoutez un média non compressé à votre wx comme ceci:

<Media Id='2'/>

Et créez ensuite un composant avec un élément File comme ceci:

<File Source='/path/to/myinstaller.msi' Compressed='no' DiskId='2' />

Le programme d’installation recherchera un fichier appelé "myinstaller.msi " sur le support d'installation, dans le même dossier que le msi en cours d'installation. Le chemin source ci-dessus devrait pointer vers un fichier factice, il n’est là que pour apaiser wix.

Modifier : l'exemple de test.wxs suivant montre son fonctionnement. Il produit un fichier test.msi qui s’installe sous c: \ program files \ test. Notez que vous devez placer un fichier test.msi factice dans le même dossier que text.wxs pour apaiser wix.

<?xml version='1.0' encoding='utf-8'?>
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>
   <Product
         Name='ProductName'
         Id='*'
         Language='1033'
         Version='0.0.1'
         Manufacturer='ManufacturerName' >
      <Package
            Keywords='Installer'
            Description='Installer which installs itself'
            Manufacturer='ManufactererName'
            InstallerVersion='100'
            Languages='1033'
            Compressed='yes'
            SummaryCodepage='1252'/>

      <Media Id='1' Cabinet='test.cab' EmbedCab='yes'/> 
      <Media Id='2' /> 

      <Directory Id='TARGETDIR' Name="SourceDir">
         <Directory Id='ProgramFilesFolder'>
            <Directory Id='TestFolder' Name='Test' >
               <Component Id="InstallMyself">
                  <File Source="./test.msi" Compressed="no" DiskId="2" />
               </Component>
            </Directory>
         </Directory>
      </Directory>

      <Feature
            Id='Complete'
            Display='expand'
            Level='1'
            Title='Copy msi file to program files folder'
            Description='Test'>

         <ComponentRef Id="InstallMyself" />
      </Feature>

   </Product>
</Wix>

Autres conseils

Avec un package .MSI, lancez un autre package .MSI à partir de " dans les " elle-même s'appelle une installation imbriquée , et il s'agit d'un bad juju (voir règle 20). Windows Installer utilise certaines données globales pour gérer l’installation en cours et ne gère pas correctement plusieurs installations en même temps. Pour la même raison, si vous démarrez une installation et essayez d’en démarrer une autre pendant que la première est toujours en cours, vous verrez généralement apparaître une fenêtre s’affichant sous l’effet de "Une autre installation en cours, attendez qu’elle soit terminée". .

Vous pouvez avoir un programme, généralement appelé bootstrapper (je pense que c’est ce à quoi vous faites allusion) qui n’est pas en soi un package d’installation, mais qui contient un package d’installation (tel qu’un. MSI ou un fichier .exe) en tant que ressource, éventuellement compressée. L'action du programme d'amorçage consiste à extraire / développer la ressource dans un fichier, généralement dans un répertoire % TEMP% , puis à lancer le fichier .EXE extrait ou à exécuter MSIEXEC sur le fichier .MSI extrait. Le programme d'amorçage peut contenir plusieurs ressources et les extraire et les installer une par une, si vous devez installer les conditions préalables avant le package principal. Vous pouvez également expédier plusieurs packages sous forme de fichiers distincts et demander au programme de démarrage de les exécuter / les installer directement à partir du support de distribution, ou de les copier sur la machine cible et d'exécuter la série d'installation à partir de cet emplacement, ou ...

WiX lui-même n'est pas installé, non. C'est un outil avec lequel les packages .MSI peuvent être construits. Le projet WiX a sur sa liste de souhaits un programme d’amorçage générique, mais il n’a pas encore été implémenté. Il existe d’autres bootstrappers disponibles, par exemple. celui-ci .

Vous n'aurez pas besoin d'une action personnalisée. En fait, le programme d'amorçage n'étant pas lui-même un package d'installation Windows Installer, une action personnalisée " n'a aucun sens à cela. Et, si vous connaissez suffisamment les autorités de certification pour connaître le fichier DTF géré / non géré, vous en savez suffisamment pour éviter les actions personnalisées chaque fois que vous le pouvez. (sourire)

Je pense qu'il est beaucoup plus facile pour votre programme d'amorçage d'extraire le fichier MSI vers un emplacement prédéfini plutôt que vers le dossier temp. Par exemple, dans C: \ Documents and Settings \ Tous les utilisateurs \ Application Data \ Ma société \ Cache d'installation de mon produit. Une fois l’installation terminée, le fichier de démarrage laisserait le fichier MSI à cet emplacement. Si, à un moment donné, l’utilisateur décide de réinstaller votre produit, Windows Installer pourra localiser le fichier MSI source.

Ajoutez également le chemin d'accès à ce fichier dans le table RemoveFile afin qu'il soit supprimé lors de la désinstallation. Vous pouvez utiliser cet élément RemoveFile dans WiX pour cela.

Donc, si je comprends bien, je pense que l’application devrait créer une transformation (MST) contenant les fichiers de contenu et l’appliquer au MSI de base. Je ne suis toujours pas convaincu de comprendre cependant. :)

Je configurerais le chemin du cache MSI vers un emplacement connu.

Puis au moment de l'exécution si vous avez besoin de " éditer " MSI utilise VBScript ou similaire.

Mais je demande quand même POURQUOI!?!

Je travaille également sur un moyen de déployer plusieurs fichiers MSI. J'ai un programme bootstrapper.exe qui regroupe les fichiers MSI et les exécute un à la fois. Cela résout mon problème dans la plupart des cas.

Le cas qu’il ne résout pas est la distribution de l’installation par GPO (Global Policy Object). L'objet de stratégie de groupe nécessite un fichier point-msi pour exécuter une installation.

Pour ce faire, voici ce que j'ai fait qui a presque résolu le problème (mais pas tout à fait). Je mets les fichiers point-msi dans la table des fichiers d'un programme d'installation, puis mon bootstrapper dans la table binaire et l'exécute à partir d'une action personnalisée insérée après InstallFinalize dans InstallExecuteSequence. Bien sûr, le bootstrapper ne pourra pas exécuter d'autres MSI car le MSI de niveau supérieur contient le mutex _MSIExecute.

C'était assez facile d'aller un peu plus loin. J'ai fait en sorte que le bootstrapper renvoie le contrôle au programme d'installation de niveau supérieur et continue. Et puis, j’ai ajouté un appel WaitForSingleObject pour attendre la fin de l’installation de niveau supérieur, puis le programme de démarrage peut continuer à terminer l’installation.

Mon problème est que l'installation de l'objet de stratégie de groupe a lieu au démarrage et que l'installation de niveau supérieur est terminée avant que les programmes d'installation secondaires ne soient terminés et que l'objet de stratégie de groupe ne redémarre pas la machine.

L'installation de niveau supérieur renvoie également un statut de réussite lorsque l'installation peut échouer ultérieurement.

Je suis toujours à la recherche d'un moyen d'empêcher la fin de l'installation de niveau supérieur jusqu'à la fin du programme d'amorçage.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top