Click here to Skip to main content
15,886,518 members
Articles / Programming Languages / Javascript

Multiplatform Desktop HTML Editor with .NET Core 3 and Electron.NET

Rate me:
Please Sign up or sign in to vote.
4.93/5 (10 votes)
6 Jan 2020CPOL5 min read 20.6K   654   12  
Development of a multiplatform desktop application with .NET Core 3 and Electron.NET from scratch

Multiplatform HtmlEditor

Introduction

With .NET Core 3, C# developers have now many possibilities to develop truly multiplatform GUI applications. You can find a study of these solutions in a recently released book:

Electron.NET is one of the solutions presented in this book, it provides all means to code a GUI application for Windows, Linux and Mac OS X based on the same .NET Core 3 project.
Electron.NET is the .NET Core wrapper around the famous Electron framework (based on NodeJS).

For illustrating the use of this tool, I will develop an HTML Editor application. This prototype program illustrates the Electron.NET’s capacity to use JavaScript component inside a cross platform desktop application.
In our case, the CKeditor is used for the implementation of the editor itself.

An Electron.NET application is built from an ASP.NET MVC web application, and, therefore extended with the specifics features of a desktop application by using the Electron wrapper for .NET Core: Electron.NET.

Prerequisites

Before reviewing the development of the HTMLEditor application with Electron.NET, you have to install the appropriate development environment.

So you should have installed on your computer:

  • NodeJS
  • NPM
  • Electron.NET global tool for dotnet CLI (see the GitHub website)

Check the GitHub web site of the project: https://github.com/ElectronNET/Electron.NET.

The HtmlEditor application use the 5.30.1 version of Electron.NET.

Be careful, you have to double check that you are using the appropriate .NET Core version, the current version of Electron.NET is targeting the .NET Core 3.0 (if you use the 3.1 version of .NET Core, it will not work… not even install).

Application Coding

The development of the application can be described as a simple process.

1. Creation of the ASP.NET MVC Application

First, you have to create a standard .NET Core 3 ASP.NET MVC application, with the following command for example, but you can use Visual Studio.

dotnet new mvc -o Multiplatform.HtmlEditor

2. Add ElectronNET.API NuGet Packages to the Project

For adding the NuGet dependencies, you can use the familar "NuGet package Manager" of Visual Studio:

Add the ElectronNET.API package to the project.

You have to install the CLI tool as well.
For adding the required dotnet CLI Electron.NET global tool:

dotnet tool install ElectronNET.CLI -g --version 5.30.1

3. Instantiate ElectronNET.API in the Application

This is done by adding an instance of the Electron wrapper in the MVC app. Actually, in the startup.cs file:

C#
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment()) {
        app.UseDeveloperExceptionPage();
    } else {
        app.UseExceptionHandler("/Home/Error");
    }
    app.UseStaticFiles();

    app.UseRouting();

    app.UseEndpoints(endpoints => {
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
    });

    // Open the Electron-Window here
    //Task.Run(async () => await Electron.WindowManager.CreateWindowAsync());
    if (HybridSupport.IsElectronActive) {
        ElectronBootstrap();
    }
}

public async void ElectronBootstrap()
{
    var browserWindow = await Electron.WindowManager.CreateWindowAsync
                        (new BrowserWindowOptions {
        Width = 1000,
        Height = 800,
        Show = false,
    });

    browserWindow.OnReadyToShow += () => browserWindow.Show();
    browserWindow.SetTitle("HTMLEditor 2020");
}

The application is running now in a desktop container, but does not integrate any features:

Add the ElectronNET.API package to the project.

Besides adding Electron in the application, the default ASP.NET MVC application has been cleaned from the unnecessary code (pages, logging, config …).

4. Add Custom Menu to the Application

Once the application is running as desktop app, you have to modify the default native menu. For doing that, the “native” menu of the application is implemented with a dedicated MVC Controller: MenusController.cs.

C#
>
public class MenusController : Controller
{
    public IActionResult Index()
    {
        if (HybridSupport.IsElectronActive) {
            var menu = new MenuItem[] {
                new MenuItem {
                    Label = "File", Submenu = new MenuItem[] {
                        new MenuItem {
                            Label = "Open HTML",
                            Accelerator = "CmdOrCtrl+O",
                            Click = async ()  =>
                            {
                                // Open file HTML
                                var mainWindow = Electron.WindowManager.BrowserWindows.First();
                                var options = new OpenDialogOptions
                                {
                                    Title = "Open HTML file",
                                    Filters = new FileFilter[]
                                    {
                                        new FileFilter { Name = "HTML", 
                                          Extensions = new string[] {"html","htm" } }
                                    }
                                };

                                var result = await Electron.Dialog.ShowOpenDialogAsync
                                             (mainWindow, options);

                                if (result.First() != "")
                                {
                                    string OpenfilePath = result.First();
                                    string strContent = FileOperation.openRead(OpenfilePath);

                                    //Call Render JS
                                    var mainWindow1 = 
                                        Electron.WindowManager.BrowserWindows.First();
                                    Electron.IpcMain.Send
                                        (mainWindow1,"setContent",strContent);

                                    mainWindow.SetTitle(OpenfilePath);
                                }
                            }
                        },
                        new MenuItem { Label = "Save HTML",
                                       Accelerator = "CmdOrCtrl+S",
                                       Click = async () =>
                        {
                            var mainWindow = Electron.WindowManager.BrowserWindows.First();

                            Electron.IpcMain.Send(mainWindow,"saveContent");
                        }
                                     },
                        new MenuItem { Type = MenuType.separator },
                        new MenuItem {
                            Label = "Exit",
                            Accelerator = "CmdOrCtrl+X",
                            Click = () =>
                            {
                                // Exit app
                                Electron.App.Exit();
                            }
                        },
                    }
                },
                new MenuItem {
                    Label = "Help", Submenu = new MenuItem[] {
                        new MenuItem
                        {
                            Label = "About",
                            Accelerator = "CmdOrCtrl+R",
                            Click = async () =>
                            {
                                // open native  message  windows
                                var options = new MessageBoxOptions
                                      ("This is a demo application for Electron.NEt 
                                        and .NET CORE 3.");
                                options.Type = MessageBoxType.info;
                                options.Title = "About HTMLEditor";

                                await Electron.Dialog.ShowMessageBoxAsync(options);
                            }
                        }
                    }
                }
            };
            Electron.Menu.SetApplicationMenu(menu);
        }
        return View();
    }
}

Notice that the menu controller can be used for calling (sync or async) the several features of the application.

5. Add the JavaScript HTML Editor in Your Application

The HTML editor itself is a freely available JavaScript component: CKeditor4.
The web site allows you to personalize the menu of the editor by generating a config.js file. This file is directly downloadable from the ckeditor4 web site: https://github.com/ckeditor/ckeditor4.

A dedicated web site allows you to configure the editor with a dedicated graphical interface. You can find this app online at https://ckeditor.com/cke4/builder.

Once you have created the appropriate configuration file, you have to add it to your MVC project (on the client side).

The required components (js, css, img) for the implementation of the editor have to be added to the project. Here is the files arborescence of the client dependencies for adding the ckeditor4 HTML editor to your project.

Add Ckeditor to the ASP.NET app.

6. Establishing Communication Between the Main Thread and the Render Thread

There are two functions which require communication between the C# (main process) and the Html/Js (Render process).

  • Open File
  • Save File

Here is the schema of the communication between the two-processes needed for the implementation of these two features:

Open File

Image 5

Save File

Image 6

7. Use the File’s Operations Object

The editor integrates the basic file’s operations: Open, Save. A dedicated class is implemented for these operations: FileOperations.cs. This static object integrates the two matching methods required for the example.

Once each of these steps has been done successfully (and tested), the application is finished, well almost, you have to build the project and it could be a little bit tricky regarding the type of executable you want to produce.

8. Build the .NET Core 3 / Electron.NET Application

For the first release of this article, the most obvious (actually the basic) executable deploiement type is exposed.

This part is very well documented on the ElectronNET GitHub web site.

  • First, you have to create the Electron configuration file for the ASP.NET MVC application with the command:
    electronize init
    
  • Thereafter, you can execute the application with the command:
    electronize start
    

    This command will do the build, and the restore for the project, it could take a little time the first time it is executed (the Electron wrapper has to be loaded).

Current Issues

  • I have not managed to update the icon of the application (working on it)
  • The menu display “Electron” and not “File” in the menu bar on Mac OS X.

Conclusion

The usage of Electron.NET appears to be a solution of choice for the ASP.NET developers who want to develop multiplatform desktop application (for Windows, Linux and MacOS X). Electron.NET makes it possible.

With the encapsulation of a web application into a desktop application, many JavaScript components can be reused or recycled for a desktop development and that is a strong point of this way of doing. There are plenty of JavaScript components that can be a great addition to a desktop application (for the navigation, GUI effects …).

Nevertheless, the use of Electron.NET is not optimized for the Windows platform, and many methods of the original project are not available in the .NET Core wrapper. Besides, Elentron.NET requires you to master the JavaScript programing more than actually ASP.NET C# knowledge.

But Electron.NET is a great wrapper that can be used if you want to produce desktop application from your web site development.

If Electron.NET does not match your expectations, there are many other solutions for coding a multi-platform GUI desktop application with C# .NET Core 3, check the book which inspired this article here.

History

  • 6th January, 2020: First version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



Comments and Discussions

 
-- There are no messages in this forum --