Un file .msi può installarsi da solo (presumibilmente tramite un'azione personalizzata)?

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

  •  01-07-2019
  •  | 
  •  

Domanda

Voglio costruire un MSI che, nel processo di installazione, si distribuirà insieme ai file/componenti contenuti nella TargetDir.

Quindi MyApp.msi contiene MyApp.exe e MyAppBootstrapperEmpty.exe (senza risorse) nella sua tabella file.

L'utente avvia MyAppBootstrapperPackaged.exe (contenente MyApp.msi come risorsa, ottenuto da Internet da qualche parte, o tramite e-mail o altro).MyAppBootStrapperPackaged.exe estrae MyApp.msi in una cartella temporanea e lo esegue tramite msiexec.exe.

Una volta completato il processo msiexec.exe, desidero MyApp.msi, MyBootstrapperEmpty.exe (E MyApp.exe nella cartella %ProgramFiles%\MyApp in modo che MyApp.exe possa avere accesso sicuro a MyApp.msi quando viene eseguito (per creare il seguente- contenuto della confezione menzionato).

MyAppBootstrapper*.exe potrebbe provare a copiare MyApp.msi nella cartella %ProgramFiles%\MyApp, ma avrebbe bisogno dell'elevazione per farlo e non ne consentirebbe la rimozione tramite il processo di disinstallazione di Windows Installer (da Aggiungi/Rimuovi programmi o in altro modo), che dovrebbe essere preservato.

Ovviamente (penso sia ovvio - sbaglio?) Non posso includere l'MSI come file nel mio Media/CAB (scenario dell'uovo e della gallina), quindi credo che dovrebbe essere fatto tramite un'azione personalizzata prima dell'installazione processo, aggiungendo al volo l'MSI originale al Media/CAB del DB MSI e la voce appropriata nella tabella File.È possibile farlo e, se sì, come?

Pensa a un modello di distribuzione dei contenuti in cui i file di contenuto devono essere distribuiti solo insieme all'app.Il contenuto viene prodotto dall'utente finale tramite l'App in fase di esecuzione e confezionato in un file EXE distribuibile che include sia l'App che il contenuto.

Il programma di installazione di MyApp deve rimanere un MSI, ma può essere eseguito da un EXE Bootstrapper.Il MyApp.exe installato deve avere accesso sia a MyApp.msi che all'EXE e deve essere "assemblato" in fase di runtime dall'App da un MyAppBootstrapper.exe di base (vuoto), anch'esso installato da MSI, e dal contenuto creato da utente finale.L'MSI della risorsa dell'EXE deve essere lo stesso utilizzato per installare l'app che sta eseguendo il pacchetto runtime.

WIX non deve essere installato con MyApp.

Non possono esserci dipendenze di rete in fase di esecuzione/packaging (ad es.non è possibile eseguire il confezionamento tramite un servizio Web: deve essere eseguito localmente).

Conosco (e utilizzo) le azioni personalizzate (gestite e non gestite, tramite DTF e in altro modo).

È stato utile?

Soluzione

Aggiungi un supporto non compresso alle tue wx in questo modo:

<Media Id='2'/>

E poi crea un componente con un elemento File come questo:

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

Ciò farà sì che il programma di installazione cerchi un file chiamato "myinstaller.msi" sul supporto di installazione, nella stessa cartella dell'msi che viene installato.Il percorso sorgente sopra dovrebbe puntare a un file fittizio, è lì solo per placare Wix.

Modificare:Il seguente esempio test.wxs dimostra che funziona.Produce un file test.msi che si installa in c:\program files est.Tieni presente che devi inserire un file fittizio test.msi nella stessa cartella di text.wxs per placare 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>

Altri suggerimenti

Avere un pacchetto .MSI che avvia un altro pacchetto .MSI dall'interno stesso è chiamato a installazione nidificata, e il suo cattivo juju (vedi regola 20).Windows Installer dispone di alcuni dati globali che utilizza per gestire l'installazione corrente e non gestisce bene più installazioni contemporaneamente.Per lo stesso motivo, se avvii un'installazione e poi provi ad avviarne un'altra mentre la prima è ancora in corso, di solito vedrai un popup con l'effetto di "un'altra installazione in corso, attendi fino al termine".

Puoi avere un programma, solitamente chiamato bootstrapper (penso sia quello a cui ti riferisci) che di per sé non è un pacchetto di installazione, ma che contiene un pacchetto di installazione (ad esempio un .MSI o un .EXE) come risorsa, possibilmente compresso.L'azione del programma bootstrapper è estrarre/espandere la risorsa in un file, comunemente in un file %TEMP% directory, quindi avviare il file .EXE estratto o eseguire MSIEXEC sul file .MSI estratto.Il bootstrapper può contenere più risorse ed estrarle+installarle una per una, se è necessario installare i prerequisiti prima del pacchetto principale.Oppure puoi spedire più pacchetti come file separati e fare in modo che il programma di avvio automatico li esegua/installa direttamente dal supporto di distribuzione uno per uno, oppure copiali sul computer di destinazione ed esegui la serie di installazioni da lì, oppure...

WiX stesso non viene installato, no.È uno strumento con cui è possibile creare pacchetti .MSI.Il progetto WiX ha nella sua lista dei desideri un programma bootstrapper generico, ma non è stato ancora implementato.Sono disponibili altri bootstrap, ad es. Questo.

Non avrai bisogno di un'azione personalizzata: infatti, poiché il programma di avvio automatico non è di per sé un pacchetto di installazione di Windows Installer, "azione personalizzata" non ha alcun significato.Inoltre, se hai abbastanza familiarità con le CA per conoscere i concetti gestiti/non gestiti/DTF, allora ne sai abbastanza per evitare azioni personalizzate ogni volta che puoi.(largo sorriso)

Penso che sia molto più semplice per il tuo bootstrapper estrarre il file MSI in una posizione predefinita anziché nella cartella temporanea.Ad esempio, in C:\Documents and Settings\All Users\Dati applicazioni\My Company\My Product Install Cache.Al termine dell'installazione, il bootstrapper lascerebbe il file MSI lì.Se a un certo punto l'utente decide di reinstallare il prodotto, Windows Installer sarà in grado di individuare il file MSI di origine.

Inoltre, aggiungi il percorso a questo file a Tabella RimuoviFile in modo che venga eliminato durante la disinstallazione.Puoi usare Elemento RemoveFile in WiX per quello.

Quindi, se ho capito, penso che farei in modo che l'app crei una trasformazione (MST) con i file di contenuto e la applichi all'MSI di base.Non sono ancora convinto di aver capito però.:)

Configurerei il percorso della cache MSI in una posizione nota.

Quindi in fase di runtime se è necessario "modificare" l'MSI utilizzare VBScript o simili.

Ma ancora, mi chiedo PERCHÉ!?!

Sto anche lavorando a un modo per distribuire più file MSI.Ho un programma bootstrapper.exe che raggruppa i file MSI e li esegue uno alla volta.Questo risolve il mio problema nella maggior parte dei casi.

Il caso che non risolve è la distribuzione GPO (Global Policy Object) dell'installazione.L'oggetto Criteri di gruppo richiede un file dot-msi per eseguire un'installazione.

Per fare questo ecco cosa ho fatto che ha quasi risolto il problema (ma non del tutto).Inserisco i file dot-msi nella tabella dei file di un programma di installazione, inserisco il mio programma di avvio automatico nella tabella binaria e lo eseguo da un'azione personalizzata inserita dopo InstallFinalize in InstallExecuteSequence.Ovviamente il bootstrapper non sarà in grado di eseguire altri MSI perché l'MSI di livello superiore contiene il mutex _MSIExecute.

È stato abbastanza facile andare un po' oltre.Ho fatto in modo che il bootstrapper restituisse il controllo al programma di installazione di livello superiore e continuassi.Quindi ho aggiunto una chiamata WaitForSingleObject per attendere il completamento dell'installazione di livello superiore e il bootstrapper può quindi continuare a completare l'installazione.

Il mio problema è che l'installazione dell'oggetto Criteri di gruppo avviene al momento dell'avvio e l'installazione di livello superiore viene completata prima che vengano completati i programmi di installazione secondari e l'oggetto Criteri di gruppo riavvia la macchina.

L'installazione di primo livello restituisce inoltre uno stato di successo quando l'installazione potrebbe effettivamente non riuscire in seguito.

Sto ancora cercando un modo per impedire il completamento dell'installazione di livello superiore fino al completamento del bootstrapper.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top