デスクトップを指定してプロセスを起動する
プロセスを起動する際は、通常、元のWindow Stationとデスクトップを引き継ぎますが、CreateProcess
ではこれらを明示的に指定できるようになっています。
STARTUPINFO si = {}; si.cb = sizeof(si); si.lpDesktop = "WinSta0\\AltDesktop"; PROCESS_INFORMATION pa = {}; CreateProcess( NULL, "C:\\Windows\\explorer.exe", NULL, NULL, FALSE, 0x00000020, NULL, NULL, &si, &pa );
あんまSTARTUPINFOの中身までみませんよね。ただ、これでDesktopを指定して動かすことが出来ます。
新しいデスクトップでExplorerを動かす
CreateDesktop
で作成したデスクトップはまっさらで、何も表示されず、普通に使うことが出来ません。たまーにWindowsはこんな感じになりますが、これは、そのデスクトップ用のExplorerが動いていないことが起因しています。
そこで、上記を用いて、Explorerを動かしてやることで、まともに使えるデスクトップにしてやります。
また、3秒で戻ってきましょう(ただ、今回は、がんばれば戻ってこれます)。
#include <Windows.h> int main() { HDESK current = OpenInputDesktop(0, FALSE, GENERIC_ALL); HDESK desk = CreateDesktop("AltDesktop", NULL, NULL, 0, GENERIC_ALL, NULL); SwitchDesktop(desk); STARTUPINFO si = {}; si.cb = sizeof(si); si.lpDesktop = "WinSta0\\AltDesktop"; PROCESS_INFORMATION pa = {}; CreateProcess( NULL, "C:\\Windows\\explorer.exe", // 64-bit OSは64-bit版を NULL, NULL, FALSE, 0x00000020, // NORMAL_PRIORITY_CLASS NULL, NULL, &si, &pa ); Sleep(3 * 1000); SwitchDesktop(current); CloseHandle(pa.hThread); CloseHandle(pa.hProcess); }
少し注意するのは64-bit OSの場合は64-bit版のExplorerを起動することです。上記のようにフルパス指定なら問題ないですが、explorer.exe
と指定した場合、プロセスのアーキテクチャに依存して起動します。タスクバーが表示されないので、間違えるとやや詰みます。
Windows 7の場合、追加したデスクトップではAeroが切れます。Windows 8ではAeroも動きますが、まあ、逆に見分けづらかったりしますね。
魔法のWindow Message
Windows 8の場合、単にExplorerを起動しただけではタスクバーがうまく表示されません。ただ、動く条件はありそうだったので、Spy++で調べたりしながら試したところ、次のようにWindow Messageを送ることでうまくいきました。
HWND wnd = FindWindow("Shell_TrayWnd", NULL); PostMessage(wnd, 0x574, 0x02, 0x00);
まあ、無理やり探し出しているので、良い方法とは言えんです。製品作ったりするならサポートにきいたほうが良いでしょうね。