Estamos usando o WiX há um tempo e, apesar das queixas usuais sobre a facilidade de uso, está indo razoavelmente bem. O que estou procurando é um conselho útil sobre:
- Configurando um projeto WiX (layout, referências, padrões de arquivo)
- Integração do WiX em soluções e processos de criação / lançamento
- Configurando instaladores para novas instalações e atualizações
- Quaisquer bons hacks WiX que você gostaria de compartilhar
practical, answerable questions based on actual problems that you face
parte do FAQ.Respostas:
Mantenha as variáveis em um
wxi
arquivo de inclusão separado . Permite a reutilização, as variáveis são mais rápidas de encontrar e (se necessário) permitem uma manipulação mais fácil por uma ferramenta externa.Definir variáveis de plataforma para construções x86 e x64
Armazene o local da instalação no registro, permitindo que as atualizações encontrem o local correto. Por exemplo, se um usuário definir um diretório de instalação personalizado.
Nota : o guru da WiX, Rob Mensching , publicou uma excelente entrada no blog, que entra em mais detalhes e corrige um caso extremo quando as propriedades são definidas na linha de comando.
Exemplos usando 1. 2. e 3.
e
A abordagem mais simples é sempre fazer grandes atualizações , pois permite novas instalações e atualizações no MSI único. UpgradeCode é fixado em um Guid exclusivo e nunca será alterado, a menos que não desejemos atualizar o produto existente.
Nota : No WiX 3.5, há um novo elemento MajorUpgrade que facilita ainda mais a vida !
Criando um ícone em Adicionar / Remover Programas
Nas versões de lançamento, fazemos a versão de nossos instaladores, copiando o arquivo msi para um diretório de implantação. Um exemplo disso usando um destino wixproj chamado de destino AfterBuild:
Use o calor para coletar arquivos com o Guid curinga (*). Útil se você deseja reutilizar arquivos WXS em vários projetos (veja minha resposta em várias versões do mesmo produto). Por exemplo, esse arquivo em lote colhe automaticamente a saída do RoboHelp.
Há um pouco de coisa acontecendo:
robocopy
remover os metadados das cópias de trabalho do Subversion antes de coletar; a-dr
referência do diretório raiz é configurada para o local da instalação em vez do TARGETDIR padrão;-var
é usado para criar uma variável para especificar o diretório de origem (saída de implementação da web).Maneira fácil de incluir a versão do produto no título da caixa de diálogo de boas-vindas usando Strings.wxl para localização. (Crédito: saschabeaumont . Adicionado como essa ótima dica está oculta em um comentário)
Poupe um pouco de dor e siga o conselho de Wim Coehen de um componente por arquivo. Isso também permite que você deixe de fora (ou curinga
*
) o GUID do componente .Rob Mensching tem uma maneira elegante de rastrear rapidamente problemas nos arquivos de log MSI pesquisando
value 3
. Observe os comentários sobre internacionalização.Ao adicionar recursos condicionais, é mais intuitivo definir o nível de recurso padrão como 0 (desativado) e depois definir o nível de condição para o valor desejado. Se você definir o nível de recurso padrão> = 1, o nível de condição deverá ser 0 para desativá-lo, o que significa que a lógica da condição deve ser o oposto do que você esperaria, o que pode ser confuso :)
fonte
Verificando se o IIS está instalado:
Verificando se a compatibilidade da metabase do IIS 6 está instalada no Vista +:
fonte
Mantenha todos os IDs em namespaces separados
F.
Exemplos: F.Documentation, F.Binaries, F.SampleCode.C.
Ex: C.ChmFile, C.ReleaseNotes, C.LicenseFile, C.IniFile, C.RegistryCA.
Ex: CA.LaunchHelp, CA.UpdateReadyDlg, CA.SetPropertyXFi.
Di.
Acho que isso ajuda imensamente a acompanhar todos os vários IDs em todas as categorias.
fonte
Pergunta fantástica. Adoraria ver algumas práticas recomendadas.
Eu tenho muitos arquivos que distribuí, então configurei meu projeto em vários arquivos de origem wxs.
Eu tenho um arquivo de origem de nível superior que chamo Product.wxs, que basicamente contém a estrutura da instalação, mas não os componentes reais. Este arquivo possui várias seções:
O restante dos arquivos .wix é composto por fragmentos que contêm ComponentGroups que são referenciados na marca Feature nos Product.wxs. Meu projeto contém um bom agrupamento lógico dos arquivos que distribuo
Isso não é perfeito, meu senso de aranha OO formiga um pouco porque os fragmentos precisam fazer referência a nomes no arquivo Product.wxs (por exemplo, o DirectoryRef), mas acho mais fácil manter esse arquivo de origem grande e único.
Eu adoraria ouvir comentários sobre isso, ou se alguém tiver alguma dica boa também!
fonte
Adicione uma caixa de seleção à caixa de diálogo de saída para iniciar o aplicativo ou o arquivo de ajuda.
...
Se você fizer dessa maneira, a aparência "padrão" não estará correta. A caixa de seleção é sempre um plano de fundo cinza, enquanto a caixa de diálogo é branca:
texto alternativo http://www.dizzymonkeydesign.com/blog/misc/adding-and-customizing-dlgs-in-wix-3/images/exit_dlg_1.gif
Uma maneira de contornar isso é especificar o seu próprio ExitDialog personalizado, com uma caixa de seleção diferente . Isso funciona, mas parece muito trabalho apenas para alterar a cor de um controle. Outra maneira de resolver o mesmo é pós-processar o MSI gerado para alterar os campos X, Y na tabela Control para esse controle CheckBox específico. O código javascript fica assim:
A execução desse código como um script de linha de comando (usando cscript.exe) após a geração do MSI (a partir do light.exe) produzirá um ExitDialog com aparência mais profissional:
texto alternativo http://www.dizzymonkeydesign.com/blog/misc/adding-and-customizing-dlgs-in-wix-3/images/exit_dlg_2.gif
fonte
WIXUI_EXITDIALOGOPTIONALCHECKBOX
porWIXUI_EXITDIALOGOPTIONALCHECKBOX = 1 and NOT Installed
dentro #<Publish>
Criando versões ao vivo, teste, treinamento ... usando os mesmos arquivos de origem.
Em poucas palavras: Crie um UpgradeCode exclusivo para cada instalador e defina automaticamente o primeiro caractere de cada Guid para cada instalador, deixando os 31 restantes únicos.
Pré-requisitos
Premissas
Estrutura de Diretórios
Processo
Exemplo Config.wxi
Exemplo Config.Common.wxi
Exemplo Components.wxs
Nota: agora sugiro deixar o atributo Guid fora do Component (equivalente a
*
), usando um arquivo por componente e definindo o arquivo como o caminho-chave. Isso elimina a necessidade de chamadasModifyComponentsGuids
eRevertComponentsGuids
destinos mostrados abaixo. Isso pode não ser possível para todos os seus componentes.Exemplo Setup.Live.wixproj
Pensamentos finais
ATUALIZAÇÃO 1: Guids de componente de geração automática remove a necessidade de chamar a tarefa FileUpdate se você criar componente com Guid = "*" para cada arquivo, configurando o arquivo como o caminho da chave.
ATUALIZAÇÃO 2: Um dos problemas que enfrentamos é que, se você não gerar automaticamente os Guids de seu componente e a compilação falhar, os arquivos temporários precisarão ser excluídos manualmente.ATUALIZAÇÃO 3: Foi encontrada uma maneira de remover a dependência do svn: externals e da criação temporária de arquivos. Isso torna o processo de compilação mais resistente (e é a melhor opção se você não pode curinga seus Guids) e menos quebradiço se houver uma falha na compilação com luz ou vela.
ATUALIZAÇÃO 4: O suporte para várias instâncias usando transformações de instância está no WiX 3.0+, definitivamente também vale uma olhada.
fonte
Usando o log de diagnóstico Msi para obter informações detalhadas sobre falhas
msiexec /i Package.msi /l*v c:\Package.log
Onde
é o nome do seu pacote e é onde você deseja a saída do logCódigos de erro Msi
Vídeo introdutório do Wix
Oh e vídeo introdutório aleatório do Wix, apresentando "Mr. WiX", Rob Mensching é útil na "imagem conceitual".
fonte
Use Javascript CustomActions, porque são muuuuito fáceis
As pessoas disseram que Javascript é a coisa errada a ser usada nas MSI CustomActions . Razões apresentadas: difícil de depurar, difícil de torná-lo confiável. Eu não concordo Não é difícil depurar, certamente não é mais difícil que o C ++. É apenas diferente. Achei que escrever CustomActions em Javascript era super fácil, muito mais fácil do que usar C ++. Muito mais rapido. E igualmente confiável.
Há apenas uma desvantagem: as Javascript CustomActions podem ser extraídas via Orca, enquanto uma CA C / C ++ exigiria engenharia reversa. Se você considera a mágica do instalador protegida como propriedade intelectual, convém evitar o script.
Se você usa script, você só precisa começar com alguma estrutura. Aqui estão alguns para você começar.
Código Javascript "boilerplate" para CustomAction:
Em seguida, registre a ação personalizada com algo como isto:
Obviamente, você pode inserir quantas funções Javascript desejar, para várias ações personalizadas. Um exemplo: usei o Javascript para fazer uma consulta WMI no IIS, para obter uma lista dos sites existentes, nos quais um filtro ISAPI poderia ser instalado. Essa lista foi usada para preencher uma caixa de listagem mostrada posteriormente na sequência da interface do usuário. Tudo muito fácil.
No IIS7, não há provedor WMI para o IIS, então usei o
shell.Run()
abordagem para chamar o appcmd.exe para executar o trabalho. Fácil.Pergunta relacionada: Sobre Javascript CustomActions
fonte
Peter Tate já mostrou como você pode definir definições reutilizáveis do ComponentGroup em fragmentos separados do wix. Alguns truques adicionais relacionados a isso:
Alias de diretório
Os fragmentos do grupo de componentes não precisam conhecer os diretórios definidos pelo produto principal wxs. No fragmento do seu grupo de componentes, você pode falar sobre uma pasta como esta:
Em seguida, o produto principal pode criar um alias de um de seus diretórios (por exemplo, "productInstallFolder") como este:
Gráfico de dependência
Os elementos ComponentGroup podem conter elementos filho ComponentGroupRef. Isso é ótimo se você tiver um grande conjunto de componentes reutilizáveis com um gráfico de dependência complexo entre eles. Você acabou de configurar um ComponentGroup em seu próprio fragmento para cada componente e declarar as dependências assim:
Se você agora fizer referência ao grupo de componentes "B" na sua configuração porque é uma dependência direta do seu aplicativo, ele puxará automaticamente o grupo de componentes "A", mesmo que o autor do aplicativo nunca tenha percebido que era uma dependência de "B". "Funciona" desde que você não tenha nenhuma dependência circular.
Wixlib reutilizável
A idéia do gráfico de dependência acima funciona melhor se você compilar os componentes big-pool-o-reusable em um wixlib reutilizável com lit.exe. Ao criar uma configuração de aplicativo, você pode fazer referência a este wixlib como um arquivo wixobj. O vinculador candle.exe eliminará automaticamente todos os fragmentos que não são "puxados" pelos arquivos wxs do produto principal.
fonte
Estou surpreso que ninguém tenha mencionado o uso do T4 para gerar o arquivo WXS durante a compilação. Eu aprendi sobre isso por meio de Henry Lee @ New Age Solutions .
Essencialmente, você cria uma tarefa MSBuild personalizada para executar um modelo T4, e esse modelo gera o WXS imediatamente antes da compilação do projeto Wix. Isso permite que você (dependendo de como implementá-lo) inclua automaticamente todos os resultados de montagens da compilação de outra solução (o que significa que você não precisa mais editar os wxs sempre que adicionar um novo assembly).
fonte
Usando o Heat.exe para esmagar o rosto e infligir "Epic Pwnage" em instalações dolorosamente grandes
Expandindo as respostas de Si e Robert-P sobre o calor.
Tradução: (usando o heat para evitar a digitação manual de arquivos individuais no projeto e para automatizar as compilações para um processo mais fácil em geral.)
WiX 2.0 Heat Syntax
Para versões mais recentes (nem todas tão diferentes das versões anteriores, mas existem alterações de sintaxe potencialmente irritantes ...), vá para o diretório Heat is do cmd.exe e digite apenas heat, mas eu tenho um exemplo aqui para obter ajuda com versões mais recentes, se necessário.
Adicionando o seguinte ao seu Evento de Construção no visual studio 2010.
(Clique com o botão direito do mouse em Projeto-> Propriedades -> Eventos de Construção-> Eventos de Pré-Construção)
$(WIX)bin\heat.exe" dir "$(EnviromentVariable)" -cg GroupVariable -gg -scom -sreg -sfrag - srd -dr INSTALLLOCATION -var env.LogicPath -out "$(FragmentDir)\FileName.wxs
Gera Guids quando o calor é executado (como quando você executa o comando acima)
Não pegue "arquivos COM"
Não pegue "Arquivos do Registro"
Não pegue "Fragmentos"
Não pegue o "diretório raiz"
dir indica que você deseja que o Heat procure em uma pasta
O nome da variável que você adicionaria às variáveis de pré-processador na seção Propriedades do projeto (projeto de clique com o botão direito do mouse, vá para propriedades) -> Seção Build, onde diz Definir variáveis de pré-processador (assume visual studio 2010)
Não há aspas duplas, mas termina com um ponto-e-vírgulaO ComponentGroup que será referenciado do fragmento criado para o arquivo wxs principal
O diretório do fragmento em que o fragmento wxs de saída será armazenado
O nome do arquivo
Tutorial completo aqui, muito útil
Parte 1 Parte 2
fonte
Incluindo objetos COM:
heat
gera quase todas (se não todas) as entradas do registro e outras configurações necessárias para elas. Alegrar!Incluindo objetos COM gerenciados (também conhecidos como objetos .NET ou C # COM)
Usar
heat
um objeto COM gerenciado fornecerá um documento wix quase completo.Se você não precisa da biblioteca disponível no GAC (ou seja, disponível globalmente: na maioria das vezes, você não precisa disso nos assemblies .NET de qualquer maneira - provavelmente já fez algo errado neste momento, se não se destina a isso. uma biblioteca compartilhada), você deve atualizar a
CodeBase
chave do registro a ser configurada[#ComponentName]
. Se você está planejando instalá-lo no GAC (por exemplo, você criou uma nova biblioteca comum incrível que todo mundo vai querer usar), remova essa entrada e adicione dois novos atributos aoFile
elemento:Assembly
eKeyPath
. O conjunto deve ser definido como ".net" eKeyPath
"sim".No entanto, alguns ambientes (especialmente qualquer coisa com memória gerenciada, como linguagens de script) também precisarão acessar o Typelib. Certifique-se de executar
heat
no seu typelib e incluí-lo.heat
irá gerar todas as chaves de registro necessárias. Quão legal é isso?fonte
Instalando no
C:\ProductName
Alguns aplicativos precisam ser instalados
C:\ProductName
ou algo semelhante, mas 99,9% (se não 100%) dos exemplos na rede são instalados emC:\Program Files\CompanyName\ProductName
.O código a seguir pode ser usado para definir a
TARGETDIR
propriedade como raiz daC:
unidade (retirada da lista de usuários do WiX ):NOTA: Por padrão,
TARGETDIR
não aponta paraC:\
! Em vez disso, aponta para oROOTDRIVE
que, por sua vez, aponta para a raiz da unidade com mais espaço livre ( veja aqui ) - e esse não é necessariamente oC:
unidade. Pode haver outro disco rígido, partição ou unidade USB!Em seguida, em algum lugar abaixo da sua
<Product ...>
tag, você precisará das seguintes tags de diretório, como de costume:fonte
WindowsVolume
?WindowsVolume
propriedade não pode ser usada comoDirectory
(o compilador fornece um erro / aviso), conforme indicado aqui e aqui . Pessoalmente, acho essa solução alternativa confusa.Variáveis Ambientais
Ao compilar seus documentos Wxs para o código wixobj, você pode usar variáveis ambientais para determinar várias informações. Por exemplo, digamos que você queira alterar quais arquivos serão incluídos em um projeto. Digamos que você tenha uma variável ambiental chamada RELEASE_MODE, que você definiu logo antes de criar seu MSI (seja com um script ou manualmente, isso não importa) Na sua fonte wix, você pode fazer algo como:
e, posteriormente, em seu código, use-o no local para alterar rapidamente o documento wxs, por exemplo:
fonte
Usando o especial RobM "Lembre-se de propriedade" padrão
http://robmensching.com/blog/posts/2010/5/2/The-WiX-toolsets-Remember-Property-pattern
fonte
Criando ação personalizada para WIX gravada em código gerenciado (C #) sem votiva
http://www.codeproject.com/KB/install/wixcustomaction.aspx
fonte
Caixas de diálogo de edição
Uma boa capacidade de editar caixas de diálogo é usar o SharpDevelop na versão 4.0.1.7090 (ou superior). Com a ajuda dessa ferramenta, uma caixa de diálogo independente (arquivos wxs de fontes WiX como, por exemplo, InstallDirDlg.wxs) pode ser aberta, visualizada e editada no modo Design.
fonte
Definindo o sinalizador enable32BitAppOnWin64 do IIS http://trycatchfail.com/blog/post/WiX-Snippet-change-enable32BitAppOnWin64.aspx
fonte
Modifique o "Pronto para instalar?" caixa de diálogo (também conhecida como VerifyReadyDlg) para fornecer um resumo das escolhas feitas.
É assim:
alt text http://i46.tinypic.com/s4th7t.jpg
Faça isso com uma CustomAction Javascript:
Código Javascript:
Declare a CA Javascript:
Anexe a CA a um botão. Neste exemplo, a CA é acionada quando clicar em Avançar no CustomizeDlg:
Pergunta relacionada ao SO: Como definir, em tempo de execução, o texto a ser exibido no VerifyReadyDlg?
fonte
Coloque componentes que podem ser corrigidos individualmente dentro de seus próprios fragmentos
Isso vale para os instaladores e patches de produtos que, se você incluir qualquer componente em um fragmento, deverá incluir todos os componentes nesse fragmento. No caso de criar um instalador, se você perder alguma referência a componente, receberá um erro de vinculação no light.exe. No entanto, quando você cria um patch, se incluir uma referência de componente único em um fragmento, todos os componentes alterados desse fragmento serão exibidos no seu patch.
como isso:
em vez disso:
Além disso, ao aplicar patches usando o tópico "Using Purely WiX" no arquivo de ajuda WiX.chm, use este procedimento para gerar o patch:
não basta apenas ter a versão 1.1 do product.wixpdb criada usando os componentes em fragmentos separados. Portanto, certifique-se de fragmentar seu produto corretamente antes do envio.
fonte
Impressão do EULA a partir do Wix3.0 e posterior
1) Quando você compila seu código-fonte wix, o light.exe deve fazer referência ao WixUIExtension.dll na linha de comando. Use a opção de linha de comando -ext para isso.
2) Se quando você adicionar a referência ao WixUIExtension.dll, seu projeto falhar na compilação, isso provavelmente ocorrerá devido a conflitos de IDs de Diálogo, ou seja, seu projeto estava usando os mesmos IDs de diálogos que alguns diálogos padrão no WixUIExtension.dll, forneça IDs diferentes para suas caixas de diálogo. Este é um problema bastante comum.
3) O seu diálogo de licença deve ter o controle ScrollableText com o ID "LicenseText". O Wix procura exatamente esse nome de controle quando é impresso.
e um PushButton que se refere à ação personalizada
4) Defina CustomAction com o Id = "PrintEula" assim:
Nota: BinaryKey é diferente no Wix3.0 em comparação ao Wix2.0 e deve ser exatamente "WixUIWixca" (diferencia maiúsculas de minúsculas).
Quando o usuário pressionar o botão, ele será presenteado com a caixa de diálogo Selecionar impressora padrão e poderá imprimir a partir daí.
fonte
Exibimos a versão do produto em algum lugar (minúsculo) na primeira tela da GUI. Porque as pessoas tendem a cometer erros ao escolher a versão certa sempre. (E mantenha-nos desenvolvedores procurando por idades ..)
Configuramos o TFSBuild para também gerar transformações (arquivos .mst) com a configuração para nossos diferentes ambientes. (Conhecemos todos os ambientes nos quais precisamos implantar).
Como o post original de Grant Holliday está desativado, copio e colo seu conteúdo aqui:
Tarefa MSBuild para gerar arquivos MSI Transform a partir do XMLMarch 11 2008
Na minha postagem anterior, descrevi como você pode usar arquivos MSI Transform (* .mst) para separar as configurações específicas do ambiente de um pacote MSI genérico.
Embora isso ofereça um nível de flexibilidade em sua configuração, existem dois aspectos negativos dos arquivos do Transform:
Felizmente, podemos usar a Biblioteca de Objetos do Microsoft Windows Installer (c: windowssystem32msi.dll) para abrir “bancos de dados” MSI e criar arquivos de transformação.
Os créditos vão novamente para Alex Shevchuk - Do MSI ao WiX - Parte 7 - Personalizando a instalação usando o Transforms para nos mostrar como conseguir isso com o VbScript. Basicamente, tudo o que fiz foi usar o exemplo de Alex e, usando o Interop.WindowsInstaller.dll, implementei uma tarefa MSBuild. A tarefa MSBuild
Faça o download do código-fonte e do exemplo transforms.xml aqui (~ 7Kb Zipped VS2008 Solution)
fonte
Antes de implantar um pacote de instalação, eu sempre controlo o conteúdo dele.
É apenas uma simples chamada na linha de comando (de acordo com a publicação Terrences), abra a linha de comando e digite
Isso extrairá o conteúdo do pacote para um subdiretório 'Extrair' com o caminho atual.
fonte
Em vez de ORCA, use InstEd, que é uma boa ferramenta para visualizar tabelas MSI. Também tem a capacidade de diferenciar dois pacotes pelo Transform -> Compare To ...
Além disso, está disponível uma versão Plus com funcionalidade adicional. Mas também a versão gratuita oferece uma boa alternativa para o Orca.
fonte
Registrando assemblies .NET para interoperabilidade COM com compatibilidade x86 / x64
Nota: este fragmento é essencialmente o mesmo que o REGASM Assembly.dll / codebase
Algumas coisas estão acontecendo neste exemplo, então aqui está o código e eu explicarei depois ...
Se você estava se perguntando, isso é realmente para um driver de telescópio ASCOM .
Primeiro, segui os conselhos acima e criei algumas variáveis de plataforma em um arquivo separado, você pode ver aquelas espalhadas pelo XML.
A parte if-then-else, próxima à parte superior, lida com a compatibilidade x86 x x64. Meu assembly tem como alvo 'Qualquer CPU', em um sistema x64, preciso registrá-lo duas vezes, uma vez no registro de 64 bits e outra nas
Wow6432Node
áreas de 32 bits . O if-then-else me define para isso, os valores são usados em umforeach
loop posteriormente. Dessa forma, só preciso criar as chaves do registro uma vez (princípio DRY).O elemento file especifica a DLL de montagem real que está sendo instalada e registrada:
Nada revolucionário, mas observe o
Assembly=".net"
- esse atributo sozinho faria com que o assembly fosse colocado no GAC, o que NÃO era o que eu queria. Usar oAssemblyApplication
atributo para apontar de volta para si mesmo é simplesmente uma maneira de parar o Wix de colocar o arquivo no GAC. Agora que o Wix sabe que é um assembly .net, ele me permite usar certas variáveis do fichário dentro do meu XML, como!(bind.assemblyFullname.filDriverAssembly)
para obter o nome completo do assembly.fonte
Defina a
DISABLEADVTSHORTCUTS
propriedade para forçar todos os atalhos anunciados em seu instalador a se tornarem atalhos regulares, e você não precisa incluir uma chave de registro fictícia para ser usada como caminho de chave.Eu acho que o Windows Installer 4.0 ou superior é um requisito .
fonte
É uma estrutura legal, mas com base na minha experiência, pergunto-me como você lida com essas condições:
R. Todas as suas instalações parecem pousar no mesmo destino. Se um usuário precisar instalar todas as 3 versões ao mesmo tempo, seu processo permitirá isso. Eles podem dizer sem ambiguidade qual versão de cada executável está sendo acionada?
B. Como você lida com novos arquivos que existem no TEST e / ou TRAINING, mas ainda não no LIVE?
fonte
Aqui está uma maneira de ajudar grandes projetos da Web a verificar se o número de arquivos implantados corresponde ao número de arquivos criados em um MSI (ou módulo de mesclagem). Acabei de executar a tarefa personalizada do MSBuild em nosso aplicativo principal (ainda em desenvolvimento) e ele capturou alguns arquivos ausentes, principalmente imagens, mas alguns arquivos javascript haviam passado!
Essa abordagem (espreitando a tabela File do MSI conectando-se ao destino AfterBuild do projeto WiX) pode funcionar para outros tipos de aplicativos nos quais você tem acesso a uma lista completa dos arquivos esperados.
fonte
Executar uma reinstalação forçada quando uma instalação não permite desinstalar ou reinstalar e não reverte.
Script VBscript usado para substituir uma instalação que não está sendo desinstalada por qualquer motivo.
fonte
Crie uma interface do usuário que tenha uma ação personalizada que definirá uma variável e a interface do usuário desabilitará / habilitará o próximo botão (ou similar) com base na variável definida na ação personalizada.
Não é tão direto quanto você imagina, não é muito difícil, mas não está documentado em nenhum lugar!
Interações Wix com Condições, Propriedades e Ações Personalizadas
fonte