ASP .NET .NET Core

Criando aplicações desktop multiplataforma com ASP.NET Core e Electron.NET

Otimize a criação de aplicações desktop reutilizando códigos do ASP.NET Core, com a ajuda do Electron.NET.

há 3 anos 4 meses

Formação Especialista ASP.NET Core
Conheça a formação em detalhes

Com poucas exceções, atualmente qualquer nova aplicação é criada visando a web, pois desta forma estará acessível ao maior número de usuários. Entretanto, ela pode necessitar de uma versão desktop. Esta versão pode ser criada de várias formas, mas se a aplicação web for desenvolvida em ASP.NET Core, este processo pode ser otimizado com a ajuda do Electron.NET.

Electron.NET

Electron.NET é uma biblioteca open source que permite que aplicações ASP.NET Core sejam convertidas em aplicações Electron. Ela também fornece APIs que permite que essas aplicações acessem as APIs do Electron.

É importante frisar que esta biblioteca não reescreve o Electron e a aplicação ASP.NET Core não é convertida para uma aplicação desktop. Ela funciona basicamente como uma aplicação self-contained em um ambiente chamado “Electron”.

Preparando o ambiente

Para exemplificar o uso desta biblioteca, utilizarei uma aplicação ASP.NET Core simples, um ToDo, cujo o código pode ser visto no meu Github.

Configurando o Electron.NET na aplicação

Com o projeto web em mãos, podemos adicionar nele o Electron.NET. Esta biblioteca é composta de dois pacotes, o ElectronNET.API, que fornece acesso as APIs do Electron e o ElectronNET.CLI que é uma ferramenta global.

Desta forma, inicialmente é necessário adicionar à aplicação o pacote ElectronNET.API:

dotnet add package ElectronNET.API

Em seguida precisamos ativar a extensão UseElectron na classe Program, no método CreateHostBuilder:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseElectron(args);
            webBuilder.UseStartup<Startup>();
        });

Também será necessário configurá-lo na classe Startup, onde inicialmente criaremos o método abaixo:

private async void ElectronStatup()
{
    var window = await Electron.WindowManager.CreateWindowAsync();  
    window.OnClosed += () => {  
        Electron.App.Quit();  
    };  
}

Que será chamado no método Configure:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    //...
    
    if (HybridSupport.IsElectronActive)
    {
        ElectronStatup();
    }
}

Note que estamos utilizando a constante HybridSupport.IsElectronActive, para que o método ElectronStatup seja chamado apenas quando a aplicação estiver sendo executada pelo Electron.NET. Pois se a aplicação for executada como geralmente é feito:

dotnet run

Ainda será criado o servidor web e ela estará acessível via navegador:

Aplicação ASP.NET Core sendo executada como aplicação web

Para que seja executada como aplicação desktop, é necessário instalar a ferramenta global ElectronNET.CLI:

dotnet tool install ElectronNET.CLI -g

Ela irá adicionar no terminal o comando electronize. Que precisa ser iniciado:

electronize init

C# (C Sharp) - Introdução ao ASP.NET Core
Curso C# (C Sharp) - Introdução ao ASP.NET Core
Conhecer o curso

Este comando irá adicionar na aplicação um arquivo chamado electronnet.manifest.json, que conterá as configurações do Electron.NET. Com isso, agora podemos executá-la como aplicação desktop com o comando abaixo:

electronize start

Na primeira execução o Electron.NET irá instalar algumas dependências, então pode demorar um pouco. Nas demais ele é tão rápido quanto o dotnet run.

Com isso, a tela do nosso programa será exibida:

Aplicação ASP.NET Core sendo executada como aplicação desktop

Tornando a aplicação mais desktop

No momento a nossa aplicação desktop é apenas uma casca da aplicação web, felizmente o Electron.NET fornece uma série de recursos para torná-la mais desktop.

Podemos customizar a janela:

private async void ElectronStatup()
{
    var window = await Electron.WindowManager.CreateWindowAsync(
        new BrowserWindowOptions
        {
            Width = 1152,
            Height = 940,
            Show = false
        }
    );  
    
    await window.WebContents.Session.ClearCacheAsync();

    window.OnReadyToShow += () => window.Show();
    window.SetTitle("Exemplo do Electron.NET");

    window.OnClosed += () => {  
        Electron.App.Quit();  
    };  
}

E até mesmo criar um menu:

private void CreateMenu()  
{  
    bool isMac = RuntimeInformation.IsOSPlatform(OSPlatform.OSX);  
    MenuItem[] menu = null;

    MenuItem[] appMenu = new MenuItem[]  
    {  
        new MenuItem { Role = MenuRole.about },  
        new MenuItem { Type = MenuType.separator },  
        new MenuItem { Role = MenuRole.services },  
        new MenuItem { Type = MenuType.separator },  
        new MenuItem { Role = MenuRole.quit }  
    };

    MenuItem[] fileMenu = new MenuItem[]  
    {  
        new MenuItem { Role = isMac ? MenuRole.close : MenuRole.quit }  
    };

    MenuItem[] viewMenu = new MenuItem[]  
    {  
        new MenuItem { Role = MenuRole.reload },  
        new MenuItem { Role = MenuRole.forcereload },  
        new MenuItem { Role = MenuRole.toggledevtools },  
        new MenuItem { Type = MenuType.separator },  
        new MenuItem { Role = MenuRole.resetzoom },  
        new MenuItem { Type = MenuType.separator },  
        new MenuItem { Role = MenuRole.togglefullscreen }  
    };  

    if (isMac)  
    {  
        menu = new MenuItem[]  
        {  
            new MenuItem { 
				Label = "Electron", 
				Type = MenuType.submenu, 
				Submenu = appMenu 
			},  
            new MenuItem { 
				Label = "File", 
				Type = MenuType.submenu, 
				Submenu = fileMenu 
			},  
            new MenuItem { 
				Label = "View", 
				Type = MenuType.submenu, 
				Submenu = viewMenu 
			}  
        };  
    }  
    else  
    {  
        menu = new MenuItem[]  
        {  
            new MenuItem { 
				Label = "File", 
				Type = MenuType.submenu, 
				Submenu = fileMenu 
			},  
            new MenuItem { 
				Label = "View", 
				Type = MenuType.submenu, 
				Submenu = viewMenu 
			}  
        };  
    }

    Electron.Menu.SetApplicationMenu(menu);  
}

Que deve ser chamado, antes da criação da tela:

private async void ElectronStatup()
{
    CreateMenu();
    
    var window = await Electron.WindowManager.CreateWindowAsync(
    //...
}

Criando o executável

Ao final do desenvolvimento da aplicação, o executável dela pode ser criado com o comando abaixo:

electronize build /target osx

Note que é importante informar a plataforma do executável. Deve-se informar cada uma individualmente:

electronize build /target win
electronize build /target osx
electronize build /target linux

Mas no caso do MacOS (osx), devido as particularidades da plataforma, o executável dela só pode ser criado em um ambiente Unix (Linux e/ou MacOS).

Conclusão

Mesmo o .NET fornecendo outras opções para a criação de uma aplicação desktop, o Electron.NET é uma ótima opção para quem deseja criar uma aplicação desktop reaproveitando códigos de uma aplicação web. Isso agiliza o desenvolvimento, principalmente se for necessário criar uma aplicação multiplataforma.

No momento ela não possui uma documentação completa, mas a equipe do projeto auxilia a todos com dificuldade no Gitter. Então se quiser saber mais sobre a biblioteca, esta é uma boa fonte de informações.

Lembrando que você pode ver o código da aplicação demonstrada aqui no meu Github.

Autor(a) do artigo

Wladimilson M. Nascimento
Wladimilson M. Nascimento

Instrutor, nerd, cinéfilo e desenvolvedor nas horas vagas. Graduado em Ciências da Computação pela Universidade Metodista de São Paulo.

Todos os artigos

Artigos relacionados Ver todos