C#でレジストリをいじってスタートアップにする


1行概要

C#でレジストリキーHKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Runをいじって任意のプログラムをスタートアップに設定する。

はじめに

先日、好きなプロダクトに初PR・マージされた🎉

そのプロダクトとは、Windowsのタスクバーでもネコ走らせてみた🐈で記事になっている『RunCat for Windows』だ。
タスクバーに常駐し、CPU負荷率に応じてネコが走るというもの。有名なアプリなので知っている方も多いはず。

私がPRで追加したのは、アプリのメニューアイテムにスタートアップオプションを加えるというもの。

本記事はマージ記念として、実際の修正内容をベースにC#でレジストリキーをいじってスタートアップに登録する方法を記述する。

早い話が

スタートアップに纏わるレジストリキーは4つ。

  • HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run
  • HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce
  • HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
  • HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce

上2つはルートがHKEY_CURRENT_USERでマシンの全ユーザに対象となるもの、下2つはHKEY_CURRENT_USERで現在ログイン中のユーザに対象となるもの。
末尾のRunRunOnceの違いは1回きりか半永久的にかというもの。

今回は上から3つ目、HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Runの値をいじる。

C#からレジストリをいじる

MarshalByRefObject.RegistryKeyクラスにWindowsレジストリを扱うメソッドが用意されている。
各リファレンスは次の通り。

RegistryKey.GetValue

public object GetValue (string name, object defaultValue, Microsoft.Win32.RegistryValueOptions options)
指定した名前に関連付けられている値を、取得オプションを指定して取得する。 名前が見つからない場合、設定されている既定値を返す。

パラメーター

name : String 取得する値の名前。 この文字列の大文字と小文字は区別されない。
defaultValue : Object name が存在しない場合に返す値。
options : RegistryValueOptions 取得した値のオプションの処理を指定する列挙値の 1 つ。

戻り値

Object name に関連付けられた値を、指定した options に従って処理したもの。defaultValue が見つからなかった場合は name。

RegistryKey.SetValue

public void SetValue (string name, object value)
指定した名前/値ペアを設定する。

パラメーター

name : String 格納する値の名前。
value : Object 格納するデータ。

RegistryKey.DeleteValue

public void DeleteValue (string name)
指定した値をこのキーから削除する。

パラメーター

name : String 削除する値の名前。

RegistryKey.Close

public void Close ()
キーを閉じ、キーの内容が変更されている場合はディスクへフラッシュする。

実際のコード

追加をしたメソッドは主に次の2つだ。

SetStartup

メニューアイテムのスタートアップオプションをクリックした際に発火する処理。
ラジオチェックの値を切り替え、オン/オフに応じてレジストリキーをセット/削除する。

Program.cs
private void SetStartup(object sender, EventArgs e)
{
    startupMenu.Checked = !startupMenu.Checked;
    string keyName = @"Software\Microsoft\Windows\CurrentVersion\Run";
    using (RegistryKey rKey = Registry.CurrentUser.OpenSubKey(keyName, true))
    {
        if (startupMenu.Checked)
        {
            rKey.SetValue(Application.ProductName, Application.ExecutablePath);
        }
        else
        {
            rKey.DeleteValue(Application.ProductName, false);
        }
        rKey.Close();
    }
}

IsStartupEnabled

レジストリの値を読み込み、nullでない(=IsStartupEnabled)ならtrueを、null(=IsNotStartupEnabled)ならfalseを返す。

Program.cs
private bool IsStartupEnabled()
{
    string keyName = @"Software\Microsoft\Windows\CurrentVersion\Run";
    using (RegistryKey rKey = Registry.CurrentUser.OpenSubKey(keyName))
    {
        return (rKey.GetValue(Application.ProductName) != null) ? true : false;
    }
}

おわりに

今回はC#でレジストリキーHKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Runをいじって任意のプログラムをスタートアップに設定する内容を説明した。
好きなプロダクトにPRが通ったことは素直にうれしい経験だった。