2012-09-03 21 views
39

TL; DR: ¿Por qué necesito un elemento vacío<CreateFolder/> en este componente condicional para que funcione?¿Por qué mi instalador de WiX necesita un CreateFolder vacío para actualizar condicionalmente un archivo Xml?

Estoy armando un sencillo instalador basado en WiX para una aplicación interna. Este instalador necesita desplegar un archivo de configuración estándar (un archivo .NET .config normal) y luego personalizarlo usando propiedades pasadas al msiexec en la línea de comando.

Una de las personalizaciones consiste en crear una configuración de aplicación específica solo si se ha definido la propiedad RUNTIME. Aquí está el componente de WiX para ello:

<Component Id="C.Rbnz.Fsis.CollectionPeriodService.exe.config.runtime" 
      Guid="*"> 
    <Condition> 
     <![CDATA[RUNTIME]]> 
    </Condition> 

    <CreateFolder/> 

    <util:XmlFile Id="X.Runtime.1" 
        Action="createElement" 
        ElementPath="/configuration/appSettings" 
        File="[#F.Rbnz.Fsis.CollectionPeriodService.exe.config]" 
        Name="add" 
        Sequence="2"/> 

    <util:XmlFile Id="X.Runtime.2" 
        File="[#F.Rbnz.Fsis.CollectionPeriodService.exe.config]" 
        ElementPath="/configuration/appSettings/add[\[]not(@key)[\]]" 
        Action="setValue" 
        Name="key" 
        Value="RunTime" 
        Sequence="3"/> 

    <util:XmlFile Id="X.Runtime.3" 
        File="[#F.Rbnz.Fsis.CollectionPeriodService.exe.config]" 
        ElementPath="/configuration/appSettings/add[\[]@key='RunTime'[\]]" 
        Action="setValue" 
        Name="value" 
        Value="[RUNTIME]" 
        Sequence="4"/> 

    </Component> 

Esto funciona igual que yo quiero - si se especifica tiempo de ejecución en la línea de comandos para msiexec, el nuevo elemento se crea; si no, no pasa nada.

¿Por qué tengo que tener el <CreateFolder/> vacío dentro de este componente?

Mientras intentaba hacer que funcionara, encontré "Wix Condition Statement", que mostraba un componente en funcionamiento, pero no explica por qué es necesario <CreateFolder/>.

Extracción <CreateFolder/> me da este error:

ICE18: KeyPath for Component: 'C.Rbnz.Fsis.CollectionPeriodService.exe.config.runtime' is Directory: 'INSTALLDIR'. The Directory/Component pair must be listed in the CreateFolders table.

que es, estoy seguro, muy informativos una vez que sabes lo que significa.

Respuesta

39

Cada componente tiene una ruta clave; el más común es un archivo. Su componente no tiene un archivo u otra ruta clave, por lo que WiX le da el valor predeterminado de un directorio. A continuación aparece Windows Installer y dice que los componentes con rutas de clave de directorio deben garantizar que se cree el directorio, incluso si algo más lo hace. Es una regla tonta con una solución fácil.

+1

Entiendo una parte de esto: el componente requiere una ruta clave, de manera predeterminada obtiene un directorio, y '' es necesario para asegurarse de que funciona. Pero, ¿qué directorio es, y dónde? ¿Esto es seguro? ¿Esto está creando carpetas vacías (desechos) en algún lugar de la máquina de destino como parte de la instalación? ¿Hay alguna manera más ordenada de hacer esto? – Bevan

+1

Es lo que le está diciendo al componente que es su directorio principal. Según el mensaje de error, es INSTALLDIR. –

+0

@Bevan: una entrada CreateFolder faltante en un componente vacío que está configurado para instalarse en una carpeta vacía sin otros archivos en ella, desencadenará una situación exótica en la que Windows Installer eliminará la carpeta después del lanzamiento (porque está vacía) y a continuación, Windows Installer intenta volver a ponerlo en el próximo lanzamiento a través de un acceso directo publicitado (esto activa una comprobación de keypath). Este sinsentido se repite en un ciclo sin fin. Acabo de verificar para probar si esto se ha solucionado en versiones posteriores de Windows Installer, pero todavía veo el problema. Una entrada CreateFolder evita este exótico problema de auto reparación. –

15

En su lugar, puede usar el parámetro KeyPath = "yes" en su etiqueta de componente. Solo si el 'INSTALLDIR' es la ruta correcta para este componente.

Cuestiones relacionadas