2010-08-13 7 views
9

Dans Windows Installer le jeu d'outils XML, pour installer un service, nous regroupons <ServiceInstall> avec un <File> dans un <Component>. Pour installer le service sous conditions, nous mettons <Condition> sous le <Component>. Cependant si la condition est fausse, le fichier ne sera pas installé aussi. Si je mets le <File> dans un <Component> inconditionnel, alors le service n'a aucun chemin de fichier exécutable et ainsi l'installation échouera. Si je mets le <File> dans les deux <Component>, les symboles en double seront trouvés.WiX: InstallService conditionnellement, mais installe le fichier inconditionnellement

La question est, pouvons-nous installer un service conditionnellement, mais installer inconditionnellement le fichier exécutable associé?

Merci!

+1

Ce serait vraiment bien si l'attribut ServiceInstall/@ Start peut être défini sur [Propriété], donc vous pouvez toujours installer le service sans le démarrer. – Ivan

Répondre

5

Créez deux composants avec les différents GUID 'et Ids' et les conditions mutuellement exclusives: une pour le fichier et le service, et une autre pour le fichier seulement. Quelque chose comme ceci:

<Component Id="SvcComp" Guid="{YOUR-GUID}" SharedDllRefCount="yes"> 
    <Condition> SOME_CONDITION </Condition> 
    <File Id="SvcFile" Name="Service.exe" Source="Service.exe" Vital="yes" /> 
    <ServiceInstall Id="Svc" Name="Service" DisplayName="Service" Description="Service" Type="ownProcess" Start="auto" ErrorControl="normal" Vital="yes" /> 
    <ServiceControl Id="Svc" Name="Service" Stop="both" Remove="uninstall" Wait="yes" /> 
</Component> 

<Component Id="ExeComp" Guid="{YYOUR-GUID}" SharedDllRefCount="yes" > 
    <Condition> NOT SOME_CONDITION </Condition> 
    <File Id="ExeFile" Name="Service.exe" Source="Service.exe" Vital="yes" /> 
</Component> 

Vous obtiendrez un avertissement de LGHT1076 qui pourrait être supprimé puisque les conditions dans les composants sont mutuellement exclusifs.

+0

Merci pour vos conseils, j'ai trouvé que ce que j'ai manqué est l'ID de fichier. Avec un identifiant différent mais le même nom, le même fichier peut exister dans différents ''. –

+1

Cela fonctionne techniquement, mais vous obtiendrez des erreurs de validation ICE car les deux composants ont le même keypath. Ce n'est pas une solution propre. –

1

Je suis allé sur cette route et il se complique plus vite que prévu.

Je considère avoir deux composants (malgré leurs expressions conditionnelles s'excluant mutuellement) avec le même fichier de clés mais différentes ressources ServiceInstall/Control une violation de règle de composant.

La façon dont je suggère de le faire est de déplacer toute votre logique métier dans un composant DLL séparé et de créer deux composants EXE différents. Configurez-en une en tant qu'application console/windows et l'autre en tant qu'application de service. Associez les composants à deux fonctionnalités différentes afin que l'utilisateur final puisse décider de la manière dont il souhaite configurer l'application. L'utilisateur peut ensuite effectuer une opération de modification dans des programmes d'ajout/suppression et utiliser MSI pour changer d'avis ultérieurement.

2

Si vous n'avez qu'un seul service, vous pouvez conditionner les actions de service dans le tableau InstallExecuteSequence.

Alternativement, vous devez avoir une exécution de CA pendant la phase immédiate, qui enlève temporairement l'entrée des tables de service avant l'exécution pendant différé. Je ne suis pas un fan de la division de la DLL sans raison valable.

+0

La bonne conception de l'application consiste à factoriser le code en plusieurs classes dans plusieurs assemblages. Vous créez un assembly qui a les composants du serveur et vous créez deux assemblys pour agir en tant qu'hôte de la console et un hôte de service. Les suggestions que vous faites ne font que créer des MSI de piratage qui ne suivent pas les meilleures pratiques. –

Questions connexes