C#のプログラムでWin8のデスクトップ操作を改善(1)

「スタートボタン」がUI的に完璧だったかと言えば決してそうではないでしょう。ですが、デスクトップに限って言うとスタートボタンが無くなったことにより不便になった操作は確実に存在します。
それはシャットダウンであったり、コントロールパネルの呼び出しであったり、ピン止めされてないアプリの起動であったりと、いずれも「今デスクトップに存在しないもの」を使いたい場合です。


Win+I(設定チャーム)やWin+R(ファイル名を指定して実行)などのWinキーショートカットを駆使すればよいのでしょうが、そんなそんな覚えてられないのが実情です。

なので、従来スタートメニューから実行していたそれらの機能をC#のプログラムから実行する方法を考えてみます。


まずは、「Win8を触った人が最初にググるネタ」とよく言われているシャットダウンですが、これは

         dynamic shellApplication = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application"));
         shellApplication.ShutdownWindows();

だけでOKです(COMの解放の件は今回は考えないものとする)。これでシャットダウンメニューのダイアログが画面中央に表示されます。

そしてWinキーショートカットですが、これは単純にkeybd_event() Win32 API等でそのキーコードを送信してしまえばよいのです。

using System.Runtime.InteropServices;

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern void keybd_event(byte bVirtualKey, byte bScan, uint dwFlags, IntPtr dwExtraInfo);

        private const uint KEYEVENTF_KEYUP = 2;

        public static void SendWinKey(Keys key)
        {
            keybd_event((byte)Keys.LWin, 0, 0, IntPtr.Zero); //Winキー押下
            if (key != Keys.None)
            {
                keybd_event((byte)key, 0, 0, IntPtr.Zero); //xキー押下

                keybd_event((byte)key, 0, KEYEVENTF_KEYUP, IntPtr.Zero); //xキー解除
            }
            keybd_event((byte)Keys.LWin, 0, KEYEVENTF_KEYUP, IntPtr.Zero); //Winキー解除
        }

こんなメソッドを用意してあげれば、呼び出し側はたとえば

        SendWinKey(Keys.Q); //アプリの検索チャーム

        SendWinKey(Keys.I); //設定チャーム

        SendWinKey(Keys.Pause); //コントロールパネルのシステム

みたいな感じです。

ただ、このやり方では何故か唯一Win+X("Quick Access Menu"や「高度なコンテキストメニュー」と呼ばれる機能)だけが実行できません。
なので次回は何とかしてWin+Xをプログラムから実行する方法を検討したいと思います。