[MagicKeyBattery] Windows向けApple Magic Keyboardバッテリー監視ツール
はじめに
「MagicKeyBattery」は、Windows環境でApple Magic Keyboardのバッテリー残量をタスクトレイに常駐表示するC#アプリケーションです。
WindowsにはMagic Keyboardのバッテリー残量を確認する標準機能がなく、BIOSレベルで認識されているにもかかわらず残量表示の手段が提供されていません。
このツールはWin32 HID APIを直接叩いてバッテリー情報を取得し、外部アセットを一切使わずにタスクトレイアイコンをメモリ上で動的に描画します。
ソースコードとビルド済みバイナリをGitHubで公開しています。
対応デバイス: Apple Magic Keyboard(テンキー付き / Touch IDモデル)
C# / .NET 10 / Win32 HID API / MIT License
ダウンロード・ソースコード
GitHub - fixtan/MagicKeyBattery: A lightweight Windows system tray application to monitor the battery level of Apple Magic Keyboard.
A lightweight Windows system tray application to monitor the battery level of Apple Magic Keyboard. - fixtan/MagicKeyBattery
github.comRelease v1.2.0 - Settings & Multilingual Support · fixtan/MagicKeyBattery
What's New in v1.2.0 Settings Dialog Added: You can now open a sleek dark-themed configuration UI to customize update intervals and low-battery notification thresholds.Multilingual Support (Engli...
github.comビルド方法
.NET 10 SDKがインストールされている環境で、以下のコマンドを実行します。
# ソースから直接実行
dotnet run
# スタンドアロン実行ファイルの生成
dotnet publish -c Release -r win-x64 --self-contained false /p:PublishSingleFile=true
スクリーンショット
タスクトレイ
設定ダイアログ(日本語・英語)
機能一覧
| 機能 | 説明 |
|---|---|
| バッテリー残量表示 | タスクトレイに残量をドット描画で常時表示 |
| ゼロアセット動的アイコン | 外部.icoファイル不要。16×16pxをメモリ上で毎回描画 |
| 低バッテリー通知 | 設定閾値以下でWindowsトースト通知(重複防止付き) |
| マルチ言語対応 | OS言語を自動検出。日本語/英語の動的切替 |
| 設定ダイアログ | ダークテーマUI。更新間隔・通知閾値をGUIで変更可能 |
| スタートアップ登録 | レジストリ連携でWindows起動時の自動起動をトグル |
| 超低負荷 | 3分間隔のポーリング。CPU・Bluetooth帯域への影響ほぼゼロ |
技術的課題と解決
1. キーボード排他制御の回避 ─ アクセス権0ハック
Windowsはセキュリティおよびキー入力の整合性を保つため、標準キーボードデバイス(Col01系統)をシステム側で排他制御しています。
通常のアプリケーションが GENERIC_READ | GENERIC_WRITE でデバイスハンドルを開こうとすると、Win32Error: 5 (Access Denied) で拒絶されます。
Win32 APIの CreateFile を呼び出す際、第2引数のアクセス権(dwDesiredAccess)に 0(アクセス権なし)を指定してハンドルを取得します。
HIDデバイスの仕様上、アクセス権が0であっても HidD_GetInputReport によるコントロールパケットの送受信は許可されるため、システムの排他制御をすり抜けて通信経路を確保できます。
2. Report IDの特定 ─ 総当たりプロービング
Apple製デバイスは、タイピング用のメインチャンネル(Col01)とは別に、制御信号をやり取りするための拡張チャンネル(Col02)を持っています。
モデルやファームウェアによってバッテリー情報を返却するReport IDが異なるため、事前にIDを特定する必要があります。
0x01〜0xFF(255通り)のすべてのReport IDに対し、バッファサイズを変えながら HidD_GetInputReport と HidD_GetFeature を網羅的に叩く総当たりプロービングを実施。検証に使用したテンキー付きモデル(PID: 026c)においては以下の仕様でデータが取得できることを特定しました。
| パラメータ | 値 |
|---|---|
| 窓口 | Col02 インターフェース |
| API | HidD_GetInputReport |
| Report ID | 0x90 |
| バッテリー残量格納先 | 返却バッファの3バイト目(index 2) |
| 値域 | 0〜100(パーセント) |
3. ゼロアセット動的アイコン生成
アプリケーションの軽量化とポータビリティのため、外部の .ico ファイルを一切同梱していません。C#の Graphics クラスを使用し、メモリ上の16×16ピクセルの Bitmap に直接バッテリーの外枠と残量インジケーターを1ピクセル単位で描画しています。
描画のたびに増えるHICONハンドルによるGDIリソースリークを防ぐため、user32.dll の DestroyIcon をP/Invokeし、古いハンドルを厳密に破棄する設計としています。
4. バックグラウンドポーリング最適化
OSスタックがキャッシュしているHIDレポートを取得するため、高頻度なスキャンは不要です。
スキャン間隔を3分(180,000ms)に設定し、CPU・Bluetooth帯域・キーボード側のバッテリーのいずれに対しても負荷をほぼゼロに抑えています。
ステータス更新はバックグラウンドスレッドで完全に処理され、コンテキストメニュー表示中のちらつきが発生しない設計です。
対応デバイス
現在、以下のデバイスで動作確認済みです。
| デバイス | Product ID | 接続方式 |
|---|---|---|
| Apple Magic Keyboard(テンキー付き) | 026c | Bluetooth Classic (HID) |
他のMagic Keyboardモデル(Touch IDモデル等)でも Col02 + Report ID 0x90 の組み合わせで動作する可能性がありますが、ファームウェアバージョンやモデルによって異なる場合があります。
バージョン履歴
| バージョン | リリース日 | 内容 |
|---|---|---|
| v1.0.0 | 2026/06/22 | 初版リリース。基本的なバッテリー監視機能 |
| v1.2.0 | 2026/06/22 | 設定ダイアログ追加、マルチ言語対応(日本語/英語)、低バッテリー通知、スタートアップ登録 |
プロジェクト構成
MagicKeyBattery/
├── Program.cs (アプリケーション本体・全ロジック)
├── MagicKeyBattery.csproj (.NET 10プロジェクト定義)
├── LICENSE (MIT License)
└── README.md (英語ドキュメント)
全ロジックが Program.cs の1ファイルに収まっているシングルファイル設計。Win32 API(hid.dll、kernel32.dll、user32.dll、setupapi.dll)のP/Invoke宣言、HIDデバイス列挙、バッテリー読み取り、動的アイコン生成、タスクトレイ制御、設定ダイアログ、レジストリ操作のすべてが1ファイルに含まれています。
開発の経緯
ゲーム開発(lain-lab.comの5タイトル)がひと段落したタイミングで、Bluetooth環境のアップデートも重なり、以前から不便に感じていたMagic Keyboardのバッテリー問題に取り組みました。
C#でコードを書き、GitHubにリポジトリを作成し、ビルド済みバイナリの公開まで一気に進めました。普段はThree.js/TypeScriptの世界にいるため、Win32 APIの排他制御やHIDプロトコルの世界は新鮮で、0x01〜0xFFの総当たりでReport IDを特定した瞬間が開発中のハイライトでした。