Implantar aplicativos .NET Core com o Visual Studio

Você pode implantar um aplicativo .NET Core como uma implantação dependente de estrutura, que inclui os binários do seu aplicativo, mas depende da presença do .NET Core no sistema de destino, ou como uma implantação autocontida, que inclui os binários do seu aplicativo e do .NET Core. Para obter uma visão geral da implantação de aplicativos .NET Core, consulte Implantação de aplicativos .NET Core.

As seções a seguir mostram como usar o Microsoft Visual Studio para criar os seguintes tipos de implantações:

  • Implantação dependente de estrutura
  • Implantação dependente de estrutura com dependências de terceiros
  • Implantação autocontida
  • Implantação autocontida com dependências de terceiros

Para obter mais informações sobre como usar o Visual Studio para desenvolver aplicativos .NET Core, consulte Dependências e requisitos do .NET Core.

Implantação dependente de estrutura

Implantar uma implantação dependente de estrutura sem dependências de terceiros significa simplesmente compilar, testar e publicar o aplicativo. Um exemplo simples criado em C# ilustra o processo.

  1. Crie o projeto.

    Selecione Arquivo>Novo>Projeto. Na caixa de diálogo Novo projeto, expanda as categorias de projeto (C# ou Visual Basic) de sua linguagem no painel de tipos de projeto Instalados, escolha .NET Core e, em seguida, selecione o modelo Aplicativo de console (.NET Core) no painel central. Insira um nome de projeto, como "FDD" na caixa de texto Nome. Selecione o botão OK.

  2. Adicione o código-fonte do aplicativo.

    Abra o arquivo Program.cs ou Program.vb no editor e substitua o código gerado automaticamente com o seguinte código. Ele solicitará que o usuário insira texto e exibirá as palavras individuais inseridas pelo usuário. Ele usa a expressão regular \w+ para separar as palavras no texto de entrada.

    using System;
    using System.Text.RegularExpressions;
    
    namespace Applications.ConsoleApps
    {
        public class ConsoleParser
        {
            public static void Main()
            {
                Console.WriteLine("Enter any text, followed by <Enter>:\n");
                String? s = Console.ReadLine();
                ShowWords(s ?? "You didn't enter anything.");
                Console.Write("\nPress any key to continue... ");
                Console.ReadKey();
            }
    
            private static void ShowWords(String s)
            {
                String pattern = @"\w+";
                var matches = Regex.Matches(s, pattern);
                if (matches.Count == 0)
                {
                    Console.WriteLine("\nNo words were identified in your input.");
                }
                else
                {
                    Console.WriteLine($"\nThere are {matches.Count} words in your string:");
                    for (int ctr = 0; ctr < matches.Count; ctr++)
                    {
                        Console.WriteLine($"   #{ctr,2}: '{matches[ctr].Value}' at position {matches[ctr].Index}");
                    }
                }
            }
        }
    }
    
    Imports System.Text.RegularExpressions
    
    Namespace Applications.ConsoleApps
        Public Module ConsoleParser
            Public Sub Main()
                Console.WriteLine("Enter any text, followed by <Enter>:")
                Console.WriteLine()
                Dim s = Console.ReadLine()
                ShowWords(s)
                Console.Write($"{vbCrLf}Press any key to continue... ")
                Console.ReadKey()
            End Sub
    
            Private Sub ShowWords(s As String)
                Dim pattern = "\w+"
                Dim matches = Regex.Matches(s, pattern)
                Console.WriteLine()   
                If matches.Count = 0 Then
                    Console.WriteLine("No words were identified in your input.")
                Else
                    Console.WriteLine($"There are {matches.Count} words in your string:")
                    For ctr = 0 To matches.Count - 1
                        Console.WriteLine($"   #{ctr,2}: '{matches(ctr).Value}' at position {matches(ctr).Index}")
                    Next
                End If
                Console.WriteLine()
            End Sub
        End Module
    End Namespace
    
    
  3. Crie um build de depuração do seu aplicativo.

    Selecione Compilar>Compilar Solução. Você também pode compilar e executar o build de Depuração do aplicativo selecionando Depurar>Iniciar Depuração.

  4. Implante seu aplicativo.

    Depois de ter depurado e testado o programa, crie os arquivos a serem implantados com seu aplicativo. Para publicar do Visual Studio, faça o seguinte:

    1. Altere a configuração da solução de Depuração para Lançamento na barra de ferramentas para compilar uma versão de lançamento (em vez de uma de depuração) do aplicativo.

    2. Clique com o botão direito do mouse no projeto (e não na solução) no Gerenciador de Soluções e selecione Publicar.

    3. Na guia Publicar, selecione Publicar. O Visual Studio grava os arquivos que compõem seu aplicativo no sistema de arquivos local.

    4. A guia Publicar agora mostra um único perfil FolderProfile. As configurações do perfil são mostradas na seção Resumo da guia.

    Os arquivos resultantes são colocados em um diretório nomeado Publish no Windows e publish em sistemas Unix que está em um subdiretório do subdiretório .\bin\release\netcoreapp2.1 do seu projeto.

Junto com os arquivos do aplicativo, o processo de publicação emite um arquivo de banco de dados do programa (.pdb) que contém informações de depuração sobre seu aplicativo. O arquivo é útil principalmente para exceções de depuração. Você pode optar por não empacotá-lo com os arquivos do aplicativo. No entanto, você deve salvá-lo no caso de desejar depurar o build de lançamento para seu aplicativo.

Implante o conjunto completo de arquivos de aplicativo da maneira que desejar. Por exemplo, você pode empacotá-los em um arquivo zip, usar um simples comando copy ou implantá-los com qualquer pacote de instalação de sua escolha. Uma vez instalado, os usuários podem executar seu aplicativo usando o comando dotnet e fornecendo o nome de arquivo de aplicativo, como dotnet fdd.dll.

Além dos binários do aplicativo, o instalador deverá também agrupar o instalador da estrutura compartilhada ou procurar por ele como um pré-requisito como parte da instalação do aplicativo. A instalação da estrutura compartilhada requer acesso de Administrador/raiz, pois se trata de todo o computador.

Implantação dependente de estrutura com dependências de terceiros

Implantar uma implantação dependente de estrutura com uma ou mais dependências de terceiros requer que todas as dependências estejam disponíveis para seu projeto. As etapas adicionais a seguir são necessárias antes de ser possível compilar seu aplicativo:

  1. Use o Gerenciador de Pacotes NuGet para adicionar uma referência a um pacote NuGet ao projeto e se o pacote ainda não estiver disponível no sistema, instale-o. Para abrir o gerenciador de pacotes, selecione Ferramentas>Gerenciador de Pacotes NuGet>Gerenciar Pacotes NuGet para a Solução.

  2. Confirme se as dependências de terceiros (por exemplo, Newtonsoft.Json) estão instaladas no sistema e, se não estiverem, instale-as. A guia Instalados lista os pacotes NuGet instalados no sistema. Se Newtonsoft.Json não estiver listado, selecione a guia Procurar e insira "Newtonsoft.Json" na caixa de pesquisa. Selecione Newtonsoft.Json e, no painel direito, selecione seu projeto antes de selecionar Instalar.

  3. Se Newtonsoft.Json já estiver instalado no sistema, adicione-o ao projeto selecionando o projeto no painel direito da guia Gerenciar Pacotes para a Solução.

Uma implantação dependente de estrutura com dependências de terceiros é tão portátil quanto as dependências de terceiros. Por exemplo, se uma biblioteca de terceiros der suporte apenas a macOS, o aplicativo não será portátil para sistemas Windows. Isso acontecerá se a dependência de terceiros em si depender do código nativo. Um bom exemplo disso é o servidor Kestrel, que requer uma dependência nativa no libuv. Quando uma FDD é criada para um aplicativo com esse tipo de dependência de terceiros, a saída publicada contém uma pasta para cada RID (Identificador de Runtime) que dá suporte a dependência nativa (e que existe em seu pacote NuGet).

Implantação autocontida sem dependências de terceiros

Implantar uma implantação autocontida sem dependências de terceiros inclui a criação do projeto, a modificação do arquivo csproj, a compilação, os testes e a publicação do aplicativo. Um exemplo simples criado em C# ilustra o processo. Comece criando, codificando e testando seu projeto como você faria com uma implantação que depende da estrutura:

  1. Crie o projeto.

    Selecione Arquivo>Novo>Projeto. Na caixa de diálogo Novo projeto, expanda as categorias de projeto (C# ou Visual Basic) de sua linguagem no painel de tipos de projeto Instalados, escolha .NET Core e, em seguida, selecione o modelo Aplicativo de console (.NET Core) no painel central. Insira um nome de projeto, como "SCD" na caixa de texto Nome e selecione o botão OK.

  2. Adicione o código-fonte do aplicativo.

    Abra o arquivo Program.cs ou Program.vb no editor e substitua o código gerado automaticamente com o código a seguir. Ele solicitará que o usuário insira texto e exibirá as palavras individuais inseridas pelo usuário. Ele usa a expressão regular \w+ para separar as palavras no texto de entrada.

    using System;
    using System.Text.RegularExpressions;
    
    namespace Applications.ConsoleApps
    {
        public class ConsoleParser
        {
            public static void Main()
            {
                Console.WriteLine("Enter any text, followed by <Enter>:\n");
                String? s = Console.ReadLine();
                ShowWords(s ?? "You didn't enter anything.");
                Console.Write("\nPress any key to continue... ");
                Console.ReadKey();
            }
    
            private static void ShowWords(String s)
            {
                String pattern = @"\w+";
                var matches = Regex.Matches(s, pattern);
                if (matches.Count == 0)
                {
                    Console.WriteLine("\nNo words were identified in your input.");
                }
                else
                {
                    Console.WriteLine($"\nThere are {matches.Count} words in your string:");
                    for (int ctr = 0; ctr < matches.Count; ctr++)
                    {
                        Console.WriteLine($"   #{ctr,2}: '{matches[ctr].Value}' at position {matches[ctr].Index}");
                    }
                }
            }
        }
    }
    
    Imports System.Text.RegularExpressions
    
    Namespace Applications.ConsoleApps
        Public Module ConsoleParser
            Public Sub Main()
                Console.WriteLine("Enter any text, followed by <Enter>:")
                Console.WriteLine()
                Dim s = Console.ReadLine()
                ShowWords(s)
                Console.Write($"{vbCrLf}Press any key to continue... ")
                Console.ReadKey()
            End Sub
    
            Private Sub ShowWords(s As String)
                Dim pattern = "\w+"
                Dim matches = Regex.Matches(s, pattern)
                Console.WriteLine()   
                If matches.Count = 0 Then
                    Console.WriteLine("No words were identified in your input.")
                Else
                    Console.WriteLine($"There are {matches.Count} words in your string:")
                    For ctr = 0 To matches.Count - 1
                        Console.WriteLine($"   #{ctr,2}: '{matches(ctr).Value}' at position {matches(ctr).Index}")
                    Next
                End If
                Console.WriteLine()
            End Sub
        End Module
    End Namespace
    
    
  3. Determine se você deseja usar o modo de invariável de globalização.

    Especialmente se seu aplicativo for destinado ao Linux, será possível reduzir o tamanho total da sua implantação usando o modo invariável de globalização. O modo invariável de globalização é útil para aplicativos que não são conhecidos globalmente e que podem usar as convenções de formatação, de maiúsculas e minúsculas e a comparação de cadeia de caracteres e ordem de classificação da cultura invariável.

    Para habilitar o modo invariável, clique com o botão direito do mouse no seu projeto (não na solução) no Gerenciador de Soluções e selecione Editar SCD.csproj ou Editar SCD.vbproj. Em seguida, adicione as seguintes linhas realçadas ao arquivo:

    <Project Sdk="Microsoft.NET.Sdk">
    
      <PropertyGroup>
        <TargetFramework>net6.0</TargetFramework>
        <Nullable>enable</Nullable>
      </PropertyGroup>
    
      <ItemGroup>
        <RuntimeHostConfigurationOption Include="System.Globalization.Invariant" Value="true" />
      </ItemGroup> 
    
    </Project>
    
  4. Crie um build de depuração do seu aplicativo.

    Selecione Compilar>Compilar Solução. Você também pode compilar e executar o build de Depuração do aplicativo selecionando Depurar>Iniciar Depuração. Essa etapa de depuração permite identificar problemas com seu aplicativo quando ele está em execução em sua plataforma de host. Ainda será necessário testá-lo em cada uma de suas plataformas de destino.

    Se você tiver habilitado o modo invariável de globalização, certifique-se principalmente de testar se a ausência de dados que levam em conta a cultura é adequada para o seu aplicativo.

Após concluir a depuração, será possível publicar sua implantação independente:

Depois de ter depurado e testado o programa, crie os arquivos a serem implantados com seu aplicativo para cada plataforma à qual ele se destina.

Para publicar seu aplicativo do Visual Studio, faça o seguinte:

  1. Defina as plataformas às quais seu aplicativo se destinará.

    1. Clique com o botão direito do mouse no projeto (e não na solução) no Gerenciador de Soluções e selecione Editar SCD.csproj.

    2. Crie uma marcação <RuntimeIdentifiers> na seção <PropertyGroup> de seu arquivo csproj que define as plataformas de destino do seu aplicativo e especifique o RID (identificador de runtime) de cada plataforma que você selecionar. Também é necessário adicionar um ponto e vírgula para separar os RIDs. Consulte o Catálogo de identificadores de runtime para obter uma lista de identificadores de runtime.

    Por exemplo, o exemplo a seguir indica que o aplicativo é executado em sistemas operacionais Windows 64 de 64 bits e no sistema de operacional OS X de 64 bits.

    <PropertyGroup>
       <RuntimeIdentifiers>win-x64;osx-x64</RuntimeIdentifiers>
    </PropertyGroup>
    

    O elemento <RuntimeIdentifiers> poderá ir para qualquer <PropertyGroup> que exista no arquivo csproj. Um arquivo csproj de exemplo completo aparece mais adiante nesta seção.

  2. Publique seu aplicativo.

    Depois de ter depurado e testado o programa, crie os arquivos a serem implantados com seu aplicativo para cada plataforma à qual ele se destina.

    Para publicar seu aplicativo do Visual Studio, faça o seguinte:

    1. Altere a configuração da solução de Depuração para Lançamento na barra de ferramentas para compilar uma versão de lançamento (em vez de uma de depuração) do aplicativo.

    2. Clique com o botão direito do mouse no projeto (e não na solução) no Gerenciador de Soluções e selecione Publicar.

    3. Na guia Publicar, selecione Publicar. O Visual Studio grava os arquivos que compõem seu aplicativo no sistema de arquivos local.

    4. A guia Publicar agora mostra um único perfil FolderProfile. As definições de configuração do perfil são mostradas na seção Resumo da guia. O Runtime de Destino identifica qual runtime foi publicado e o Local de Destino identifica onde os arquivos da implantação independente foram gravados.

    5. Por padrão, o Visual Studio grava todos os arquivos publicados em um único diretório. Para sua conveniência, é melhor criar perfis separados para cada runtime de destino e colocar os arquivos publicados em um diretório específico da plataforma. Isso envolve a criação de um perfil de publicação separado para cada plataforma de destino. Agora recompile o aplicativo para cada plataforma fazendo o seguinte:

      1. Selecione Criar novo perfil na caixa de diálogo Publicar.

      2. Na caixa de diálogo Escolher um destino de publicação, altere o local de Escolher uma pasta para bin\Release\PublishOutput\win-x64. Selecione OK.

      3. Selecione o novo perfil (FolderProfile1) na lista de perfis e certifique-se de que o Runtime de Destino é win-x64. Se não for, selecione Configurações. Na caixa de diálogo Configurações de Perfil, altere o Runtime de Destino para win-x64 e selecione Salvar. Caso contrário, selecione Cancelar.

      4. Selecione Publicar para publicar seu aplicativo para plataformas Windows 10 de 64 bits.

      5. Siga as etapas anteriores novamente para criar um perfil para a plataforma osx-x64. O Local de Destino é bin\Release\PublishOutput\osx-x64 e o Runtime de Destino é osx-x64. O nome que o Visual Studio atribui a este perfil é FolderProfile2.

    Cada local de destino contém o conjunto completo de arquivos (os arquivos do aplicativo e todos os arquivos .NET Core) necessários para iniciar o aplicativo.

Junto com os arquivos do aplicativo, o processo de publicação emite um arquivo de banco de dados do programa (.pdb) que contém informações de depuração sobre seu aplicativo. O arquivo é útil principalmente para exceções de depuração. Você pode optar por não empacotá-lo com os arquivos do aplicativo. No entanto, você deve salvá-lo no caso de desejar depurar o build de lançamento para seu aplicativo.

Implante os arquivos publicados na maneira que desejar. Por exemplo, você pode empacotá-los em um arquivo zip, usar um simples comando copy ou implantá-los com qualquer pacote de instalação de sua escolha.

A seguir está o arquivo csproj completo para esse projeto.

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.1</TargetFramework>
    <RuntimeIdentifiers>win-x64;osx-x64</RuntimeIdentifiers>
  </PropertyGroup>
</Project>

Implantação autocontida com dependências de terceiros

Implantar uma implantação autocontida com uma ou mais dependências de terceiros envolve adicionar as dependências. As etapas adicionais a seguir são necessárias antes de ser possível compilar seu aplicativo:

  1. Use o Gerenciador de Pacotes NuGet para adicionar uma referência a um pacote NuGet ao projeto e se o pacote ainda não estiver disponível no sistema, instale-o. Para abrir o gerenciador de pacotes, selecione Ferramentas>Gerenciador de Pacotes NuGet>Gerenciar Pacotes NuGet para a Solução.

  2. Confirme se as dependências de terceiros (por exemplo, Newtonsoft.Json) estão instaladas no sistema e, se não estiverem, instale-as. A guia Instalados lista os pacotes NuGet instalados no sistema. Se Newtonsoft.Json não estiver listado, selecione a guia Procurar e insira "Newtonsoft.Json" na caixa de pesquisa. Selecione Newtonsoft.Json e, no painel direito, selecione seu projeto antes de selecionar Instalar.

  3. Se Newtonsoft.Json já estiver instalado no sistema, adicione-o ao projeto selecionando o projeto no painel direito da guia Gerenciar Pacotes para a Solução.

A seguir está o arquivo csproj completo para esse projeto:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.1</TargetFramework>
    <RuntimeIdentifiers>win-x64;osx-x64</RuntimeIdentifiers>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Newtonsoft.Json" Version="10.0.2" />
  </ItemGroup>
</Project>

Quando você implanta seu aplicativo, todas as dependências de terceiros usadas em seu aplicativo também contém os arquivos do aplicativo. As bibliotecas de terceiros não são necessárias no sistema em que o aplicativo está em execução.

Você só poderá implantar uma implantação independente com uma biblioteca de terceiros em plataformas que tenham suporte para essa biblioteca. Isso é semelhante a ter dependências de terceiros com dependências nativas em sua implantação dependente de estrutura, em que as dependências nativas não existem na plataforma de destino a menos que elas tenham sido instaladas anteriormente.

Confira também