Instalador .NET: o que o setup não faz no cliente
O setup copia arquivos e cria atalhos. Runtime do .NET 10, firewall do SQL Server e teste no Windows Sandbox são outra etapa. Veja como separar e testar.
O mesmo programa de caixa, um WinForms vazio em .NET 10, publicado para Windows de três jeitos, gerou pastas de 182 KB, 116 MB e 123 MB. A diferença é o runtime do .NET: ou ele vai junto com o programa, ou a máquina do cliente já precisa tê-lo. Essa é a primeira de várias decisões que o setup não toma por você. Um instalador copia arquivos, cria atalhos e sabe se desinstalar. Ele não instala o runtime sozinho, não abre o firewall do computador onde está o banco e não descobre qual é o servidor do cliente.
Este post separa o que é trabalho do instalador do que é trabalho de implantação, com um programa de desktop que grava vendas num SQL Server de outro computador da loja. O que o próprio aplicativo precisa fazer antes de virar MSI (configuração no primeiro uso, senha protegida, dados fora da pasta do programa) está em instalador .NET que leva a connection string do seu PC.
O runtime: escolha antes de montar o setup
A figura mostra as três publicações do mesmo projeto, feitas com dotnet publish -c Release -r win-x64 no SDK 10.0.402:

O guia de publicação do .NET descreve as opções:
- Dependente do runtime (
--self-contained false): a pasta é minúscula, mas o cliente precisa do .NET Desktop Runtime. O arquivoruntimeconfig.jsongerado diz exatamente o quê. - Autocontido (
--self-contained true): o runtime vai na pasta, com 232 arquivos. Nada a instalar antes, mas cada atualização de segurança do .NET exige uma versão nova do seu programa. - Arquivo único (
-p:PublishSingleFile=true): o mesmo runtime embutido num só.exe(o segundo arquivo da pasta é o.pdbde depuração, que não precisa ir para o cliente).
O runtimeconfig.json da versão dependente:
{
"runtimeOptions": {
"tfm": "net10.0",
"frameworks": [
{
"name": "Microsoft.NETCore.App",
"version": "10.0.0"
},
{
"name": "Microsoft.WindowsDesktop.App",
"version": "10.0.0"
}
],
"configProperties": {
"System.Reflection.Metadata.MetadataUpdater.IsSupported": false,
"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false,
"CSWINRT_USE_WINDOWS_UI_XAML_PROJECTIONS": false
}
}
}
Ou seja, além do runtime básico, um app WinForms precisa do Microsoft.WindowsDesktop.App 10. Se for por esse caminho, o setup tem de verificar e instalar o .NET Desktop Runtime, ou a página de download tem de dizer isso com todas as letras.
A versão importa também por prazo. Segundo a política de suporte do .NET, o .NET 8 e o .NET 9 deixam de receber correções em 10 de novembro de 2026. O .NET 10 é LTS, com suporte até 14 de novembro de 2028, e está no patch 10.0.14 (de 25/10/2026). Programa novo, ou que ainda vai para cliente neste fim de ano, deve mirar o .NET 10. As correções de segurança recentes estão em atualização de segurança do .NET de outubro de 2026.
O banco em outro computador: firewall e protocolo
Quando o SQL Server fica no computador do escritório e o caixa conecta pela rede, duas coisas acontecem lá, e não no caixa. O setup do caixa não tem como fazê-las.
Primeiro, o protocolo TCP/IP tem de estar habilitado na instância. Confira no SQL Server Configuration Manager; a documentação lembra que o serviço precisa ser reiniciado para a mudança valer.
Depois, o firewall do Windows daquele computador precisa aceitar a conexão. O guia de firewall do SQL Server traz o exemplo com a porta TCP 1433 da instância padrão e a UDP 1434 do SQL Server Browser. Uma versão limitada à rede local, executada no PowerShell como administrador no computador do banco:
New-NetFirewallRule -DisplayName "SQL Server (rede da loja)" -Direction Inbound ` -Protocol TCP -LocalPort 1433 -RemoteAddress LocalSubnet -Profile Private -Action Allow # Só se usar instância nomeada (ex.: SERVIDOR\SQLEXPRESS), que usa porta dinâmica: New-NetFirewallRule -DisplayName "SQL Server Browser (rede da loja)" -Direction Inbound ` -Protocol UDP -LocalPort 1434 -RemoteAddress LocalSubnet -Profile Private -Action Allow
O mesmo guia avisa que instância nomeada usa porta dinâmica. Nesse caso, ou você fixa uma porta TCP na instância e libera essa porta, ou libera o executável do serviço. Fixar a porta é mais previsível para quem dá suporte. A connection string do caixa aponta para o nome ou IP desse computador, e trocá-la depois tem jeito certo, explicado em connection string não se troca na tela.
Teste numa máquina que nunca viu o programa
O teste que pega quase tudo é instalar num Windows limpo. O Windows Sandbox abre um Windows descartável, sem nada do que está instalado na sua máquina, e apaga tudo ao fechar. Ele não existe no Windows Home; nas outras edições, é ativado em Recursos do Windows.
Um arquivo .wsb, no formato da documentação, monta a pasta do instalador só para leitura e abre o Explorer nela:
<Configuration>
<MappedFolders>
<MappedFolder>
<HostFolder>C:\builds\caixa\setup</HostFolder>
<SandboxFolder>C:\setup</SandboxFolder>
<ReadOnly>true</ReadOnly>
</MappedFolder>
</MappedFolders>
<LogonCommand>
<Command>explorer.exe C:\setup</Command>
</LogonCommand>
</Configuration>
Dê dois cliques no arquivo e, dentro da sandbox, faça o que o cliente faria: instale como usuário comum, abra pelo atalho, informe o servidor, registre uma venda, feche e abra de novo. Se a versão é dependente do runtime, a sandbox começa sem o .NET Desktop Runtime 10, então é ali que você vê se o setup o instala ou se o cliente vai receber um aviso pedindo o download. A rede da sandbox vem ligada por padrão, então dá para testar a conexão com o banco real da loja.
O que vai na folha de implantação
Tudo o que o setup não faz precisa estar escrito para quem instala: qual runtime (ou nenhum, se autocontido), em qual computador fica o banco, as regras de firewall acima, o nome da instância e a porta, e onde ficam os dados e o backup. Para a parte de atualizar sem perder vendas, veja atualizar o sistema com backup.
As três publicações e o runtimeconfig.json deste post foram gerados de verdade com o SDK do .NET 10 (a publicação para win-x64 roda até fora do Windows). As regras de firewall e o arquivo .wsb seguem a documentação da Microsoft, mas não foram executados aqui, porque exigem Windows.
Referência: https://learn.microsoft.com/pt-br/visualstudio/deployment/installer-projects-net-core