Skip to content

Use WebView2 In Console Application

What is WebView2

Check out the introduction of WebView2

Supported Programming Environments

According to the introduction, WebView2 is supported in the following programming environments:

  • Win32 C/C++
  • .NET Framework 4.5 or later
  • .NET Core 3.1 or later
  • .NET 5
  • .NET 6
  • WinUI 2.0
  • WinUI 3.0

Application in Console Application

WebView2 can be applied in WinForm, WPF, MAUI, etc., which have a UI.

Referring to this issue. I found a way to approach it using message-only window.

There is an article discussing the message-only window approach.

The strategy involves having a UI thread to trigger the WebView2 controller.

Code snippets

.csproj

xml
<Project Sdk="Microsoft.NET.Sdk">

 <PropertyGroup Label="Globals">
  <WebView2UseWinRT>False</WebView2UseWinRT>
 </PropertyGroup>

 <PropertyGroup>
  <OutputType>Exe</OutputType>
  <TargetFramework>net8.0-windows</TargetFramework>
  <UseWPF>true</UseWPF>
  <ImplicitUsings>enable</ImplicitUsings>
  <Nullable>enable</Nullable>
  <InvariantGlobalization>true</InvariantGlobalization>
  <SupportedOSPlatformVersion>7.0</SupportedOSPlatformVersion>
 </PropertyGroup>

 <ItemGroup>
  <PackageReference Include="Microsoft.Web.WebView2" Version="1.0.2210.55" />
  <PackageReference Include="WebView2.Runtime.X64" Version="120.0.2210.91" />
 </ItemGroup>

</Project>

program.cs

csharp
using Microsoft.Web.WebView2.Core;
using System.IO;
using System.Windows.Threading;

namespace Demo;

internal class Program
{
    static readonly IntPtr HWND_MESSAGE = new IntPtr(-3);

    static void Main(string[] args)
    {
        var htmlContent = @"
<!doctype html>
<html>
  <head>
    <title>This is the title!</title>
  </head>
  <body>
    <p>Hello World</p>
  </body>
</html>
";
        // create a new thread
        var uiThread = new Thread((htmlContent) =>
        {
            Dispatcher.CurrentDispatcher.Invoke(async (string htmlContent) =>
            {
                // setup webview runtime
                var runtimePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "WebView2");
                var environment = await CoreWebView2Environment.CreateAsync(runtimePath, null, null);

                // create controller
                var browserController = await environment.CreateCoreWebView2ControllerAsync(HWND_MESSAGE);

                // create view
                var view = browserController.CoreWebView2;

                // load html content, could also use other methods to fetch request
                // html content is limited to 2 MB
                view.NavigateToString(htmlContent);

                // get html content body
                var response = await view.ExecuteScriptAsync("document.body.outerHTML");

                // print html content to pdf files, the file path should be full path, cannot use relative path
                await view.PrintToPdfAsync(@"D:\UseWebView2InConsoleApp\Demo\bin\Debug\net8.0-windows\hello.pdf");

                Console.WriteLine("Success!");
            }, 
            new object[] { htmlContent! });

            Dispatcher.Run();
        });

        uiThread.SetApartmentState(ApartmentState.STA); 
        uiThread.Start(htmlContent);
        uiThread.Join();
    }
}

Limitation

  1. WebView2 needs a UI thread to run. It seems it cannot use a Task to run the WebView2.

  2. The Dispatcher is only available on Windows, making the method unavailable on Linux.

other approaches

A popular library in JavaScript is Puppeteer. In C#, an alternative is Puppeteer Sharp.

本站总访问量