タスクトレイに常駐するバックグラウンドアプリをつくる

tera1707.com

やりたいこと

.NET6とC#で、タスクトレイに常駐しているアプリを作りたい。
タスクトレイからコンテキストメニューを開いて、また別のアプリを起動したりしたい。

使うもの

  • VisualStudio2022
  • C#
  • WPFのプロジェクトテンプレート
  • WinFormsのAPI

やりかた

実験アプリ仕様

今回は実験として、そのバックグラウンドアプリの中で下記のようなことをするものを作ってみる。

  • 起動すると、タスクトレイの中にアイコンを表示する。
  • アイコンにマウスオーバーすると、文言を表示する。
  • アイコンを右クリックすると、コンテキストメニューを表示する。
  • それ以外のときは、なにもしない。(exeはずっと動き続け、その間タスクトレイにアイコン表示する)

やり方

まず、以前書いた「バックグラウンドプロセスを作ってみる」の記事のやり方で、バックグラウンドアプリを作成する。

WinFormsのクラス System.Windows.Forms.NotifyIconSystem.Windows.Forms.ContextMenuStrip を使うので、 プロジェクトファイル(.csproj)に、下記を追記する。(こちらの記事も参照)

<UseWindowsForms>true</UseWindowsForms>

Appクラスの中のOnStartup(StartupEventArgs e)で、下記のようにする。

using System.Diagnostics;
using System.Windows;

namespace TaskTrayJikken
{
    public partial class App : Application
    {
        protected override void OnStartup(StartupEventArgs e)
        {
            // 右クリックに出すのコンテキストメニューを作成
            var menu = new System.Windows.Forms.ContextMenuStrip();
            menu.Items.Add("アプリを終了します", null, (obj, e) => { Shutdown(); });
            menu.Items.Add("電卓を起動します", null, (obj, e) => { Process.Start(@"C:\Windows\System32\calc.exe"); });

            // タスクトレイ上のアイコンを作成
            var notifyIcon = new System.Windows.Forms.NotifyIcon
            {
                Visible = true,
                Icon = new System.Drawing.Icon(@"MyIcon.ico"), // 今回は、icoファイルを「常にコピー」にしておいて、exeと同じ階層にicoができるようにして使用
                Text = "マウスポインタを当てたときに表示する文言",
                ContextMenuStrip = menu
            };
            // アイコンを押したときの処理
            notifyIcon.Click += (obj, e) => 
            {
                Debug.WriteLine("クリックされました");
            };

            // プロセス通常起動
            base.OnStartup(e);
        }
    }
}

コード中にも書いているが、今回はアイコンの.icoファイルを、
ファイルのプロパティの「出力ディレクトリにコピー」を「常にコピー」にしておいて、exeと同じ階層にicoがある(コピーされてる)前提で上記コードで呼ぶことにした。

参考

dobon.net

WPFでタスクトレイ常駐アプリを作る - Qiita

qiita.com