LoginSignup
10
11

More than 3 years have passed since last update.

C# - Windows常駐アプリ(タスクトレイ) - Form表示なし

Last updated at Posted at 2019-11-27

1. タスクトレイ(タスクバー)にアイコンを置く

1-1. サンプルコード

このままのプログラムだと何も役には立たない。
使い道としては、外部exeを実行したりするとか。


using System;
using System.ComponentModel; // CancelEventArgsを使用するため
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;


static class MyIconUtil
{
    static class NativeMethods
    {
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public extern static bool DestroyIcon(IntPtr handle);
    }

    public static Icon Create16x16Icon(string[] iconDot)
    {
        Bitmap bmp = new Bitmap(16,16);
        using ( Graphics g = Graphics.FromImage(bmp) ) {
            g.Clear(Color.White);
        }
        for(int y=0;y<16;y++){
            for(int x=0;x<16;x++){
                if (iconDot[y][x]=='#') {
                    bmp.SetPixel(x,y,Color.Black);
                }
            }
        }

        IntPtr Hicon = bmp.GetHicon();
        return Icon.FromHandle(Hicon);
    }

    public static void DestroyIcon(Icon icon)
    {
        NativeMethods.DestroyIcon(icon.Handle);
    }
}


class TaskTrayTest
{
    static string[] iconDot = new string[]{
        "................",
        ".###...##...##..",
        "..#...#..#.#..#.",
        "..#...#....#..#.",
        "..#...#....#..#.",
        "..#...#....#..#.",
        "..#...#....#..#.",
        "..#...#....#..#.",
        "..#...#....#..#.",
        "..#...#....#..#.",
        "..#...#....#..#.",
        "..#...#....#..#.",
        "..#...#....#..#.",
        "..#...#..#.#..#.",
        ".###...##...##..",
        "................",
    };


    TaskTrayTest()
    {
        //this.ShowInTaskbar = false; // TaskTrayTestがFormを継承する場合はコメントアウトを外す

        NotifyIcon trayIcon = new NotifyIcon();

        //trayIcon.Icon = new Icon("hogehoge.ico"); // 何かしらのアイコンを設定しないとタスクトレイに表示されない
        Icon tmpIcon = MyIconUtil.Create16x16Icon(iconDot);
        trayIcon.Icon = tmpIcon;
        trayIcon.Visible = true;
        // MyIconUtil.DestroyIcon(tmpIcon);

        trayIcon.Text = "常駐テスト";
        var menu = new ContextMenuStrip();

        menu.Items.AddRange(new ToolStripMenuItem[]{
            new ToolStripMenuItem("&Open", null, (s,e)=>{MyDoSomething();}, "Open"),
            new ToolStripMenuItem("E&xit", null, (s,e)=>{MyExit();}, "Exit")
        });

        trayIcon.DoubleClick += (s,e)=>{MyDoSomething();};
        trayIcon.ContextMenuStrip = menu;
    }

    void MyDoSomething()
    {
        Console.WriteLine("MyDoSomething is called.");
    }

    void MyExit()
    {
        var e = new CancelEventArgs();
        Application.Exit(e);
        if (e.Cancel) {
            Console.WriteLine("Application.Exit is canceled.");
        }
    }

    [STAThread]
    static void Main(string[] args)
    {
        Console.WriteLine("Main() Start.");
        new TaskTrayTest();
        Console.WriteLine("Instance is created.");
        Application.Run();
        Console.WriteLine("Main() End.");
    }
}

1-2. 説明

  • NotifyIconが、タスクトレイにアイコンを表示させるためのクラス(Microsoft Docs参照1)。 このクラスのメンバがWndProcを持っていて、メッセージループを処理してイベントを処理しているようである。(ILSpyで見た感じでは。)
  • Application.Run()が、プログラムが終了しないようにしている。NotifyIconとApplication.Runのループがやりとりしているのかはよくわからない。。 (Application.Run() - Microsoft Docs)

■気を付けるべきこと
- タスクトレイからFormを表示させたりする場合は、アプリの終了のさせ方に気を付ける必要がありそう。参考サイト3参照。

1-3. 参考サイト

  1. C#: タスクトレイに常駐するアプリの作り方
  2. フォームを表示させずにトレイアイコンを表示する - dobon.net
  3. アプリケーション(自分自身)を終了させる - dobon.net
  4. 通知領域のアイコン情報のレジストリについて

1-4. アイコン

アイコンを準備する必要があるので、それ用のソフトを持っていない・フリーソフトを入れたくない場合は、手前味噌ですが下記あたりで適当に対応ください。
- C# - ちょー雑な方法でFormのアイコンを生成する (Windows)
- C#で、文字と図形からなるWindowsアイコン(.Ico)【透過】を作成するプログラムを作ってみた
- C#で画像からWindowsアイコン(.ico)に変換するソフトつくった - 透過対応

2. スタートアップへの登録

2-1. 参考サイト

まだ試せていない
[C#] スタートアップメニューにショートカットを登録する方法

3. 多重起動の防止

まだ試せていない。Mutexを使うらしい。

4. タスクバーの常時表示領域に置く設定方法(※手作業)

2020.10.31追記しました。

image.png


  1. 日本語版は機械翻訳が酷かったので英語のほうにしてます。 

10
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
11