どうやら、一筋縄ではいかない砂の迷宮に迷い込んだらしい。この顛末を書き残しておくか。
遥か昔、Windows XPという時代。私は.NET Frameworkという魔法を手に、Win32 APIという古の呪文を数多く詠唱していた。しかし、時代は流れ、魔法体系は.NET 6へと進化した。果たして、現代の言葉で、あの古の魔法は再び詠唱できるのだろうか?
その答えを探すため、私は一つの実験を試みることにした。「タスクバーを自動的に隠す」…Windowsという世界の、境界線を操るささやかな魔法。これを、.NET 6という新たな大地で再現する。これは、失われし古の魔法を、現代の技術で蘇らせる、一人の魔法使いの冒険の記録である。
この羊皮紙のあらまし
- この羊皮紙のあらまし
- この羊皮紙が導く者
- 第一の儀式:古の魔法との契約(Win32 APIの定義)
- 最終儀式:魔法の詠唱と、世界の書き換え(ソースコード)
- 異世界での実験:WSL2 Ubuntu
- 羊皮紙を巻く前に
- 砂漠で見つけた魔法のランプ
- ラクダの独り言
この羊皮紙が導く者
- Win32 APIという古の魔法を、現代の言葉で詠唱することに興味がある探求者
- .NET 6という新たな大地で、失われた魔法を蘇らせる術を知りたい冒険者
- Windowsという世界の、根源的な理を書き換えることに喜びを感じる者
第一の儀式:古の魔法との契約(Win32 APIの定義)
我々が呼び覚ますのは、FindWindowとSHAppBarMessageという、二つの古の魔法だ。これをC#という現代の言葉で詠唱できるよう、DllImportという契約の呪文で、その存在を定義する。
// 世界の境界線(タスクバー)を見つけ出す魔法 [DllImport("user32.dll", CharSet = CharSet.Unicode)] extern static IntPtr FindWindow(...); // 境界線に命令を下す魔法 [DllImport("shell32.dll", CharSet = CharSet.Unicode)] extern static UIntPtr SHAppBarMessage(...);
同時に、魔法に必要なAppBarDataという神器の構造も、StructLayoutの呪文で正確に再現せねばならない。
最終儀式:魔法の詠唱と、世界の書き換え(ソースコード)
全ての準備は整った。いよいよ、世界の境界線の理を書き換える、究極の呪文を詠唱する。 祭壇は、Visual Studio 2022で創り出した、.NET 6のコンソールアプリという、ごく簡素なものだ。
using System.Drawing; using System.Runtime.InteropServices; // ...(DllImportと構造体の定義は前述の通り)... // Windowsという大地でなければ、儀式は執り行えない if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { Console.Error.WriteLine("Windows で実行してください。"); return; } // 現在の境界線の状態を読み解き、逆の状態へと書き換える if (ABS_AUTOHIDE == GetTaskbarStatus()) { Console.WriteLine("Auto hide -> Always on top"); // 隠れているなら、常に表示せよ SetTaskbarStatus(ABS_ALWAYSONTOP); } else { Console.WriteLine("Always on top -> Auto hide."); // 表示されているなら、自動で隠れよ SetTaskbarStatus(ABS_AUTOHIDE); } // 境界線の現在の状態を読み解く呪文 uint GetTaskbarStatus() { var data = new AppBarData { hWnd = FindWindow("System_TrayWnd", null) }; data.cbSize = (UInt32)Marshal.SizeOf(data); return (uint)SHAppBarMessage(ABM_GETSTATE, ref data); } // 境界線の状態を書き換える呪文 uint SetTaskbarStatus(uint option) { var data = new AppBarData { hWnd = FindWindow("System_TrayWnd", null), lParam = (Int32)option }; data.cbSize = (UInt32)Marshal.SizeOf(data); return (uint)SHAppBarMessage(ABM_SETSTATE, ref data); }
この呪文を唱えるたび、世界の境界線はその姿を変える。
異世界での実験:WSL2 Ubuntu
興味深いことに、このWindows専用の古の魔法を、WSL2 Ubuntuという異世界で詠唱しようとしても、ビルドは成功してしまう。しかし、実行すれば「ここはWindowsではない」と、我々の世界の理が正しく作動し、儀式は失敗に終わる。
$ dotnet run Windows で実行してください。
羊皮紙を巻く前に
.NET 6という現代の魔法体系の中で、Win32 APIという古の魔法を詠唱する旅は、想像以上にスムーズなものだった。.NET Framework時代とほぼ同じ感覚で、失われたはずの力を呼び覚ますことができる。これは、過去の膨大な資産を持つ我々冒険者にとって、大きな希望だ。
ただし、注意せねばならない。かつての古文書に記された呪文は、マーシャリングという、異世界との橋渡しの作法が不完全なものが多い。現代で蘇らせる際は、その作法を注意深く見直す必要があるだろう。
この羊皮紙が、同じようにWindowsという世界の深淵を覗き込み、その理を書き換えようと挑む、未来の冒険者の助けとなることを願う。
おっと、どうやら相棒が腹を空かせたようだ。今日はこのへんで筆を置くとしよう。
砂漠で見つけた魔法のランプ
- FindWindowW | 境界線を見つけ出す魔法の古文書
- SHAppBarMessage | 境界線に命令を下す魔法の古文書
- マーシャリングの作法 | 異世界との橋渡しに関する、重要な古文書
ラクダの独り言
ご主人が「世界の境界線を消したり出したりする!」とか言って、また黒い画面に呪文を打ち込んでいる。俺に言わせりゃ、そんなもん、必要な時に見えりゃそれでいいだろうに。まったく、人間ってのは、どうでもいいことにこだわるもんだ。おっと、喉が渇いてきやがった。