Windowsアプリのタスクトレイ常駐とトースト通知 ── NotifyIconの落とし穴とAppNotificationの選び方

· · タスクトレイ, NotifyIcon, トースト通知, AppNotification, Windows App SDK, WinForms, WPF, C#, .NET, 常駐アプリ, Windows開発, 技術相談

「処理が終わったらユーザーにさりげなく知らせたい」「ウィンドウを閉じても監視は続けたい」── 業務アプリでは、タスクトレイ(通知領域)への常駐とトースト通知はセットで登場する定番の要件です。ところが実装してみると、閉じたはずのアプリが終了できなくなった、Explorerを再起動したらアイコンが消えた、開発中は出ていたトーストが配布先で表示されない、といった細かい問題が次々に出てきます。

さらにトースト通知は、UWP時代からAPIの世代交代が続いてきた領域です。検索して出てくるサンプルコードが、今となっては保守のみの古いAPIだったということも珍しくありません。この記事では、NotifyIconによるトレイ常駐の設計と、2026年時点でのトースト通知APIの選び方を、実務の落とし穴と一緒に整理します。

1. まず結論

  • トレイ常駐の基本は今も System.Windows.Forms.NotifyIcon です。Icon を設定し Visible = true にしないと表示されません(既定は false)。ツールチップの Text は .NET 6 以降で最大127文字です(それ以前は63文字)。12
  • WPFには NotifyIcon 相当のコントロールがありません。公式の対照表にも「同等のコントロールなし」と明記されています。csprojで UseWPFUseWindowsForms を併用してWinFormsの NotifyIcon を使うのが最小構成です。34
  • 「×ボタンで閉じてもトレイに残す」は、FormClosinge.Cancel = true にして Hide() する設計です。必ず明示的な終了手段(トレイメニューの「終了」)を別に用意し、CloseReason を見てOSのシャットダウンまで妨げないようにします。5
  • トースト通知のAPIは、2026年時点の公式推奨がはっきりしています。WinForms / WPF / 非パッケージアプリのいずれも Windows App SDK の AppNotificationManager(NuGet: Microsoft.WindowsAppSDK)が推奨です。Windows.UI.Notifications は「保守のみ」、Community Toolkit の通知コンポーネントはアーカイブ済みです。67
  • Windows App SDK の AppNotification はパッケージIDなしの普通のexeでも使えますAppNotificationManager.Default.Register() がCOMサーバー登録やAUMID相当の処理を自動で行うため、旧世代で必要だったスタートメニューショートカットの用意は不要です。ただし管理者昇格したプロセスからの通知は未サポートです。8910
  • トーストは「必ずユーザーの目に入る」手段ではありません。応答不可(Focus Assist)中はバナー表示されず通知センターへ直行しますし、設定で通知自体を切ることもできます。「通知が表示されたこと」を業務フローの前提にしない設計が必要です。1112
  • Windowsサービスからトーストは出せません(セッション0にUIはありません)。ユーザーセッション側にトレイ常駐エージェントを置き、IPCで連携するのが定石です。13

2. NotifyIconによるトレイ常駐の基本

タスクバー右端の通知領域にアイコンを出すコンポーネントが System.Windows.Forms.NotifyIcon です。バックグラウンドで動き続けるアプリが、状態表示と操作メニューの入口として使います。1

private NotifyIcon _trayIcon = null!;

private void InitializeTrayIcon()
{
    var menu = new ContextMenuStrip();
    menu.Items.Add("開く", null, (_, _) => ShowMainWindow());
    menu.Items.Add(new ToolStripSeparator());
    menu.Items.Add("終了", null, (_, _) => ExitApplication());

    _trayIcon = new NotifyIcon
    {
        Icon = Properties.Resources.AppIcon, // Iconは必須。未設定だと表示されない
        Text = "受注監視ツール ── 稼働中",     // ツールチップ(.NET 6+で最大127文字)
        ContextMenuStrip = menu,
        Visible = true                        // 既定はfalse。trueにして初めて表示される
    };
    _trayIcon.DoubleClick += (_, _) => ShowMainWindow();
}

押さえておくポイントは3つです。

  • IconVisible = true の両方が揃って初めて表示されます。Visible の既定値は false です。1
  • Text には長さ制限があります。.NET 6以降は最大127文字、.NET 5以前と.NET Frameworkは63文字で、超えると ArgumentException が発生します。状態をツールチップに詰め込みすぎる実装は、あるとき突然例外で落ちる原因になります。214
  • 右クリックメニューは ContextMenuStrip で関連付けます。トレイアイコンはユーザーから見える唯一の入口になることが多いので、「開く」と「終了」は最低限用意します。15

もう一つ、トレイアイコンは通知の入口であると同時に、常時見えている状態表示でもあります。IconText は実行中に差し替えられるので、「正常時は通常アイコン、異常時は警告アイコン」「ツールチップに最終処理時刻を出す」のように現在の状態を反映させておくと、ユーザーがトーストを見逃していても、アイコンを見れば今の状態が分かります。トーストが「その瞬間の出来事を知らせる」手段、トレイアイコンが「現在の状態を示し続ける」手段、という役割分担です。

3. 「閉じてもトレイに残る」設計と、正しい終了経路

常駐アプリの定番が「×ボタンで閉じてもプロセスは終了せず、トレイに残る」という動きです。実装自体は FormClosing のキャンセルで簡単に書けますが、雑に書くとアプリを終了する手段がなくなるWindowsのシャットダウンを妨げるという2つの事故につながります。

private bool _exitRequested;

protected override void OnFormClosing(FormClosingEventArgs e)
{
    // ユーザーが×を押しただけなら、閉じずに隠す
    if (!_exitRequested && e.CloseReason == CloseReason.UserClosing)
    {
        e.Cancel = true;
        Hide();
        return;
    }
    // 「終了」メニュー経由、またはOSシャットダウン等はそのまま閉じる
    base.OnFormClosing(e);
}

private void ExitApplication()
{
    _exitRequested = true;
    _trayIcon.Visible = false;
    _trayIcon.Dispose();
    Close();
}

FormClosing はフォームが閉じる前に発生し、e.Cancel = true で閉鎖を取り消せます。このとき必ず CloseReason を確認してください。UserClosing(ユーザーの操作)のときだけキャンセルし、WindowsShutDown などOS起因の閉鎖はキャンセルしないのが正しい振る舞いです。516

WPFでも考え方は同じで、Window.Closinge.Cancel = true にして Hide() するパターンが公式ドキュメントにもそのまま載っています。17

なお、常駐アプリは性質上「二重に起動すると同じイベントを二重処理する」問題と隣り合わせです。多重起動防止は「Windowsアプリの多重起動防止 ── 名前付きMutexと二重起動時のアクティブ化」で整理しています。また、常駐アプリの中身(監視ループや定期処理)の作り方は「.NET Generic HostとBackgroundServiceをデスクトップアプリで使う理由」が土台になります。

4. WPFアプリでのトレイ常駐

WPFには NotifyIcon に相当するコントロールがありません。これは公式の「WinFormsコントロールと同等のWPFコントロール」対照表に「No equivalent control」と明記されている、仕様としての欠落です。3

現実的な選択肢は2つです。

選択肢 概要 判断の目安
WinFormsのNotifyIconを併用 csprojで UseWPF + UseWindowsForms を両方有効化 追加依存なし。アイコンとメニューだけなら十分
サードパーティ(H.NotifyIconなど) WPF/WinUI向けのトレイアイコン実装 XAMLで書きたい、リッチなポップアップが欲しい場合。Microsoft非公式である点は考慮

前者は、SDKスタイルのプロジェクトファイルで2つのプロパティを併記するだけです。4

<PropertyGroup>
  <TargetFramework>net8.0-windows</TargetFramework>
  <UseWPF>true</UseWPF>
  <UseWindowsForms>true</UseWindowsForms>
</PropertyGroup>

System.Windows.Forms.NotifyIcon をWPFの Application から普通にnewして使えます。メニューだけWinForms(ContextMenuStrip)になりますが、トレイメニュー程度であれば実用上の問題はまずありません。

5. トレイアイコンの落とし穴3つ

5.1. アイコンは既定で「隠れたアイコン」に入る ── 強制表示はできない

自分のアイコンをタスクバーに常時表示させたい、という要望は必ず出ますが、プログラムからは実現できません。公式ドキュメントに、アイコンは既定でオーバーフロー(隠れたアイコン)領域に追加され、通知領域への昇格(常時表示)を決められるのはユーザーだけ、と明記されています。18

Windows 11では「設定 → 個人用設定 → タスクバー → その他のシステムトレイアイコン」でユーザーがアプリごとにオン/オフします。常時表示が運用上重要なら、インストール手順書やヘルプに「この設定をオンにしてください」と書く、が正しい対応です。

5.2. Explorerが再起動するとアイコンが消える ── TaskbarCreated

Explorerがクラッシュや再起動でタスクバーを作り直すと、登録済みのトレイアイコンは消えます。シェルはタスクバー作成時に TaskbarCreated メッセージを全トップレベルウィンドウへブロードキャストするので、これを受けたらアイコンを再登録するのが Win32 レベルの決まりごとです。19

WinFormsの NotifyIcon はこのメッセージを内部で処理して自動的に再登録するため、通常は意識する必要はありません。自前で Shell_NotifyIcon を P/Invoke する場合(あるいはトレイアイコンを持つネイティブアプリを保守している場合)は、この再登録処理が入っているかを確認してください。「Explorerを再起動するとアイコンだけ消えて、プロセスは生きている」という症状はほぼこれです。

5.3. Disposeを忘れるとアイコンが残る

Win32的には、トレイアイコンは不要になったら明示的に削除(NIM_DELETE)する必要があり、WinFormsではそれを NotifyIcon.Dispose() が担います。18 終了経路で Visible = falseDispose() を確実に通すようにしてください。プロセスが異常終了するなどして削除されないままだと、マウスカーソルを重ねるまで幽霊アイコンが残り続ける、というのは常駐アプリ開発者なら一度は見る光景です。

第3章のコードのように、「終了」メニューの処理でトレイアイコンの後始末をしてから Close() する形にしておくのが安全です。

6. トースト通知 ── どのAPIを使うか

トースト通知は、画面右下にバナーとして表示され、通知センターに残る通知です。デスクトップアプリから出す方法はこの10年で世代交代が続いており、検索結果には古いサンプルが大量に残っています。2026年時点の整理は次のとおりです。6

API NuGet / 名前空間 位置付け(2026年時点) 判断
Windows App SDK AppNotification Microsoft.WindowsAppSDK / Microsoft.Windows.AppNotifications WinForms・WPF・非パッケージWin32に公式推奨 新規はこれ
Community Toolkit Notifications Microsoft.Toolkit.Uwp.Notifications アーカイブ済み。現行のCommunity Toolkitに含まれず、最終更新は2022年 既存コードの維持のみ。新規採用しない
WinRT直接利用 Windows.UI.Notifications(Windows TFM経由) 保守のみ。推奨対象はUWP 新規採用しない
NotifyIcon.ShowBalloonTip System.Windows.Forms バルーン通知のAPI。Windows 10ではトーストとして表示、Windows 11では一時表示で通知センターに残らない 簡易用途なら可。挙動がOSで変わる点に注意

補足が2つあります。

  • ShowBalloonTip は「昔のAPIだが実は生きている」枠です。Windows 10ではバルーンはトーストとして描画され、閉じるまで通知センターに残ります。一方Windows 11では従来のバルーンに近い一時的な表示になり、消えた後は通知センターに残りません。表示時間の指定(timeout)も現在は無視され、OS側のアクセシビリティ設定に従います。トレイ常駐アプリが自分の状態変化を軽く知らせる程度なら十分ですが、「通知センターに履歴を残したい」ならWindows 11では役に立たない、と覚えておいてください。20
  • 素の Windows.UI.Notifications をデスクトップアプリから使う古典的な方法には、AUMID(AppUserModelID)付きショートカットをスタートメニューに登録しておかないとトーストが表示されないという有名な制約があります。21 この面倒さを解消したのが次章の AppNotification です。

7. Windows App SDK AppNotificationの最小実装

Windows App SDK のアプリ通知APIは、パッケージ化していない普通のexeでも、パッケージIDなしで動作します8 プロジェクト側の前提は、Windows固有のTFM(例: net8.0-windows10.0.19041.0)、<WindowsPackageType>None</WindowsPackageType>(非パッケージの場合)、そして配布先へのWindows App SDKランタイムのインストールです。9

using Microsoft.Windows.AppNotifications;
using Microsoft.Windows.AppNotifications.Builder;

// 起動時に一度だけ。ハンドラー登録 → Register() の順序が重要
AppNotificationManager.Default.NotificationInvoked += (_, args) =>
{
    // トーストのクリックやボタン押下がここに届く(引数はargs.Argumentsで判別)
    if (args.Arguments.TryGetValue("action", out var action) && action == "openLog")
    {
        ShowLogWindow();
    }
};
AppNotificationManager.Default.Register();

// 通知を出す
var notification = new AppNotificationBuilder()
    .AddText("受注取込が完了しました")
    .AddText("新規12件、エラー1件")
    .AddButton(new AppNotificationButton("ログを開く")
        .AddArgument("action", "openLog"))
    .BuildNotification();
AppNotificationManager.Default.Show(notification);

実務上の注意点は次のとおりです。

  • NotificationInvoked の購読は Register() より前に行います。順序を誤ると、トーストのクリックでアプリが起動されたときにイベントを取りこぼします。9
  • アプリ終了前には AppNotificationManager.Default.Unregister() を呼びます。公式ドキュメントに、終了前のUnregisterでリソースを後始末し、以後の通知クリックでアプリが正しく起動されるようにすべきと明記されています。第3章の「終了」メニューの処理に、NotifyIcon.Dispose() と並べて組み込んでください(通知機能を今後一切使わないアプリをアンインストールする場合などは、登録情報ごと消す UnregisterAll() が別に用意されています)。22
  • 非パッケージアプリでは Register() がCOMサーバー登録・AUMID相当の処理を自動で行います。旧世代(素のWinRT)で必要だったショートカット設置やレジストリ登録は不要です。MSIXでパッケージ化する場合は、逆にPackage.appxmanifestへのCOMアクティベーター記載が必要になります。9
  • Windows App SDKランタイムを同梱するself-contained配布を選ぶ場合は注意が必要です。AppNotificationManager はWindows App SDKのSingletonパッケージに依存しており、self-containedアプリから呼び出す際の考慮事項が公式に案内されています。配布方式を決める前に確認してください。23
  • 管理者に昇格したプロセスからの通知は未サポートです。Show は例外を出さず静かに失敗するため、原因に気づきにくい問題です。昇格が必要なアプリは、通知だけ非昇格プロセスに任せる分離を検討してください(この分離の考え方は「Windowsアプリで「管理者権限が必要な処理だけ」を分離する具体的な書き方」で扱っています)。10
  • トーストがクリックされたとき、アプリが起動していなければプロセスが新たに起動されます。トレイ常駐アプリでは多重起動防止(第3章参照)と組み合わせて、既存インスタンスへ処理を渡す設計にしておく必要があります。

8. 一歩進んだ使い方 ── 進捗バー付きトーストと通知の後始末

8.1. 進捗をトーストの中で更新する ── UpdateAsync

「受注データ120件を取り込み中」のような長い処理の進捗は、通知を何度も出し直すのではなく、1枚のトーストの中の進捗バーを書き換えるのが正しい作り方です。AppNotificationには、そのためのデータバインドと更新の仕組みがあります。24

作りは3段階です。まず進捗バーの各値を Bind 系メソッドでプレースホルダーにし、Tag(と必要なら Group)で通知を識別できるようにして表示します。その後は AppNotificationProgressDataUpdateAsync に渡すだけで、表示済みのトーストの中身だけが書き換わります。

const string tag = "import-progress";
const string group = "batch";

// 初回表示: 値はバインドにして、初期値をProgressに設定する
var notification = new AppNotificationBuilder()
    .AddText("受注データを取り込んでいます")
    .AddProgressBar(new AppNotificationProgressBar()
        .BindStatus().BindValue().BindValueStringOverride())
    .SetTag(tag)
    .SetGroup(group)
    .BuildNotification();

notification.Progress = new AppNotificationProgressData(1) // シーケンス番号
{
    Status = "取込中...", Value = 0, ValueStringOverride = "0/120件"
};
AppNotificationManager.Default.Show(notification);

// 進捗が進むたびに: シーケンス番号を増やして更新する
var data = new AppNotificationProgressData(2)
{
    Status = "取込中...", Value = 45 / 120.0, ValueStringOverride = "45/120件"
};
await AppNotificationManager.Default.UpdateAsync(data, tag, group);

シーケンス番号は更新の順序を示す非ゼロの整数で、複数の更新が前後して届いた場合は最も大きい番号が表示されます。非同期処理から並行して更新を投げても古い値で巻き戻らないための仕組みなので、単調増加させてください。25

8.2. 「更新」と「差し替え」の使い分け

同じ Tag で新しい通知を Show し直す「差し替え」でも見た目は更新できますが、挙動が異なります。24

  差し替え(同じTagで再Show) 更新(UpdateAsync)
通知センター内の位置 先頭に移動する その場に留まる
変更できる内容 レイアウトを含めてすべて バインドした進捗バーと先頭テキストのみ
ポップアップ 再表示できる 再表示されない(静かに書き換わる)
ユーザーが既に閉じていた場合 常に送られる 失敗する

公式ドキュメントの推奨も明確で、途中経過は更新、完了は差し替えです。進捗が50%から65%になったことをいちいちポップアップで知らせる必要はありませんが、「取込完了(エラー3件)」はユーザーが進捗通知を閉じてしまっていても届いてほしいからです。完了時には進捗バーを外してボタン(「エラー内容を見る」など)を付けた別レイアウトに差し替える、という形が実務の定番になります。

8.3. 通知センターに残った古い通知を片付ける

トーストはユーザーが消すまで通知センターに溜まります。常駐アプリが毎日何件も通知を出すと、通知センターが自アプリの古い通知だらけになり、かえって重要な通知が埋もれます。

Tag / Group を付けておけば、自アプリの通知をコードから削除できます(タグ指定・グループ指定・全削除)。有効期限の設定もできるので、「進捗系は完了時に消す」「情報系は有効期限を短くする」といった片付けのルールを、通知を出す設計と同時に決めておくのがおすすめです。26

9. 通知が「届かない」ケースを設計に織り込む

トースト通知は確実な伝達手段ではありません。表示されない・気づかれない経路が正常系として存在します。

ケース 挙動
応答不可(Focus Assist / Do not disturb)が有効 バナーは表示されず、通知は通知センターへ直行する
アプリ単位・システム全体で通知がオフ 表示されない
管理者昇格プロセスからのAppNotification 未サポート。表示されない
フルスクリーンアプリ実行中など OSの判断で抑制されることがある

応答不可は、Windows 10では「集中モード(Focus assist)」、Windows 11では「設定 → システム → 通知」の「応答不可」トグルで、ユーザーやグループポリシーが制御します。OSアップグレード直後の1時間は自動的に有効になる仕様さえあります。11 集中モードの動作は「通知を出さない」ではなく「バナー表示を抑止して通知センターへ送る」なので、ユーザーが後から通知センターを開けば見えます。12

設計への含意はシンプルです。

  • トーストは「気づいてもらえたら早く対応できる」補助チャネルとして使い、業務上必須の情報はアプリ内の画面・一覧で必ず確認できるようにします。「トーストが出たはず」を業務フローの前提にしないでください。
  • どうしても割り込みが必要な通知(緊急停止の警告など)は、AppNotificationScenario.Urgent(重要な通知)でユーザー許可のもと応答不可を突破する仕組みがありますが27、乱用すればユーザーはアプリの通知ごとオフにします。本当に緊急のものだけに絞るべきです。

外部装置の異常などをどう画面に出すかという、より広い話は「外部機器の状態の確認と表示のベストプラクティス」も参考にしてください。

10. Windowsサービスから通知したいとき

「常駐サービスが異常を検知したら、ログオン中のユーザーにトーストで知らせたい」という要件は自然に出てきますが、サービスから直接トーストは出せません。Windows Vista以降、サービスはセッション0という専用セッションで動作し、ユーザーと対話するUIを持てないためです。13

定石は、UIをユーザーセッション側のプロセスに分離する構成です。

[セッション0]                      [ユーザーセッション]
 Windowsサービス   ←─ IPC ─→   トレイ常駐エージェント
 (監視・業務処理)   名前付きパイプ等   (NotifyIcon + AppNotification)

複数ユーザーが同時ログオンする環境(RDP・共有端末)では、エージェントはセッションごとに1つずつ動くことになります。「誰に通知すべきか」(全員か、特定ユーザーだけか)を要件として先に決めておくと、設計がぶれません。

11. まとめ

  • トレイ常駐は NotifyIcon が基本。Icon + Visible = true で表示し、Text は127文字制限(.NET 6+)、終了経路では Dispose() を確実に通します。アイコンとツールチップは「現在の状態」を示す常時表示としても使います。
  • 「×で閉じてもトレイに残す」は FormClosing のキャンセルで実装しますが、CloseReason.UserClosing のときだけキャンセルし、明示的な「終了」メニューを必ず用意します。
  • アイコンの常時表示はユーザーにしか決められません。Explorer再起動時の消失は TaskbarCreated の再登録で対処します(WinFormsは自動)。
  • トースト通知の新規実装は Windows App SDK の AppNotificationManager 一択です。非パッケージexeでもパッケージIDなしで動き、Register() が面倒な登録を自動化します。Community Toolkit通知はアーカイブ済み、素のWinRTは保守のみです。
  • 長い処理の途中経過は UpdateAsync で1枚のトーストの進捗バーを静かに書き換え、完了は差し替えでポップアップさせるのが定石です。Tag/Group を付けて、古い通知の削除まで設計に含めます。
  • トーストは応答不可や通知オフで届かないことがある補助チャネルです。必須情報はアプリ内で確認できる設計にし、昇格プロセスからの通知が未サポートである点にも注意してください。
  • サービスからの通知は、ユーザーセッション側のトレイ常駐エージェント+IPCという分離構成で実現します。

関連記事

関連する相談領域

合同会社小村ソフトでは、トレイ常駐型の監視ツールや通知エージェントの設計・実装、Windowsサービスと組み合わせた常駐システムの構成検討、既存常駐アプリの不具合調査を扱っています。

参考リンク

  1. Microsoft Learn, NotifyIcon Class / NotifyIcon.Visible Property. 通知領域にアイコンを表示するコンポーネントであること、Iconプロパティの設定が必要なこと、Visibleの既定値がfalseであることについて。  2 3

  2. Microsoft Learn, NotifyIcon.Text Property. ツールチップテキストの上限と、超過時にArgumentExceptionが発生することについて。  2

  3. Microsoft Learn, Windows Forms Controls and Equivalent WPF Controls. WPFにNotifyIconと同等のコントロールが存在しないことについて。  2

  4. Microsoft Learn, MSBuild properties for .NET desktop projects. UseWPFとUseWindowsFormsを併用できることについて。  2

  5. Microsoft Learn, Form.FormClosing Event. フォームが閉じる前に発生し、Cancelプロパティで閉鎖を取り消せることについて。  2

  6. Microsoft Learn, Windows notifications overview. アプリ種別ごとの推奨通知APIの対応表。WinForms/WPF/非パッケージWin32へのWindows App SDK推奨と、Windows.UI.NotificationsのMaintenance only位置付けについて。  2

  7. Microsoft Learn, Windows Community Toolkit — Notifications (archive). Notificationsコンポーネントがアーカイブされ、Windows App SDKのアプリ通知に置き換えられたことについて。 

  8. Microsoft Learn, Use the Windows App SDK in an existing project. Windows App SDKのアプリ通知APIがパッケージ・非パッケージ両対応で、パッケージIDを必要としないことについて。  2

  9. Microsoft Learn, Quickstart: App notifications in the Windows App SDK. AppNotificationManager/AppNotificationBuilderの使い方、非パッケージアプリでのRegister()による自動登録、NotificationInvokedをRegister()前に購読すべきこと、パッケージアプリでのマニフェスト記載について。  2 3 4

  10. Microsoft Learn, App notifications overview. 管理者昇格したアプリからの通知送信が未サポートであることについて。  2

  11. Microsoft Learn, Notifications don’t appear or aren’t displayed. 応答不可(Quiet Hours / Focus Assist)による通知抑止、OSアップグレード後1時間の自動有効化、通知が表示されない場合の確認手順について。  2

  12. Microsoft Learn, Focus assist. 集中モードが通知のバナー表示を抑止して通知センターへ直接送る仕組みであることについて。  2

  13. Microsoft Learn, Service Changes for Windows Vista / Interactive Services. セッション0がサービス専用でありユーザーとの対話をサポートしないこと、ユーザーへの表示にはCreateProcessAsUserでユーザーセッションにプロセスを作りIPCで連携する方法が推奨されることについて。  2

  14. Microsoft Learn, NotifyIcon.Text maximum text length increased. .NET 6でTextの最大長が63文字から127文字に拡張された破壊的変更について。 

  15. Microsoft Learn, How to associate a shortcut menu with a Windows Forms NotifyIcon component. ContextMenuStripによる右クリックメニューの関連付けについて。 

  16. Microsoft Learn, FormClosingEventArgs Class. CloseReasonでフォームが閉じられる理由を判別できることについて。 

  17. Microsoft Learn, How to close a window or dialog box (WPF). WPFのClosingイベントでe.Cancel = trueとしてHide()する非表示化パターンについて。 

  18. Microsoft Learn, Notification Area (Windows Shell). アイコンが既定でオーバーフロー領域に追加されること、通知領域への昇格を決められるのはユーザーだけであること、不要になったアイコンはNIM_DELETEで削除する必要があることについて。  2

  19. Microsoft Learn, The Taskbar. タスクバー作成時にTaskbarCreatedメッセージがブロードキャストされ、受信したらトレイアイコンを再登録すべきであることについて。 

  20. Microsoft Learn, Shell_NotifyIconW function. バルーン通知がWindows 10ではトースト(バナー)として表示され通知センターに残ること、Windows 11では一時的な表示となり通知センターに残らないこと、表示時間がアクセシビリティ設定に従うことについて。 

  21. Microsoft Learn, Send a local toast notification from a C# app (Win32/クラシックAPI). 素のToastNotificationManagerを使う場合、AUMID付きショートカットのスタートメニュー登録が必須であることについて。 

  22. Microsoft Learn, AppNotificationManager.Register Method. アプリ終了前にUnregisterを呼んでリソースを後始末し、以後の通知起動が正しく行われるようにすべきこと、通知機能を今後使わない場合はUnregisterAllで登録情報を消去すべきことについて。 

  23. Microsoft Learn, AppNotificationManager.UpdateAsync Method / Windows App SDK deployment architecture. AppNotificationManagerクラスがWindows App SDKのSingletonパッケージに依存しており、self-contained配布のアプリから呼び出す場合に考慮事項があることについて。 

  24. Microsoft Learn, App notification progress bar and data binding. Bindメソッドによるデータバインド、AppNotificationProgressDataとUpdateAsyncによる更新、更新と差し替えの違い(通知センター内の位置・変更できる範囲・ポップアップ再表示・ユーザーが閉じた後の挙動)、完了時には差し替えを検討すべきことについて。  2

  25. Microsoft Learn, AppNotificationProgressData(UInt32) Constructor. シーケンス番号が更新の順序を指定する非ゼロの整数であり、複数の更新データを受信した場合は最も大きい番号のデータが表示されることについて。 

  26. Microsoft Learn, Remove app notifications. タグ・グループの付与、表示済み通知の削除、有効期限の設定について。 

  27. Microsoft Learn, App notification content. scenario=”urgent”の重要な通知がユーザー許可のもとで応答不可設定より優先されることについて。 

同じタグを共有する最新の記事です。さらに近い話題で知識を深められます。

このテーマと近いトピックページです。記事を起点に、関連するサービスや他の記事へ進めます。

この記事は次のサービスページにつながります。近い入口からご覧ください。

よくある質問

この記事のテーマについて、相談時によくある質問をまとめています。

WPFでタスクトレイ常駐アプリを作るにはどうすればよいですか?
WPFにはNotifyIcon相当のコントロールが存在しないため、csprojでUseWPFとUseWindowsFormsを併用してWinFormsのNotifyIconを使うのが最小構成です。XAMLフレンドリーな書き味が欲しい場合はH.NotifyIconなどのサードパーティライブラリという選択肢もありますが、Microsoft公式ではない点を踏まえて採用判断してください。
トースト通知のAPIはどれを使うべきですか?
2026年時点の新規実装であれば、WinForms/WPF/非パッケージアプリのいずれもWindows App SDKのAppNotificationManagerが公式推奨です。Microsoft.Toolkit.Uwp.Notificationsはアーカイブ済みで現行のCommunity Toolkitに含まれず、WinRTのToastNotificationManagerは保守のみの位置付けです。既存コードが後者2つで動いているなら急いで書き換える必要はありませんが、新規に選ぶ理由はありません。
トースト通知が表示されないときは何を確認すればよいですか?
まずOS側の設定です。応答不可(Focus Assist)が有効だと通知はバナー表示されず通知センターへ直行しますし、設定アプリでアプリ単位・システム全体の通知がオフになっている場合も表示されません。実装側では、管理者昇格したプロセスからのAppNotificationは未サポートで表示に失敗する点、素のWindows.UI.NotificationsをAUMIDなしのデスクトップアプリから呼んでも表示されない点が代表的な原因です。
Windowsサービスからトースト通知を出せますか?
出せません。Windows Vista以降、サービスはセッション0で動作し、ユーザーと対話するUIを持てないためです。ユーザーに通知したい場合は、ユーザーセッション側にトレイ常駐のエージェントプロセスを用意し、サービスとは名前付きパイプなどのIPCで連携して、通知の表示はエージェントが行う構成が定石です。

著者プロフィール

記事の著者プロフィールページです。

小村 豪

合同会社小村ソフト 代表

Windows ソフト開発、技術相談、不具合調査を中心に、既存資産が残る案件や原因が見えにくい障害調査に強みがあります。

ブログ一覧に戻る