2009-03-24 14 views
13

Utilizziamo wix per creare configurazioni per la nostra applicazione. Nel caso in cui l'utente abbia già installato una versione precedente della nostra applicazione, eseguiamo un importante aggiornamento con lo MajorUpgrade XML element. Funziona tutto come desiderato: se è installata una versione precedente, viene aggiornata in modo trasparente. Se è presente una versione più recente, l'installer interrompe con un messaggio chiaro.Come correggere la logica di aggiornamento di una configurazione wix dopo aver cambiato InstallScope in "perMacchina"

Tuttavia, ora vogliono cambiare il InstallScope da "Peruser" a "perMachine". Sfortunatamente questo rompe la logica di aggiornamento. Il nuovo programma di installazione non sembra rilevare e rimuovere la precedente installazione "perUser". Invece, si installa solo sulla versione precedente nella stessa posizione ProgramFiles. L'utente può vedere due voci nell'elenco "aggiungi/rimuovi programmi" e vede due scorciatoie identiche sul desktop (il vecchio utente specifico e il nuovo perMachine).

Come si esegue la transizione del programma di installazione da "perUser" all'ambito di installazione "perMachine" senza interrompere la logica di aggiornamento?

risposta

5

Partendo con la configurazione per computer.

<Property Id="ALLUSERS" Value="1" /> 

Questo farà eseguire un sistema automatico di controllo per computer (se avete l'elemento MajorUpgrade lavoro, suppongo), che non prendere l'utente per-precedente installazione:

Action start 15:46:35: FindRelatedProducts. 
MSI (c) (D0:0C) [15:46:35:496]: FindRelatedProducts: current install is per-machine. Related install for product '{0C6604FB-58EC-48B9-8259-5871EFDADEB9}' is per-user. Skipping... 
MSI (c) (D0:0C) [15:46:35:496]: FindRelatedProducts: current install is per-machine. Related install for product '{0C6604FB-58EC-48B9-8259-5871EFDADEB9}' is per-user. Skipping... 

Quindi, prima di l'installazione, assicurarsi di eseguire un'altra FindRelatedProducts richiesta di prodotti che sono stati installati in ambito utente (ad esempio come questo):

<!-- temporarily switch to per-user install scope--> 
<Publish Dialog="MyWelcomeDlg" Control="Next" Property="ALLUSERS" Value="{}">1</Publish> 
<!-- find related products that have been installed per-user --> 
<Publish Dialog="MyWelcomeDlg" Control="Next" Event="DoAction" Value="FindRelatedProducts">1</Publish> 
<!-- switch back to per-machine install scope--> 
<Publish Dialog="MyWelcomeDlg" Control="Next" Property="ALLUSERS" Value="1">1</Publish> 

questo a sua volta trova il singolo utente di installazione:

Action start 15:46:36: FindRelatedProducts. 
FindRelatedProducts: Found application: {0C6604FB-58EC-48B9-8259-5871EFDADEB9} 
MSI (c) (D0:88) [15:46:36:716]: PROPERTY CHANGE: Adding WIX_UPGRADE_DETECTED property. Its value is '{0C6604FB-58EC-48B9-8259-5871EFDADEB9}'. 
MSI (c) (D0:88) [15:46:36:716]: PROPERTY CHANGE: Adding MIGRATE property. Its value is '{0C6604FB-58EC-48B9-8259-5871EFDADEB9}'. 

prodotti esistenti verranno rimossi non importa in quale controllare si trovano.

Action start 15:46:41: RemoveExistingProducts. 
RemoveExistingProducts: Application: {0C6604FB-58EC-48B9-8259-5871EFDADEB9} 

Su un lato nota: Questo non aggirare una difficoltà di base che si verifica quando si dispone di programmi di installazione a doppio scopo: Utente1 sulla macchina potrebbe installare una portata per utente, poi Utente2 installa per computer . L'utente1 vedrà entrambe le installazioni nella sua tabella programmi/caratteristiche e non so quale abbia la precedenza. Quindi considera di andare solo con installazioni per macchina.

+0

Funziona perfettamente anche nella direzione opposta =) –

+0

Sarebbe possibile eseguire queste azioni senza un'interfaccia utente? (Non ho un controllo per posizionare gli elementi di pubblicazione in), quale potrebbe essere una buona soluzione alternativa? –

7

Purtroppo Windows Installer non lo supporta. Alcuni processi esterni al pacchetto (un bootstrapper/chainer?) Dovranno gestire l'aggiornamento da per utente a per macchina.

+0

Questo ha funzionato per un caso particolare ho avuto una volta, ma non ci sono garanzie - utile per la stranezza della soluzione però: http://stackoverflow.com/a/12291807/129130. Mi chiedo come questo influisce sul database MSI - sembra registrare nuovamente il prodotto per macchina e annullare la registrazione di un'installazione per utente, ma lo fa per tutti gli utenti? Non ricordo. Penso che abbiamo usato questo come una soluzione unica per i sistemi con principalmente un utente. –

+0

Questa risposta non è corretta. È * possibile * controllare entrambi gli ambiti di installazione per i prodotti esistenti. Vedi la mia risposta. –

1

È possibile utilizzare questa tecnica per rilevare l'installazione per utente da per-macchina da installare: http://www.mail-archive.com/[email protected]/msg35197.html

+0

+1 hack interessante. Quel thread di mailing list non ha la conferma che funzionerebbe comunque. Non sono più interessato a questo problema, quindi non posso testarlo rapidamente. Se qualcuno può confermare che funziona, si prega di commentare. –

+0

Non funziona. Secondo me non è mai stato testato perché non viene nemmeno compilato ... l'id "24INSTALLPERUSER" non è un identificatore legale per esempio. Le sequenze 199 e 201 non sono corrette. Ho corretto l'hack per farlo funzionare, verificando con orca che le due azioni personalizzate si sarebbero adattate subito prima e dopo FindRelatedProducts, ma al momento dell'esecuzione della configurazione entrambe le azioni personalizzate sono ancora eseguite dopo FindRelatedProducts. Ottieni un'azione "Ignora Trova prodotti correlati: già eseguita sul lato client". Peccato, sarebbe stata una buona idea ... –

+0

Ho fatto qualcosa di simile e funziona, vedere la mia risposta. –

0

Trova entrambe le installazioni perUser e/o perMachine esistenti. E forza la nuova installazione su un'installazione di perMachine (ovviamente logico per rendere applicabile quel condizionale come desiderato). Funziona quando viene eseguito come un'installazione normale e se installato in modo invisibile in LocalSystem (aggiornamenti silenziosi). Tieni presente che può trovare solo un'installazione perUser quando viene eseguita come tale utente.

creare un'azione personalizzata (in DLL)

#pragma comment(linker, "/EXPORT:[email protected]") 
extern "C" __declspec(dllexport) UINT __stdcall RunFindRelatedProducts(MSIHANDLE a_hInstall) 
{ 
MsiSetProperty(a_hInstall, "ALLUSERS", "1"); 
MsiDoAction(a_hInstall, "FindRelatedProducts"); 
MsiSetProperty(a_hInstall, "ALLUSERS", ""); 
MsiDoAction(a_hInstall, "FindRelatedProducts"); 
MsiSetProperty(a_hInstall, "ALLUSERS", "1"); 
return ERROR_SUCCESS; 
}//end function 

Poi "sostituire" i FindRelatedProducts standard con l'azione personalizzata

<InstallUISequence> 
    <FindRelatedProducts>0</FindRelatedProducts> 
    <Custom Action="RunFindRelatedProducts" Before='FindRelatedProducts'>NOT Installed</Custom> 
</InstallUISequence> 
<InstallExecuteSequence> 
    <FindRelatedProducts>0</FindRelatedProducts> 
    <Custom Action="RunFindRelatedProducts" Before='FindRelatedProducts'>NOT Installed</Custom> 
</InstallExecuteSequence> 
Problemi correlati