C#でトースト通知を実装する方法|Windows対応のサンプルコードと表示されない時の対処法

はじめに

C#でWindows向けアプリを作っていると、「処理が完了した」「エラーが発生した」「リマインダーを表示したい」といった場面で、画面右下に通知を出したくなることがあります。このような通知は一般的に「トースト通知」と呼ばれ、Windows 10やWindows 11では通知センターにも残せるため、業務アプリ、常駐アプリ、監視ツール、ダウンロードツールなどでよく使われます。

現在のMicrosoft公式ドキュメントでは、「トースト通知」という呼び方は徐々に「アプリ通知」という名称へ置き換えられています。ただし、C#開発者の間では今でも「toast」「トースト通知」という呼び方が広く使われているため、本記事では検索されやすい表現に合わせて「C#のトースト通知」として解説します。Windowsのアプリ通知は、アプリのウィンドウ外に表示されるUIポップアップで、クリック時にアプリを起動したり、バックグラウンド処理を実行したりできます。Microsoft Learn

この記事では、C#でトースト通知を実装するための基礎、WPF・WinForms・コンソールアプリでの考え方、サンプルコード、表示されない時の原因と対処法までまとめて解説します。

1. C#でトースト通知を実装する前に知っておくべき基礎

1-1. トースト通知とは?Windowsで表示される通知の仕組み

トースト通知とは、Windowsの画面右下、または通知センターに表示される短いメッセージ通知です。メールの受信通知、チャット通知、処理完了通知、更新通知などでよく見かけるものです。

C#アプリから表示する場合、通知の内容は主に次のような要素で構成されます。

通知タイトル、本文、アイコン、画像、通知音、ボタン、入力欄、クリック時の引数、進捗バー、通知の有効期限などです。

Windowsのトースト通知は、単にメッセージを表示するだけではありません。通知をクリックした時にアプリを前面に出したり、ボタンを押した時に特定の処理を実行したり、通知センターに履歴を残したりできます。Microsoftのドキュメントでも、通知は情報提供だけでなく、クリック時のアプリ起動やバックグラウンドアクションに使えるものとして説明されています。Microsoft Learn

1-2. C#でトースト通知を使う主な利用シーン

C#でトースト通知を使う代表的なシーンは、次のようなものです。

ファイルのダウンロードやアップロードが完了した時、バッチ処理や集計処理が終わった時、バックグラウンド監視で異常を検知した時、スケジュールや期限を知らせたい時、チャットやメッセージを受信した時、ユーザー操作の結果を軽く知らせたい時などです。

たとえば、WPFで作った業務アプリなら「CSV出力が完了しました」、WinFormsの管理ツールなら「バックアップが終了しました」、コンソールアプリなら「定期処理でエラーが発生しました」といった通知に使えます。

ただし、トースト通知はユーザーの作業中に割り込むUIです。便利だからといって何度も表示すると、ユーザー体験を悪化させます。重要度が低い情報はアプリ内のステータス表示にし、本当に気づいてほしい情報だけを通知にするのが基本です。

1-3. Windows 10・Windows 11での対応状況

C#のトースト通知は、Windows 10およびWindows 11向けのデスクトップアプリで利用できます。Microsoftのアプリ通知ドキュメントでは、WPF、WinForms、コンソールアプリ、UWPアプリなど、複数のフレームワークでアプリ通知を扱うための案内が用意されています。Microsoft Learn

Windows 11でも基本的な考え方は同じですが、通知の表示デザインや通知センターの見え方はWindows 10と少し異なります。また、ユーザーがWindowsの通知設定をオフにしている場合や、応答不可モードを有効にしている場合は、コードが正しくてもポップアップとして表示されないことがあります。

Windows 7では現在のWindows 10/11形式のトースト通知は利用できません。古い環境では、タスクトレイのバルーン通知や独自のポップアップウィンドウで代替する必要があります。

1-4. WinForms・WPF・コンソールアプリ・UWPでの違い

C#でトースト通知を実装する場合、アプリの種類によって設定方法や注意点が変わります。

WPFアプリでは、ボタンクリックやバックグラウンド処理の完了時に通知を表示できます。MVVM構成の場合は、通知処理をサービスクラスに分離すると保守しやすくなります。

WinFormsアプリでは、フォームのイベントやボタン操作から通知を表示できます。従来のNotifyIconによるバルーン通知と似ていますが、トースト通知はWindowsの通知センターと連携でき、ボタンや入力欄などのリッチなUIも扱えます。

コンソールアプリでもトースト通知は表示できます。ただし、クリック時の処理や通知履歴を本格的に扱う場合は、アプリIDや起動引数、実行形態に注意が必要です。

UWPやWinUI 3、Windows App SDKを使ったアプリでは、通知の登録やアクティブ化処理がフレームワークに沿って整理されています。Windows App SDKではMicrosoft.Windows.AppNotificationsMicrosoft.Windows.AppNotifications.Builder名前空間のAPIを使って通知を構築できます。Microsoft Learn

2. C#でトースト通知を実装するための準備

2-1. 必要な開発環境

C#でWindowsのトースト通知を実装する場合、基本的には次の環境を用意します。

Visual Studio 2022、.NET 6以降または.NET 8以降、Windows 10またはWindows 11、C#のWPF・WinForms・コンソールアプリ用プロジェクト、必要に応じてWindows App SDKまたはWindows Community Toolkitを使用します。

Windows App SDKの公式クイックスタートでは、Visual Studio 2022 v17.6以降やC#向けの.NETワークロード、MSIX Packaging Toolsなどが前提として案内されています。Microsoft Learn

既存のWPFやWinFormsアプリに軽く組み込むなら、CommunityToolkit.WinUI.Notificationsを使う方法が実装しやすいです。一方、WinUI 3やWindows App SDKベースのアプリでは、AppNotificationBuilderを使う方法が現在の標準的な選択肢になります。

2-2. Visual Studioでプロジェクトを作成する手順

WPFアプリで試す場合は、Visual Studioで「WPF アプリ」を選択し、ターゲットフレームワークを.NET 8などにします。WinFormsで試す場合は「Windows フォーム アプリ」を選択します。コンソールアプリで試す場合も、Windows専用APIを扱うため、プロジェクトファイルでWindows向けのターゲットフレームワークを指定するのが安全です。

たとえばWPFアプリの場合、.csprojは次のような構成になります。

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

<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
<UseWPF>true</UseWPF>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>

WinFormsの場合は、UseWindowsFormsを有効にします。

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

<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>

コンソールアプリの場合も、Windows通知APIを使うなら次のようにWindows向けターゲットにしておくとよいです。

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

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>

2-3. 必要なNuGetパッケージ

WPF、WinForms、コンソールアプリで手軽にトースト通知を表示したい場合は、次のNuGetパッケージを追加します。

PowerShell
Install-Package CommunityToolkit.WinUI.Notifications

または、.NET CLIを使う場合は次のコマンドです。

Bash
dotnet add package CommunityToolkit.WinUI.Notifications

CommunityToolkit.WinUI.Notificationsには、ToastContentBuilderToastNotificationManagerCompatなど、C#からトースト通知を扱いやすくするクラスが含まれています。Microsoft LearnのAPIリファレンスでも、ToastNotificationManagerCompatはWin32の非MSIXアプリを含む各種アプリでトースト通知の送信と管理に使えるクラスとして説明されています。Microsoft Learn

古い記事ではMicrosoft.Toolkit.Uwp.Notificationsが紹介されていることがあります。既存プロジェクトではそのまま動いているケースもありますが、新規開発ではCommunityToolkit.WinUI.Notificationsを優先して検討するとよいでしょう。

2-4. アプリIDとショートカット登録が必要になる理由

C#のトースト通知でつまずきやすいポイントが、アプリID、正式にはAppUserModelIDです。Windowsは、通知を「どのアプリからの通知か」として管理します。そのため、デスクトップアプリから通知を出す場合、アプリを識別するIDやショートカット、パッケージ情報が正しく登録されていないと、通知が表示されなかったり、クリックイベントが動作しなかったりします。

特にWindows.UI.Notifications.ToastNotificationManager.CreateToastNotifier()を直接使う古い実装では、デスクトップアプリにはAppUserModelID付きのスタートメニューショートカットが必要になります。MicrosoftのAPIリファレンスでも、デスクトップアプリでトーストを表示するにはスタート画面のショートカットとAppUserModelIDが必要であると説明されています。Microsoft Learn

一方、現在のToastNotificationManagerCompatでは、古いDesktopNotificationManagerCompatよりも扱いやすくなっています。Microsoft Learnでは、古いDesktopNotificationManagerCompatについて、新しいToastNotificationManagerCompatへの移行が推奨されており、Win32アプリではスタートメニューショートカット不要で、イベントハンドラーによるシンプルなアクティブ化処理が使えると説明されています。Microsoft Learn

つまり、実装方法によって必要な登録作業が変わります。簡単な通知表示だけならToolkitで実装し、本格的にクリック起動や配布まで考えるなら、アプリID、MSIX、ショートカット、起動引数、通知履歴の扱いまで設計する必要があります。

2-5. トースト通知を表示するための権限と前提条件

トースト通知を表示するには、Windows側で通知が許可されている必要があります。次の条件を確認してください。

Windowsの「設定」から通知が有効になっていること、対象アプリの通知がオフになっていないこと、集中モードまたは応答不可モードで抑制されていないこと、アプリが通知を表示できるユーザーセッションで実行されていること、管理者権限で実行していないことです。

Windows App SDKのアプリ通知では、管理者特権で実行されているアプリは通知を送受信できないという制限があります。公式クイックスタートでも、アプリを昇格実行している場合はShowがサイレントに失敗し、通知が表示されないと説明されています。Microsoft Learn

3. C#でシンプルなトースト通知を表示するサンプルコード

3-1. 最小構成でトースト通知を表示するコード

まずは、C#で最小構成のトースト通知を表示するサンプルです。CommunityToolkit.WinUI.Notificationsをインストールしたうえで、次のコードを実行します。

C#
using CommunityToolkit.WinUI.Notifications;

new ToastContentBuilder()
.AddText("処理が完了しました")
.AddText("C#からトースト通知を表示しました。")
.Show();

コンソールアプリで試す場合は、Program.csを次のようにします。

C#
using CommunityToolkit.WinUI.Notifications;

Console.WriteLine("トースト通知を表示します。");

new ToastContentBuilder()
.AddText("通知テスト")
.AddText("C#のコンソールアプリから表示しています。")
.Show();

Console.WriteLine("通知を送信しました。");
Console.ReadLine();

ToastContentBuilder.Show()は、現在の内容で新しいトースト通知を表示するためのメソッドです。Microsoft Learnのリファレンスでも、Show()は現在のコンテンツを使って新しいトースト通知を表示するメソッドとして定義されています。Microsoft Learn

3-2. 通知タイトルと本文を設定する方法

AddTextを複数回呼び出すと、1行目がタイトルのように強調表示され、2行目以降が本文として表示されます。

C#
using CommunityToolkit.WinUI.Notifications;

new ToastContentBuilder()
.AddText("バックアップ完了")
.AddText("データベースのバックアップが正常に終了しました。")
.Show();

業務アプリでは、1行目に結論、2行目に補足を書くと分かりやすくなります。

C#
new ToastContentBuilder()
.AddText("帳票出力が完了しました")
.AddText("出力先: C:\\Reports\\sales_2026.xlsx")
.Show();

Windowsのアプリ通知では、少なくとも1つのテキスト要素が必要で、追加のテキスト要素も利用できます。公式ドキュメントでは、アプリ通知のテキスト要素や進捗バーなどの構成要素が説明されています。Microsoft Learn

3-3. 通知にアイコンや画像を表示する方法

トースト通知には、ロゴ画像や本文中の画像を表示できます。ローカル画像を使う場合は、アプリからアクセスできる絶対パスを指定します。

C#
using CommunityToolkit.WinUI.Notifications;

var imagePath = Path.GetFullPath("Assets\\logo.png");

new ToastContentBuilder()
.AddText("画像付き通知")
.AddText("アプリのロゴ画像を表示しています。")
.AddAppLogoOverride(new Uri(imagePath), ToastGenericAppLogoCrop.Circle)
.Show();

ヒーロー画像のように大きめの画像を表示したい場合は、次のようにします。

C#
using CommunityToolkit.WinUI.Notifications;

var heroImagePath = Path.GetFullPath("Assets\\completed.png");

new ToastContentBuilder()
.AddText("レポート作成完了")
.AddText("月次レポートの作成が完了しました。")
.AddHeroImage(new Uri(heroImagePath))
.Show();

画像が表示されない場合は、パスが正しいか、実行ファイルの配置先から画像にアクセスできるか、画像ファイルがビルド時にコピーされているかを確認してください。

3-4. 通知音を設定する方法

通知音を明示的に設定したい場合は、AddAudioを使います。

C#
using CommunityToolkit.WinUI.Notifications;

new ToastContentBuilder()
.AddText("通知音テスト")
.AddText("指定した通知音を再生します。")
.AddAudio(new Uri("ms-winsoundevent:Notification.Default"))
.Show();

通知音を鳴らしたくない場合は、サイレント通知にします。

C#
using CommunityToolkit.WinUI.Notifications;

new ToastContentBuilder()
.AddText("サイレント通知")
.AddText("通知音なしで表示します。")
.AddAudio(new ToastAudio
{
Silent = true
})
.Show();

通知音はユーザー体験に大きく影響します。エラーや緊急性の高い通知以外では、音を鳴らさない設計も検討しましょう。

3-5. 実行結果の確認方法

サンプルコードを実行すると、Windowsの画面右下付近にトースト通知が表示されます。数秒後に消えた場合でも、通知センターを開くと履歴として残っていることがあります。

確認するポイントは、画面右下にポップアップが表示されたか、通知センターに残っているか、通知元のアプリ名が想定どおりか、アイコンや画像が表示されているか、クリック時の動作が必要な場合はイベントが発火しているかです。

表示されない場合は、コードより先にWindowsの通知設定を確認してください。特に、初回テストでは「通知は送信されているが、Windows側で表示が抑制されている」というケースがよくあります。

4. WPFアプリでトースト通知を実装する方法

4-1. WPFでトースト通知を使う基本手順

WPFアプリでC#のトースト通知を使う基本手順は次のとおりです。

WPFプロジェクトを作成し、CommunityToolkit.WinUI.Notificationsを追加し、通知表示用のサービスクラスを作成し、ボタンクリックや処理完了時にサービスから通知を表示します。

小規模なアプリならコードビハインドに直接書いても動きますが、実務では通知処理をサービス化するのがおすすめです。画面側のロジックと通知処理を分離でき、後から通知内容やログ出力を変更しやすくなります。

4-2. ボタンクリックで通知を表示するサンプルコード

まず、MainWindow.xamlにボタンを配置します。

XML
<Window x:Class="ToastSample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Toast Sample" Height="200" Width="400">
<Grid>
<Button Content="通知を表示"
Width="160"
Height="40"
Click="Button_Click" />
</Grid>
</Window>

次に、MainWindow.xaml.csでボタンクリック時に通知を表示します。

C#
using System.Windows;
using CommunityToolkit.WinUI.Notifications;

namespace ToastSample;

public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}

private void Button_Click(object sender, RoutedEventArgs e)
{
new ToastContentBuilder()
.AddText("WPF通知")
.AddText("ボタンクリックでトースト通知を表示しました。")
.Show();
}
}

このコードを実行し、ボタンをクリックするとWindowsのトースト通知が表示されます。

4-3. MVVM構成で通知処理を分離する方法

MVVMで実装する場合は、通知処理をインターフェイス化します。

C#
public interface IToastNotificationService
{
void ShowInfo(string title, string message);
void ShowError(string title, string message);
}

実装クラスを作成します。

C#
using CommunityToolkit.WinUI.Notifications;

public class ToastNotificationService : IToastNotificationService
{
public void ShowInfo(string title, string message)
{
new ToastContentBuilder()
.AddText(title)
.AddText(message)
.Show();
}

public void ShowError(string title, string message)
{
new ToastContentBuilder()
.AddText(title)
.AddText(message)
.AddAudio(new Uri("ms-winsoundevent:Notification.IM"))
.Show();
}
}

ViewModelから使う例です。

C#
public class MainViewModel
{
private readonly IToastNotificationService _toastService;

public MainViewModel(IToastNotificationService toastService)
{
_toastService = toastService;
}

public void Export()
{
try
{
// CSV出力などの処理
_toastService.ShowInfo("出力完了", "CSVファイルの出力が完了しました。");
}
catch (Exception ex)
{
_toastService.ShowError("出力エラー", ex.Message);
}
}
}

このように分離しておくと、単体テストではモックに差し替えられ、UI側に依存しない設計にできます。

4-4. WPFアプリで通知が表示されない時の注意点

WPFアプリで通知が表示されない場合は、次の点を確認します。

まず、NuGetパッケージが正しく追加されているか確認します。次に、ターゲットフレームワークがnet8.0-windowsのようにWindows向けになっているか確認します。さらに、Windowsの通知設定が有効か、アプリを管理者権限で実行していないか、集中モードや応答不可モードが有効になっていないかを確認してください。

また、Visual Studioからデバッグ実行している場合と、ビルド済みexeを直接起動した場合で通知元の表示や挙動が変わることがあります。配布時の実行パス、アプリ名、アイコン、ショートカット、インストーラーの有無も影響します。

5. WinFormsアプリでトースト通知を実装する方法

5-1. WinFormsでトースト通知を使う基本手順

WinFormsでも、基本的な手順はWPFとほぼ同じです。プロジェクトにCommunityToolkit.WinUI.Notificationsを追加し、フォームのイベントからToastContentBuilderを呼び出します。

WinFormsは既存の業務アプリで使われていることが多いため、既存画面にボタンや処理完了イベントを追加して通知を出すケースが多いでしょう。既存のMessageBox.Showをすべてトースト通知に置き換えるのではなく、ユーザーの操作を止める必要がない通知だけをトースト通知にするのがポイントです。

5-2. フォーム操作から通知を表示するサンプルコード

フォームにボタンを配置し、クリックイベントに次のコードを書きます。

C#
using CommunityToolkit.WinUI.Notifications;

namespace WinFormsToastSample;

public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void buttonNotify_Click(object sender, EventArgs e)
{
new ToastContentBuilder()
.AddText("WinForms通知")
.AddText("フォームのボタンからトースト通知を表示しました。")
.Show();
}
}

ファイル保存後に通知を出す場合は、次のように使えます。

C#
private void SaveFile()
{
// 保存処理
File.WriteAllText("result.txt", "保存内容");

new ToastContentBuilder()
.AddText("保存完了")
.AddText("ファイルを正常に保存しました。")
.Show();
}

5-3. NotifyIconとの違い

WinFormsには昔からNotifyIconがあります。NotifyIconはタスクトレイにアイコンを表示し、バルーン通知を出すための機能です。

一方、トースト通知はWindowsの通知センターと連携し、クリックイベント、ボタン、入力欄、画像、通知履歴などを扱いやすい点が特徴です。ユーザーに一時的な情報を知らせたいだけならNotifyIconでも足りますが、Windows 10/11らしい通知体験にしたい場合はトースト通知の方が適しています。

ただし、常駐アプリでタスクトレイアイコンを表示したい場合は、NotifyIconとトースト通知を組み合わせる構成も有効です。たとえば、常駐状態の表示にはNotifyIcon、重要な完了通知にはトースト通知を使います。

5-4. 既存のWinFormsアプリに組み込む時のポイント

既存のWinFormsアプリにC#のトースト通知を組み込む時は、次の点を意識します。

通知表示処理を共通クラスにまとめること、エラー通知と完了通知の文面を統一すること、連続処理で大量に通知を出さないこと、ログにも同じ内容を残すこと、ユーザー設定で通知のオン・オフを切り替えられるようにすることです。

特に業務アプリでは、通知が出たかどうかだけでなく「いつ、どの処理が、どのユーザー操作により完了したか」をログに残すと、問い合わせ対応がしやすくなります。

6. トースト通知をカスタマイズする方法

6-1. ボタン付きトースト通知を作成する方法

トースト通知にはボタンを追加できます。たとえば、「開く」「後で」「閉じる」のような操作を通知上に表示できます。

C#
using CommunityToolkit.WinUI.Notifications;

new ToastContentBuilder()
.AddArgument("action", "open")
.AddText("レポート作成完了")
.AddText("作成したレポートを開きますか?")
.AddButton(new ToastButton()
.SetContent("開く")
.AddArgument("action", "openReport")
.SetBackgroundActivation())
.AddButton(new ToastButtonDismiss("閉じる"))
.Show();

ボタンを付ける場合は、押されたボタンを識別できるようにAddArgumentでアクション名を渡しておくと便利です。Windowsの通知コンテンツスキーマでは、通知のコンテンツにビジュアル、アクション、音声などを含められると説明されています。Microsoft Learn

6-2. 入力欄付きトースト通知を作成する方法

通知上にテキスト入力欄を置くこともできます。チャット返信、簡単なコメント、承認理由などに利用できます。

C#
using CommunityToolkit.WinUI.Notifications;

new ToastContentBuilder()
.AddText("コメントを入力")
.AddText("処理を保留する理由を入力してください。")
.AddInputTextBox("reason", placeHolderContent: "理由を入力")
.AddButton(new ToastButton()
.SetContent("送信")
.AddArgument("action", "sendReason")
.SetTextBoxId("reason")
.SetBackgroundActivation())
.AddButton(new ToastButtonDismiss("キャンセル"))
.Show();

入力欄付き通知では、通知クリック時やボタンクリック時に受け取る引数の処理が重要です。表示するだけなら簡単ですが、入力値を取得して処理するにはアクティブ化イベントを実装する必要があります。

6-3. 通知クリック時の処理を実装する方法

通知クリック時の処理は、アプリ起動中か終了中かによって考慮点が変わります。まず、アプリ起動中に通知がクリックされた場合の基本形は次のようになります。

C#
using CommunityToolkit.WinUI.Notifications;

ToastNotificationManagerCompat.OnActivated += toastArgs =>
{
ToastArguments args = ToastArguments.Parse(toastArgs.Argument);

if (args.TryGetValue("action", out string? action))
{
// actionの値に応じて処理を分岐
Console.WriteLine($"通知がクリックされました: {action}");
}
};

new ToastContentBuilder()
.AddArgument("action", "openDetail")
.AddArgument("id", "123")
.AddText("詳細を確認してください")
.AddText("クリックすると詳細画面を開きます。")
.Show();

WPFで画面を操作する場合は、UIスレッドに戻す必要があります。

C#
ToastNotificationManagerCompat.OnActivated += toastArgs =>
{
Application.Current.Dispatcher.Invoke(() =>
{
ToastArguments args = ToastArguments.Parse(toastArgs.Argument);

if (args.TryGetValue("id", out string? id))
{
MessageBox.Show($"通知から開かれました。ID: {id}");
}
});
};

Windows App SDKでは、通知クリック時にAppNotificationManager.NotificationInvokedを登録し、アクティブ化引数を見て処理を分岐します。公式クイックスタートでは、通知をクリックした時にUIを表示するケースと、UIを表示せずバックグラウンドアクションを処理するケースが紹介されています。Microsoft Learn

6-4. 通知の有効期限を設定する方法

期限が過ぎた通知を残したくない場合は、通知の有効期限を設定します。たとえば、10分後には意味がなくなるリマインダーなら、ExpirationTimeを設定します。

C#
using CommunityToolkit.WinUI.Notifications;

new ToastContentBuilder()
.AddText("一時的な通知")
.AddText("この通知は10分後に期限切れになります。")
.Show(toast =>
{
toast.ExpirationTime = DateTimeOffset.Now.AddMinutes(10);
});

ToastNotificationにはExpirationTimeプロパティがあり、指定した日時以降は通知が現在有効なものとして扱われなくなります。Microsoft Learn

期限付き通知は、セール情報、期限付き承認、会議直前のリマインダーなどに向いています。逆に、完了通知やエラーログのように後から確認したいものは、通知センターに残す設計も検討しましょう。

6-5. 複数行テキストや進捗バーを表示する方法

複数行のテキストを表示したい場合は、AddTextを複数回使います。

C#
new ToastContentBuilder()
.AddText("データ同期中")
.AddText("顧客データをサーバーへ送信しています。")
.AddText("完了までしばらくお待ちください。")
.Show();

進捗バーは、ダウンロード、アップロード、動画変換、帳票生成など、時間のかかる処理の状態表示に向いています。Microsoftのドキュメントでも、アプリ通知の進捗バーはダウンロードなどの進行状況をユーザーに知らせるために利用できると説明されています。Microsoft Learn

XMLで表すと、進捗バーは次のような構造です。

XML
<toast>
<visual>
<binding template="ToastGeneric">
<text>ダウンロード中</text>
<text>ファイルを取得しています。</text>
<progress title="進捗"
value="0.6"
valueStringOverride="60%"
status="処理中" />
</binding>
</visual>
</toast>

進捗をリアルタイム更新したい場合は、タグやグループ、データバインディングを使って通知を更新する設計になります。単純な完了通知より実装が複雑になるため、まずは通常の通知で要件を満たせるか確認するとよいでしょう。

7. C#のトースト通知が表示されない時の原因と対処法

7-1. Windowsの通知設定がオフになっている

最も多い原因は、Windows側の通知設定です。コードが正しくても、OSの設定で通知が無効になっていると表示されません。

Windows 11の場合は、「設定」→「システム」→「通知」を開き、通知全体がオンになっているか、対象アプリの通知が許可されているかを確認します。Windows 10でも同様に、「設定」→「システム」→「通知とアクション」から確認できます。

アプリ名が一覧に出てこない場合は、一度アプリから通知を送信したうえで、再度設定画面を確認してください。

7-2. 集中モード・応答不可モードが有効になっている

Windowsには、通知を一時的に抑制する機能があります。Windows 10では集中モード、Windows 11では応答不可モードとして表示されることがあります。

このモードが有効な場合、通知は通知センターには残っても、画面右下にポップアップ表示されないことがあります。「通知は送信されたはずなのに画面に出ない」という場合は、この設定を確認してください。

7-3. アプリIDやショートカット登録が正しくない

古いWin32実装やToastNotificationManager.CreateToastNotifier(appID)を直接使う実装では、AppUserModelIDやスタートメニューショートカットが正しくないと通知が表示されません。Microsoftのリファレンスでも、デスクトップアプリではスタート画面のショートカットとAppUserModelIDが必要であると説明されています。Microsoft Learn

対処法としては、まずCommunityToolkit.WinUI.NotificationsToastNotificationManagerCompatを使う構成にできないか検討します。古いサンプルコードをそのまま使っている場合は、現在のToolkitのAPIへ置き換えることで解決する場合があります。

7-4. NuGetパッケージや参照設定が不足している

ToastContentBuilderが見つからない、CommunityToolkit名前空間が見つからない、Windows.UI.Notificationsが見つからないといったエラーは、パッケージやターゲットフレームワークの不足が原因です。

確認すべき点は、CommunityToolkit.WinUI.Notificationsがインストールされているか、using CommunityToolkit.WinUI.Notifications;を書いているか、.csprojがWindows向けターゲットになっているか、Visual Studioで復元が成功しているかです。

7-5. デバッグ実行では表示されないケース

Visual Studioからデバッグ実行している時だけ通知が表示されない、または通知元名が想定と違うことがあります。特に、アプリID、実行パス、ショートカット、パッケージ化の有無が絡む場合は、デバッグ実行と配布後の実行で挙動が異なることがあります。

対処法として、Releaseビルドしたexeを直接実行する、スタートメニューから起動する、インストーラー経由で配置して確認する、といった方法を試してください。

7-6. 管理者権限や実行環境による影響

管理者権限で起動したアプリでは、通知が表示されないことがあります。Windows App SDKのアプリ通知では、管理者特権で実行されているアプリは通知を送受信できないという制限があります。Microsoft Learn

また、Windowsサービス、タスクスケジューラ、リモートセッション、別ユーザーセッションで実行されるプロセスから通知を出す場合も注意が必要です。トースト通知は、基本的に対話中のユーザーに対して表示される機能です。サービスから直接表示するのではなく、ユーザーセッション側の常駐アプリに通知処理を委譲する構成が安全です。

7-7. Windowsの通知履歴に表示されない時の確認方法

通知が画面に出ず、通知センターにも残らない場合は、そもそもWindowsに通知が登録されていない可能性があります。次の順番で確認します。

まず、最小構成のAddTextだけの通知に戻します。次に、画像や音、ボタン、入力欄などのカスタマイズを外します。そのうえで、Windowsの通知設定、アプリの実行権限、NuGetパッケージ、ターゲットフレームワーク、AppUserModelIDを確認します。

通知センターにだけ残って画面に出ない場合は、ポップアップが抑制されている可能性があります。SuppressPopupを使っている場合は、値がtrueになっていないか確認してください。SuppressPopuptrueにすると、通知のポップアップ表示を抑制して通知センターに静かに入れる動作になります。Microsoft Learn

8. C#トースト通知の実装でよくあるエラー

8-1. ToastNotificationManagerでエラーが出る場合

ToastNotificationManagerを直接使っているコードでエラーが出る場合、デスクトップアプリ向けの前提条件を満たしていない可能性があります。特に、AppUserModelIDを指定せずにCreateToastNotifier()を使っている場合は注意が必要です。

Microsoftのリファレンスでは、デスクトップアプリで通知を作成する場合、引数なしのCreateToastNotifier()ではなく、必要なAppUserModelIDを指定する形を使うよう説明されています。Microsoft Learn

新規開発では、まずToastContentBuilderToastNotificationManagerCompatを使う方法を検討してください。古いサンプルをそのままコピーすると、現在の.NET環境では参照や登録処理でつまずくことがあります。

8-2. 名前空間が見つからない場合

次のようなエラーが出ることがあります。

The type or namespace name 'CommunityToolkit' could not be found

この場合は、NuGetパッケージが入っていないか、usingが不足しています。

C#
using CommunityToolkit.WinUI.Notifications;

パッケージを追加しても解決しない場合は、Visual Studioで「NuGetパッケージの復元」を実行し、プロジェクトをクリーンして再ビルドしてください。

8-3. 通知は送信されたのに画面に表示されない場合

通知送信のコードが実行されても画面に出ない場合は、次の原因が考えられます。

Windowsの通知設定がオフ、応答不可モードで抑制されている、アプリが管理者権限で実行されている、アプリIDが正しくない、画像パスなどが不正で通知生成に失敗している、デバッグ実行と配布実行でアプリの識別情報が変わっている、などです。

まずは画像、音、ボタンを外し、次の最小コードで表示できるか確認してください。

C#
new ToastContentBuilder()
.AddText("テスト")
.AddText("最小構成の通知です。")
.Show();

これで表示できるなら、カスタマイズ部分に原因があります。これでも表示できないなら、Windows設定、実行権限、アプリ登録を疑います。

8-4. クリックイベントが反応しない場合

通知は表示されるのにクリックイベントが反応しない場合は、イベント登録のタイミングが遅い可能性があります。アプリ起動直後、できるだけ早い段階でToastNotificationManagerCompat.OnActivatedを登録してください。

また、通知にAddArgumentで必要な引数を付けていないと、クリック時にどの通知が押されたのか判断できません。

C#
new ToastContentBuilder()
.AddArgument("action", "open")
.AddArgument("targetId", "1001")
.AddText("詳細があります")
.AddText("クリックして詳細を開きます。")
.Show();

WPFやWinFormsで画面を操作する場合は、UIスレッドに戻すことも忘れないでください。

8-5. Windowsバージョンによって動作が異なる場合

Windows 10とWindows 11では、通知の見た目や通知センターの動作が異なる場合があります。また、進捗バーや高度な通知レイアウトは、Windowsのビルド番号によって対応状況が変わることがあります。

進捗バーのXML要素はデスクトップの特定ビルド以降でサポートされる機能として説明されています。古い環境も対象にする場合は、テキスト中心のシンプルな通知にしておくと安全です。GitHub

9. C#でトースト通知を実装する時のベストプラクティス

9-1. ユーザーに通知を出しすぎない設計

トースト通知は便利ですが、出しすぎると迷惑になります。たとえば、1件ごとの処理完了をすべて通知するのではなく、「10件の処理が完了しました」のようにまとめて通知する方がよい場合があります。

通知すべき情報かどうかは、次の基準で判断します。

ユーザーが今すぐ知る必要があるか、アプリ画面を見ていなくても気づく必要があるか、通知をクリックした後に具体的な行動があるか、通知センターに残す意味があるかです。

この基準に当てはまらない情報は、ステータスバー、ログ画面、バッジ表示などで代替した方がよいでしょう。

9-2. 通知内容を短く分かりやすくするコツ

トースト通知の文面は短く、結論を先に書きます。

良い例は次のような文面です。

バックアップ完了
2026年6月分のバックアップが正常に終了しました。

悪い例は次のような文面です。

お知らせ
処理が行われました。詳細についてはアプリケーションを確認してください。

タイトルには結果、本文には対象や次の行動を書きます。「何が」「どうなったか」「必要なら何をすればよいか」が分かるようにしましょう。

9-3. エラー通知・完了通知・リマインダーの使い分け

完了通知は、処理がバックグラウンドで終わったことを知らせるために使います。エラー通知は、ユーザー対応が必要な問題に限定します。リマインダーは、時刻や期限に意味がある情報に使います。

たとえば、単なる入力エラーは画面内に表示すべきです。一方、長時間処理が失敗した場合はトースト通知が有効です。通知の種類に応じて、音を鳴らすか、ボタンを付けるか、通知センターに残すかを変えると使いやすくなります。

9-4. 業務アプリで使う場合の注意点

業務アプリでC#のトースト通知を使う場合は、セキュリティと情報量に注意します。通知はロック画面や共有PC環境で見える可能性があるため、個人情報、顧客情報、金額、機密情報をそのまま表示しない方が安全です。

たとえば、次のような通知は避けます。

田中太郎様の請求書 1,234,567円 の承認が必要です

代わりに、次のようにします。

承認が必要です
請求処理に確認が必要な項目があります。

詳細はアプリ内で認証後に表示する設計にすると、安全性が高まります。

9-5. 通知ログを残す設計

トースト通知は一時的なUIです。ユーザーが見逃すこともあります。そのため、重要な通知はアプリ側にもログを残しましょう。

ログには、通知日時、通知種別、タイトル、本文、関連ID、クリックされたかどうか、処理結果などを残すと便利です。

C#
public record NotificationLog(
DateTimeOffset CreatedAt,
string Type,
string Title,
string Message,
string? RelatedId
);

通知を表示するサービス内でログも記録すれば、「通知が出なかった」「見逃した」という問い合わせに対応しやすくなります。

10. C#のトースト通知に関するよくある質問

10-1. C#だけでトースト通知は実装できる?

はい、C#だけで実装できます。WPF、WinForms、コンソールアプリでも、CommunityToolkit.WinUI.Notificationsを使えば比較的簡単にトースト通知を表示できます。

ただし、クリック時の起動処理、通知履歴の管理、配布時のアプリID、MSIXパッケージ化などを本格的に扱う場合は、Windowsの通知基盤に関する理解も必要です。

10-2. Windows 7やWindows 8でも使える?

Windows 10/11形式の現在のトースト通知を前提にするなら、Windows 7は対象外です。Windows 7向けには、NotifyIconのバルーン通知や独自のポップアップを使う必要があります。

Windows 8系にも通知機能はありますが、現在のC#デスクトップアプリで一般的に使うトースト通知の実装とは前提が異なります。新規開発ではWindows 10/11を対象にするのが現実的です。

10-3. コンソールアプリでもトースト通知は表示できる?

はい、表示できます。CommunityToolkit.WinUI.Notificationsを追加し、Windows向けターゲットでビルドすれば、コンソールアプリからも通知を送信できます。MicrosoftのNuGet説明でも、WPF、UWP、WinForms、コンソールなどのC#アプリタイプをサポートする旨が示されています。NuGet

ただし、コンソールアプリは実行がすぐ終了することが多いため、クリックイベントを処理したい場合は、プロセスの起動状態やアプリの再起動処理を考慮する必要があります。

10-4. バックグラウンド実行中でも通知できる?

できます。ただし、バックグラウンド実行の形態によります。ユーザーがログインしているセッションで動く常駐アプリなら通知しやすいです。一方、Windowsサービスやタスクスケジューラから直接通知を出す場合は、ユーザーセッションの問題で期待どおり表示されないことがあります。

常駐アプリ、タスクトレイアプリ、ユーザー起動の補助プロセスなど、通知を担当するプロセスをユーザーセッション側に置く構成が実務では扱いやすいです。

10-5. トースト通知とバルーン通知の違いは?

バルーン通知は、主にタスクトレイアイコンに紐づいて表示される古い形式の通知です。WinFormsのNotifyIconでよく使われます。

トースト通知は、Windows 10/11の通知センターと連携する新しい通知形式です。画像、ボタン、入力欄、クリック引数、通知履歴などを扱えるため、よりリッチな通知を実装できます。

単純な常駐アプリならNotifyIconでも十分な場合がありますが、Windows標準の通知体験に合わせたいならトースト通知が適しています。

10-6. 外部ライブラリなしで実装できる?

外部ライブラリなしでも、Windows.UI.NotificationsとXMLを使って実装できます。ただし、通知XMLの作成、AppUserModelID、ショートカット、クリック時の処理などを自前で扱う必要があり、実装は複雑になります。

そのため、通常はCommunityToolkit.WinUI.Notificationsを使う方が簡単です。特にToastContentBuilderを使えば、XMLを直接書かずにC#のメソッドチェーンで通知を構築できます。

外部ライブラリを避けたい理由が「依存関係を減らしたい」だけなら、まずはToolkitを使った実装で要件を満たし、どうしても必要な場合だけWinRT APIを直接使う方が安全です。

まとめ

C#でトースト通知を実装するには、Windowsの通知機能の仕組み、アプリID、通知設定、実行権限、アプリの種類ごとの違いを理解しておくことが大切です。

もっとも簡単に始めるなら、CommunityToolkit.WinUI.Notificationsを導入し、ToastContentBuilderで通知タイトルと本文を指定してShow()を呼び出します。WPFやWinFormsでは、ボタンクリックや処理完了イベントから呼び出すだけで、比較的簡単にWindowsのトースト通知を表示できます。

一方で、通知が表示されない場合は、コードだけでなくWindowsの通知設定、応答不可モード、管理者権限、AppUserModelID、NuGetパッケージ、ターゲットフレームワークを確認する必要があります。特にデスクトップアプリでは、実装方法によってアプリIDやショートカット登録が重要になります。

実務で使う場合は、通知を出しすぎないこと、文面を短く分かりやすくすること、機密情報を表示しないこと、重要な通知はログに残すことを意識しましょう。C#のトースト通知を適切に使えば、WPF、WinForms、コンソールアプリの使いやすさを大きく向上させることができます。