今回は、Windows Forms(WinForms)で「WebハイブリッドWindowsアプリ」を作成する方法を紹介します。
WPF、MAUIなどでも基本的には同じような仕組みが使えるため、そちらでも役立つ内容かと思います。
具体的には、以下の内容を学びます。
- WinFormsにおけるWeb連携の選択肢「WebView2」と「BlazorHybrid」の紹介
 - Web技術をWinFormsに組み込む利点
 - それぞれの技術の概要とユースケース
 
以下のような方に役立つ内容となっています。
- Windowsアプリ開発でWeb技術を活用したい
 - 既存のWebアプリ資産を活かしてWindowsアプリを開発したい
 - BlazorのRazorコンポーネントを活用してWindowsアプリ開発をしたい
 
Webハイブリッドの活用方法を知っておくと、Windowsアプリ開発における選択肢の幅が広がると思います!
今回はHelloWorld的な簡単なWebハイブリッドWindowsアプリを演習で作り、雰囲気をつかみましょう。
演習のコード一式はGitHubにあります。
以下に動画もあります。
講義:WinFormsでWeb技術を使う2つの方法
なぜWeb技術を使うのか?
WinFormsは古くからある安定した技術ですが、最新のWeb技術と連携させることで、以下の利点があります。
- モダンなUIの実現(HTML/CSSで柔軟にデザインできる)
 - 豊富なWebコンテンツの利用(地図、Webサービス、グラフ等)
 - 既存のWeb資産を再利用可能(WebサイトやアプリをWinFormsに埋め込める)
 
これにより、既存の資産を活かしつつ、ユーザ体験を向上できます。
WinFormsでWebと連携する方法として、主に以下の2つの技術があります。
- (1)WebView2
 - (2)Blazorハイブリッド
 
それぞれの特徴やメリットをみていきましょう。
(1)WebView2
WebView2を使うと、WinFormsなどのWindowsアプリへEdge(Chromiumベース)を組み込み、最新のWeb技術を利用できます。
以下のメリットがあります。
- HTML/CSS/JavaScriptをフル活用可能
 
次のようなユースケースが考えられます。
- Webページ表示、HTMLベースのレポート表示
 - 地図や動画コンテンツの組み込み
 - 既存のWebアプリ資産の再利用
 - WebシステムのWindowsデスクトップ対応
 
以下のように、いくつかの方法でWebアプリをWinForms内のWebView2コントロールで表示させ、さらに双方向で通信を行うことも可能です。

(2)Blazorハイブリッド
Blazorハイブリッドは、.NETの技術でHTML/CSSに加えてC#を用いてWindowsアプリ開発が可能な仕組みです。
BlazorのWebアプリ開発経験があるならば、「BlazorのRazorコンポーネントの仕組みがそのまま使える」というとわかりやすいかもですね。
Blazorハイブリッドを理解するための基本知識:
Blazorとは、C#とHTMLを組み合わせてWebアプリを作るためのフレームワークです。
Razorコンポーネント(.razor)は、HTMLのようなマークアップとC#コード(@codeブロック内)を1つのファイルに記述できる仕組みです。
HTMLタグ内で@で始まる式を使ってC#の変数を表示したり、@onclickなどのイベントハンドラでC#のメソッドを呼び出したりできます。
C# Blazorについては以下の記事やWebアプリ開発入門編を参考にしてください。
例えば、以下のようなRazorコンポーネントを記述すると、それをそのままWinFormsアプリで使うことができます。
<h1>Counter</h1>
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
    private int currentCount = 0;
    private void IncrementCount()
    {
        currentCount++;
    }
}次のように表示されます。

Blazorで使っているRazorコンポーネントがWinFormsアプリで表示されてる!
以下のメリットがあります。
- UIもビジネスロジックもC#で記述可能
(これはBlazor自体のメリット) - コードの再利用性が高く、Web版とWindows版を簡単に作成可能
 
次のユースケースが考えられます。
- 既存Blazor Webアプリのデスクトップ版展開
 - Blazorでコードを共通化しつつWeb版とWindows版のアプリを開発
 
Blazorハイブリッドは、基本的に既にBlazorへ投資してきた方や、これから本格的にBlazor技術を採用していこうと考えている方向けの選択肢です。
C# Blazorが得意・好きという方がWindowsアプリ開発を行う場合、有力な選択肢の1つでしょう。
WebView2・Blazorハイブリッドの比較
WebView2・Blazorハイブリッドを比較して整理すると以下になります。
| 項目 | WebView2 | Blazorハイブリッド | 
|---|---|---|
| 基本概念 | Webブラウザ(Edge)をアプリに埋め込む技術 | C#でWeb技術とデスクトップアプリを統合する技術 | 
| 開発言語 | HTML/CSS/JavaScript | C#(Razorコンポーネント使用) | 
| 向いている用途 | • 既存のWebサイトをアプリ化したい • Web開発者がデスクトップアプリを作りたい  | • C#開発者がWebとデスクトップを組み合わせたい • .NET技術を活用したい  | 
| UIの作り方 | HTML/CSSで自由に設計可能 | Razorコンポーネントを使って簡単に構築 | 
| 強み | • Web技術の自由度が高い • 既存のWebサイトを簡単に流用できる  | • C#一つで全て開発できる • .NETの資産を活用できる  | 
| 開発速度 | Webの知識・資産がある場合に速い | C#/.NETの経験がある場合に速い | 
| 学習難易度 | Web開発の知識があれば低い | C#と.NETの基礎知識が必要 | 
WindowsアプリxWeb技術のハイブリッドはWinForms以外(WPF、MAUIなど)でも可能です。
WinForms以外のWindowsアプリ開発フレームワークにも興味がある方は以下も参考にしてください。
演習1:WebView2を使ったHelloWorldアプリ
WebView2を使い、WinFormsへHTMLファイルを表示する超簡単なHelloWorldアプリを作ってみましょう。
実装
まず、WinFormsWebView2Appなどという名前で、新規のWinFormsプロジェクトを作成(今回.NET9を選定)します。
次にNuGetで「Microsoft.Web.WebView2」をインストールしましょう。

ツールボックスでWebView2コントロールが選択可能になっているので、選択してフォームへ配置しましょう。

WebView2コントロールのプロパティでDockをFillにし、全画面表示にします。

Form1.csのコードに以下のように少し追記します。Google検索のページが表示されるようにします。
namespace WinFormsWebView2App
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            webView21.Source = new Uri("https://www.google.com"); //★追加
        }
    }
}
アプリを実行
アプリを実行すると、以下のようにGoogle検索の画面が表示されます。

こんなに簡単にWebアプリが表示できるんだ!
Webコンテンツを表示するだけなら本当に簡単ですね。WebView2はブラウザをそのまま部品として使える強力なコントロールです。
.NET 9環境でWebView2を使用すると、WindowsBaseライブラリの異なるバージョン間で依存関係の競合が発生することがあります。
簡単な解決策として、WebView2をバージョン1.0.2792.45にダウングレードするか、プロジェクトファイルに特定の参照を追加することで警告を解消できます。
GitHubにおける問題報告と議論も参考にしてください。
WebシステムをWindowsデスクトップアプリ(タスクトレイ常駐アプリ)と連携させ双方向通信している具体例を以下で紹介しているので、こちらも参考にしてください。
演習2:BlazorハイブリッドのHelloWorldアプリ
Blazorハイブリッドを使い、WinFormsでRazorコンポーネントを使ってみましょう。
Microsoftの「WindowsフォームのBlazorアプリを構築する」というチュートリアルがとても参考になります。これに沿って作ってみましょう。
実装
手順1:プロジェクト作成とパッケージインストール
WinFormsの新規プロジェクトを「WinFormsBlazorApp」といった名前で作成します。 (こちらも.NET9を使います)
「Microsoft.AspNetCore.Components.WebView.WindowsForms」をパッケージマネージャでインストールしましょう。
プロジェクトファイルの先頭を以下のように修正します。ソリューションエクスプローラで、プロジェクトを右クリックし「プロジェクト ファイルの編集」で行います。
<Project Sdk="Microsoft.NET.Sdk"> ←これを、
<Project Sdk="Microsoft.NET.Sdk.Razor"> ←このように修正ここからは、Blazorアプリ開発で使っているコードをプロジェクトへ配置していくイメージになります。
手順2:_Importsファイルやindex.htmlを配置
プロジェクトのルートに以下のような「_Imports.razor」を追加します。
@using Microsoft.AspNetCore.Components.Web次に、プロジェクトのルートにwwwrootフォルダを追加し、wwwroot配下で以下のようなindex.htmlを追加します。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>WinFormsBlazor</title>
    <base href="/" />
    <link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
    <link href="css/app.css" rel="stylesheet" />
    <link href="WinFormsBlazor.styles.css" rel="stylesheet" />
</head>
<body>
    <div id="app">Loading...</div>
    <div id="blazor-error-ui" data-nosnippet>
        An unhandled error has occurred.
        <a href="" class="reload">Reload</a>
        <a class="dismiss">🗙</a>
    </div>
    <script src="_framework/blazor.webview.js"></script>
</body>
</html>さらに、wwwroot配下にcssフォルダを作成し、以下のようなapp.cssを配置しましょう。
html, body {
    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}
h1:focus {
    outline: none;
}
a, .btn-link {
    color: #0071c1;
}
.btn-primary {
    color: #fff;
    background-color: #1b6ec2;
    border-color: #1861ac;
}
.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}
.invalid {
    outline: 1px solid red;
}
.validation-message {
    color: red;
}
#blazor-error-ui {
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}
    #blazor-error-ui .dismiss {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
    }ここまででwwwrootは次のような構成になっています。

手順3:Bootstrapを配置
wwwroot/css配下にbootstrapフォルダを作成し、そこへbootstrap.min.css、bootstrap.min.css.mapのコピーを配置します。
bootstrap.min.cssはBootstrapの公式サイトからダウンロードします。
ダウンロードした「bootstrap-5.3.0-dist.zip」のcssフォルダ内に上述した2つのファイルがあるので、それを配置しましょう!
ここまででwwwroot配下は以下の構成になっているはずです。

手順4:Razorコンポーネントを配置
Razorコンポーネントを配置します。Blazorアプリではお馴染みのカウンターをつくります。以下の「Counter.razor」をプロジェクトフォルダ直下に配置します。
<h1>Counter</h1>
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
    private int currentCount = 0;
    private void IncrementCount()
    {
        currentCount++;
    }
}手順5:フォームにBlazorWebViewコントロールを配置
フォームにBlazorWebViewコントロールを配置します。DockプロパティをFillにして全画面にしましょう。

間違って演習1で使ったWebView2コントロールを選択しないよう注意してください!
最後に、Form1.csのコンストラクタで、InitializeComponent();の後ろに以下のように追記しましょう。
...
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        var services = new ServiceCollection();
        services.AddWindowsFormsBlazorWebView();
        blazorWebView1.HostPage = "wwwroot\\index.html";
        blazorWebView1.Services = services.BuildServiceProvider();
        blazorWebView1.RootComponents.Add<Counter>("#app");
    }
...これで完成です。プロジェクトは最終的に以下のような構成になります。

アプリを実行
アプリを実行すると以下のように表示されます。

Serverモードでも、WASMモードでもない動作となります。
Windowsアプリとして動作しているので、Windowsローカルリソースへも直接アクセスできますよ!
まとめ
Windows Forms アプリ開発において、Web技術を活用する「Web ハイブリッド」という選択肢があることを紹介しました。
WebView2とBlazorハイブリッドという 2 つの技術があり、それぞれの特徴と利点を見てきました。
- 「WebView2」は Edge (Chromium) ブラウザをアプリに埋め込む技術で、HTML/CSS/JavaScript をフル活用可能。
 
- 既存の Web コンテンツやサイトを Windows アプリに簡単に統合できる点が大きな利点。Web 開発の知識がある方にとって、実装のハードルも低い。
 
- 「Blazorハイブリッド」は C# 開発者に向いており、Razor コンポーネントを使って UI とロジックをC#で統一的に記述。
 
- 特に既存のBlazorアプリの資産がある場合や、Web版とWindows 版を同時に開発したい場合に威力を発揮します。
 
両方のアプローチはWinFormsだけでなく、WPFやMAUIなどの他のWindowsアプリ開発フレームワークでも応用できます。
Web技術とWindows アプリを融合させることで、モダンなUIの実現、既存Web資産の再利用、豊富なWebコンテンツの活用といった多くのメリットが得られます。
今回、演習で簡単にHelloWorld的なアプリをそれぞれ作りましたが、今後もう少し実践的なアプリ開発方法も紹介していければと思います。
引き続き、一緒にC# WinFormsアプリ開発(+Webハイブリッド)を学んでいきましょう!
											

						
						
						
												
						
						
						
												
						
						
						
												
										
					
									
