Skip to content

Latest commit

 

History

History
168 lines (140 loc) · 5.43 KB

manual-installation.md

File metadata and controls

168 lines (140 loc) · 5.43 KB

Manual Installation

Create a new WPF/WinForms project or open an existing one.

Install the Microsoft.Web.WebView2 NuGet package.

Install-Package Microsoft.Web.WebView2
# or
dotnet add package Microsoft.Web.WebView2

Install the PhosphorusNET.Ipc NuGet package.

Install-Package PhosphorusNET.Ipc
# or
dotnet add package PhosphorusNET.Ipc

Depending on your project type, you'll have to modify your Window/UserControl to include a WebView2 control. Here's an example for WPF:

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp1"
        xmlns:wpf="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <DockPanel>
            <wpf:WebView2 Name="webView"/>
        </DockPanel>
    </Grid>
</Window>

Before continuing initializing the WebView2 control, you'll have to setup your web-app project. You're free to use what-ever technology you want as long as it produces static files when built. In this example we will use the popular tool "Vite" which supports React, Vue, Svelte, vanilla JS and others.

Create a directory called "wwwroot" at the root of your project. This is where your web-app will be built to.

cd wwwroot
npm create vite@latest . # Follow the prompts
npm install
npm install @ultrawelfare/phosphorus.net-ipc

Depending on your framework of choice you'll have to import the @ultrawelfare/phosphorus.net-ipc package in the entry-point of your app. For example on react apps there is a main.jsx or main.tsx file which would be the entry-point.

import "@ultrawelfare/phosphorus.net-ipc";

Back to the C# project, depending on your C# project type (WinForms / WPF) you'll have to initialize the WebView2 control. Here's an example for WPF:

public MainWindow()
{
    InitializeComponent();
    OnLoad();
}
    
private async void OnLoad()
{
    webView.CoreWebView2InitializationCompleted += (_, _) =>
    {
        #if RELEASE
        webView.CoreWebView2.SetVirtualHostNameToFolderMapping("app", "wwwroot",
            CoreWebView2HostResourceAccessKind.Allow);
        webView.CoreWebView2.Navigate("https://app/index.html");
        #else
        webView.CoreWebView2.Navigate("http://localhost:5173");
        #endif
    };
    
    await webView.EnsureCoreWebView2Async();
}

The code above depending on the build configuration will either load the static files from the wwwroot directory or from a local development server. The development server is started by Vite when you run npm run dev. Feel free to modify the code inside CoreWebView2InitializationCompleted to suit your needs.

One small thing before we continue is that the wwwroot directory in the code above is referred executable directory... Which means once your app is built in bin/Debug/.../WpfApp.exe or bin/Release/.../WpfApp.exe the wwwroot directory will not be there.

To fix this, we will have to copy the built web-app files from the wwwroot directory to the output directory of the C# project. Once you run npm run build inside your wwwroot folder, it will place the built files in the wwwroot/dist directory. To automate the process you can add the following to your .csproj file:

    <ItemGroup>
        <WwwrootFiles Include="wwwroot\dist\**\*.*" />
    </ItemGroup>

    <Target Name="CopyFiles" AfterTargets="Build">
        <Copy SourceFiles="@(WwwrootFiles)" DestinationFolder="$(OutDir)\wwwroot\%(RecursiveDir)" />
    </Target>

    <Target Name="CopyFiles" AfterTargets="Publish">
        <Copy SourceFiles="@(WwwrootFiles)" DestinationFolder="$(PublishDir)\wwwroot\%(RecursiveDir)" />
    </Target>

Now you can build your project and the web-app files will be copied to the output directory.

Moving on, we will have to create a class that extends IpcContainer and register the C# objects that we want to expose. For example:

// Calculator.cs
[IpcExpose]
class Calculator
{
    public int Multiply(int a, int b)
    {
        return a * b;
    }
    
    public async Task<int> MultiplyAsync(int a, int b)
    {
        await Task.Delay(2000);
        return a * b;
    }
}
// Container.cs
class Container : IpcContainer
{
    private Calculator _calculator = new();
    public Container()
    {
        Register("calculator", _calculator);
    }
}

Note: The [IpcExpose] attribute can either be added to a class to mark all methods as exposed or to individual methods.

Finally to register the container with the WebView2 control, you can use the RegisterIpcHandler extension method. On the OnLoad method we created before, add the following code after the EnsureCoreWebView2Async call:

await webView.EnsureCoreWebView2Async();
var container = new Container();
webView.RegisterIpcHandler(container);

Your app is now ready to communicate between C# and JS. You can now call the exposed methods from JS like this:

// General syntax:
ipc.{instanceName}.{methodName}({args});
// or for a better example using the calculator:
const result = await ipc.calculator.Multiply(2, 5);
console.log(result); // 10