WinFormsで作るシンプルなアプリケーションランチャー【.NET 9 / C#】

コンピュータ

WinFormsでシンプルなアプリケーションランチャーを作成しました。

プロジェクトの作成

mkdir ApplicationLauncher01
cd ApplicationLauncher01
dotnet new winforms

ソースコード

ファイル名:Form1.cs

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Text.Json;
using System.Windows.Forms;

namespace ApplicationLauncher01;

public class AppInfo
{
    public string? Name { get; set; }
    public string? FullName { get; set; }

    [System.Text.Json.Serialization.JsonIgnore]
    public Icon? Icon { get; set; }
}

public partial class Form1 : Form
{
    private const string IniPath = "AppLaunch.json";
    private List<AppInfo> apps = new();
    private ImageList imageList = new();

    ListBox listBox = new()
    {
        Dock = DockStyle.Fill,
        DrawMode = DrawMode.OwnerDrawFixed,
        ItemHeight = 50
    };

    public Form1()
    {
        InitializeComponent();
        InitUI();
        LoadApps();
    }
    private void InitUI()
    {
        this.Text = "App Launcher";
        this.Width = 600;
        this.Height = 400;
        this.AllowDrop = true;

        this.Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath);

        // リストボックスのアテムの描画
        listBox.DrawItem += ListBox_DrawItem;

        // リストボックスでダブルクリック
        listBox.MouseDoubleClick += ListBox_MouseDoubleClick;

        // リストボックスでキーダウン
        listBox.KeyDown += ListBox_KeyDown;

        // コントロールの追加
        this.Controls.Add(listBox);

        // ドラックエンター
        this.DragEnter += Form1_DragEnter;

        // ドラックドロップ
        this.DragDrop += Form1_DragDrop;

        // フォームクロージング
        this.FormClosing += Form1_FormClosing;
    }

    // 読み込み
    private void LoadApps()
    {
        if (!File.Exists(IniPath)) return;
        
        var lines = File.ReadAllLines(IniPath);
        foreach (var line in lines)
        {
            try
            {
                var info = JsonSerializer.Deserialize<AppInfo>(line);
                if (info != null && File.Exists(info.FullName))
                {
                    try { info.Icon = Icon.ExtractAssociatedIcon(info.FullName); } catch { }
                    apps.Add(info);
                    (Controls[0] as ListBox)?.Items.Add(info);
                }
            }
            catch { }
        }
    }

    // 保存
    private void SaveApps()
    {
        var options = new JsonSerializerOptions { WriteIndented = false };
        using var writer = new StreamWriter(IniPath, false);
        foreach (var app in apps)
        {
            app.Icon = null;
            writer.WriteLine(JsonSerializer.Serialize(app, options));
        }
    }

    // リストボックスのアイテムの描画
    void ListBox_DrawItem(object? sender, DrawItemEventArgs e)
    {
        e.DrawBackground();
        if (e.Index < 0 || e.Index >= apps.Count) return;

        var app = apps[e.Index];
        var icon = app.Icon ?? SystemIcons.Application;
        var font = e.Font ?? SystemFonts.DefaultFont;
        e.Graphics.DrawIcon(icon, e.Bounds.Left + 4, e.Bounds.Top + 4);
        e.Graphics.DrawString(app.Name, font, Brushes.Black, e.Bounds.Left + 54, e.Bounds.Top + 15);
    }
    // リストボックスでダブルクリック
    void ListBox_MouseDoubleClick(object? sender, MouseEventArgs e)
    {
        if (listBox.SelectedIndex < 0) return;

        // アプリケーションの起動
        var path = apps[listBox.SelectedIndex].FullName;
        if (File.Exists(path)) Process.Start(path);
    }
    // リストボックスでキーダウン
    void ListBox_KeyDown(object? sender, KeyEventArgs e)
    {
        if (listBox.SelectedIndex < 0) return;

        if (e.KeyCode == Keys.Delete)
        {
            // 削除
            apps.RemoveAt(listBox.SelectedIndex);
            listBox.Items.RemoveAt(listBox.SelectedIndex);
        }
    }
    // ドラックエンター
    void Form1_DragEnter(object? sender, DragEventArgs e)
    {
        var data = e.Data;
        if (data is null) return;

        if (data.GetDataPresent(DataFormats.FileDrop)) e.Effect = DragDropEffects.Copy;
    }
    // ドラックドロップ
    void Form1_DragDrop(object? sender, DragEventArgs e)
    {
        var data = e.Data;
        if (data is null) return;

        var fileDrop = data.GetData(DataFormats.FileDrop);
        if (fileDrop is null) return;

        string[] files = (string[])fileDrop;
        string exe = files[0];
        if (Path.GetExtension(exe).ToLower() == ".exe")
        {
            string name = Path.GetFileNameWithoutExtension(exe);
            var info = new AppInfo { Name = name, FullName = exe };
            try { info.Icon = Icon.ExtractAssociatedIcon(exe); } catch { }
            apps.Add(info);
            listBox.Items.Add(info);
        }
    }
    // フォームクロージング
    void Form1_FormClosing(object? sender, FormClosingEventArgs e)
    {
        // 保存
        this.SaveApps();
    }
}

ファイル名:ApplicationLauncher01.csproj

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

  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net9.0-windows</TargetFramework>
    <Nullable>enable</Nullable>
    <UseWindowsForms>true</UseWindowsForms>
    <ImplicitUsings>enable</ImplicitUsings>
    <ApplicationIcon>app.ico</ApplicationIcon>
  </PropertyGroup>

</Project>

適当なapp.icoをプロジェクトディレクトリに配置

ビルド

dotnet build -c Release -o output

outputに実行ファイルが作成されますので、インストールしたい場所にコピーする。

実行スクリーンショット

使い方

  • ウィンドウに登録したいアプリの.exeファイルをエクスプローラなどからドラックアンドドロップで登録
  • Deleteキーで登録したアプリを削除
  • アイコンをダブルクリックでアプリケーションの起動

コメント