//タスクトレイアイコンのクリック処理 public static bool ClickTasktrayIcon(string tooltip) { const string TRAY_WINDOW = "Shell_TrayWnd"; const string TRAY_NOTIFYWINDOW = "TrayNotifyWnd"; const string TRAY_PAGER = "SysPager"; const string TOOLBAR_CONTROL = "ToolbarWindow32"; //タスクバーのハンドル取得 var taskbarWin = FindWindow(TRAY_WINDOW, null); if (taskbarWin.Equals(IntPtr.Zero)) return false; //通知領域のハンドル取得 var trayWin = FindWindowEx(taskbarWin, IntPtr.Zero, TRAY_NOTIFYWINDOW, null); if (trayWin.Equals(IntPtr.Zero)) return false; //SysPagerの有無確認。(XP/2000はSysPagerあり) var tempWin = FindWindowEx(trayWin, IntPtr.Zero, TRAY_PAGER, null); if (tempWin.Equals(IntPtr.Zero)) tempWin = trayWin; //タスクトレイがツールバーで出来ているか確認 // → ツールバーでなければ終了 var toolWin = FindWindowEx(tempWin, IntPtr.Zero, TOOLBAR_CONTROL, null); if (toolWin.Equals(IntPtr.Zero)) return false; //タスクトレイのプロセス(Explorer)を取得し、外部から参照するために開く int expPid = 0; GetWindowThreadProcessId(toolWin, out expPid); var hProc = OpenProcess(ProcessAccess.VMOperation | ProcessAccess.VMRead | ProcessAccess.VMWrite, false, expPid); if (hProc.Equals(IntPtr.Zero)) return false; //プロセスを閉じるためにtry-finally try { var tbButtonLocal = new TBBUTTON(); //本プロセス内のタスクバーボタン情報作成(サイズ特定でのみ使用) //Explorer内のタスクバーボタン格納メモリ確保 var ptbSysButton = VirtualAllocEx(hProc, IntPtr.Zero, (IntPtr)Marshal.SizeOf(tbButtonLocal), AllocationTypes.Reserve | AllocationTypes.Commit, MemoryProtectionTypes.ReadWrite); if (ptbSysButton.Equals(IntPtr.Zero)) return false; //メモリ確保失敗 try { var tbButtonInfoLocal = new TBBUTTONINFO(); //本プロセス内ツールバーボタン詳細情報作成 //Explorer内のタスクバーボタン詳細情報格納メモリ確保 var ptbSysInfo = VirtualAllocEx(hProc, IntPtr.Zero, (IntPtr)Marshal.SizeOf(tbButtonInfoLocal), AllocationTypes.Reserve | AllocationTypes.Commit, MemoryProtectionTypes.ReadWrite); if (ptbSysInfo.Equals(IntPtr.Zero)) return false; //メモリ確保失敗 try { const int titleSize = 256; //Tooltip文字列長 var title = ""; //Tooltip文字列 //共有メモリにTooltip読込メモリ確保 var pszTitle = Marshal.AllocCoTaskMem(titleSize); if (pszTitle.Equals(IntPtr.Zero)) return false; //メモリ確保失敗 try { //Explorer内にTooltip読込メモリ確保 var pszSysTitle = VirtualAllocEx(hProc, IntPtr.Zero, (IntPtr)titleSize, AllocationTypes.Reserve | AllocationTypes.Commit, MemoryProtectionTypes.ReadWrite); if (pszSysTitle.Equals(IntPtr.Zero)) return false; //メモリ確保失敗 try { //通知領域ボタン数取得 var iCount = (int)SendMessage(toolWin, (int)Sm_Message.TB_BUTTONCOUNT, new IntPtr(0), new IntPtr(0)); //左から順に情報取得 for (var i = 0; i < iCount; i++) { var dwBytes = 0; //読み書きバイト数 var tbButtonLocal2 = new TBBUTTON(); //ボタン情報 var tbButtonInfoLocal2 = new TBBUTTONINFO(); //ボタン詳細情報 //共有メモリにボタン情報読込メモリ確保 var ptrLocal = Marshal.AllocCoTaskMem(Marshal.SizeOf(tbButtonLocal)); if (ptrLocal.Equals(IntPtr.Zero)) return false; //メモリ確保失敗 try { Marshal.StructureToPtr(tbButtonLocal, ptrLocal, true); //共有メモリ初期化 //ボタン情報取得(idCommandを取得するため) SendMessage( toolWin, (int)Sm_Message.TB_GETBUTTON, new IntPtr(i), ptbSysButton); //Explorer内のメモリを共有メモリに読み込み ReadProcessMemory( hProc, ptbSysButton, ptrLocal, (IntPtr)Marshal.SizeOf(tbButtonLocal), out dwBytes); //共有メモリの内容を構造体に変換 tbButtonLocal2 = (TBBUTTON)Marshal.PtrToStructure( ptrLocal, typeof(TBBUTTON)); } finally { Marshal.FreeCoTaskMem(ptrLocal); //共有メモリ解放 } //ボタン詳細情報を取得するためのマスク等を設定 tbButtonInfoLocal.cbSize = Marshal.SizeOf(tbButtonInfoLocal); tbButtonInfoLocal.dwMask = (int)(ToolbarButtonMask.TBIF_COMMAND | ToolbarButtonMask.TBIF_LPARAM | ToolbarButtonMask.TBIF_TEXT); tbButtonInfoLocal.pszText = pszSysTitle; //Tooltip書き込み先領域 tbButtonInfoLocal.cchText = titleSize; //マスク設定等をExplorerのメモリへ書き込み WriteProcessMemory( hProc, ptbSysInfo, ref tbButtonInfoLocal, (IntPtr)Marshal.SizeOf(tbButtonInfoLocal), out dwBytes); //ボタン詳細情報取得 SendMessage( toolWin, (int)Sm_Message.TB_GETBUTTONINFO, tbButtonLocal2.idCommand, ptbSysInfo); //共有メモリにボタン詳細情報を読み込む領域確保 var ptrInfo = Marshal.AllocCoTaskMem(Marshal.SizeOf(tbButtonInfoLocal)); if (ptrInfo.Equals(IntPtr.Zero)) return false; //共有メモリ確保失敗 try { Marshal.StructureToPtr(tbButtonInfoLocal, ptrInfo, true); //共有メモリ初期化 //Explorer内のメモリを共有メモリに読み込み ReadProcessMemory( hProc, ptbSysInfo, ptrInfo, (IntPtr)Marshal.SizeOf(tbButtonInfoLocal), out dwBytes); //共有メモリの内容を構造体に変換 tbButtonInfoLocal2 = (TBBUTTONINFO)Marshal.PtrToStructure( ptrInfo, typeof(TBBUTTONINFO)); } finally { Marshal.FreeCoTaskMem(ptrInfo); //共有メモリ解放 } //Tooltipの内容をExplorer内のメモリから共有メモリへ読込 ReadProcessMemory(hProc, pszSysTitle, pszTitle, (IntPtr)titleSize, out dwBytes); //ローカル変数へ変換 title = Marshal.PtrToStringAnsi(pszTitle, titleSize); //Tooltipが指定文字列を含んでいればクリック if (title.Contains(tooltip)) { //PostMessageでクリックを送るために、ボタン詳細情報のlParamでポイントされているTRAYNOTIFY情報が必要 var tNotify = new TRAYNOTIFY(); var tNotify2 = new TRAYNOTIFY(); //共有メモリ確保 var ptNotify = Marshal.AllocCoTaskMem(Marshal.SizeOf(tNotify)); if (ptNotify.Equals(IntPtr.Zero)) return false; //メモリ確保失敗 try { Marshal.StructureToPtr(tNotify, ptNotify, true); //初期化 //lParamのメモリを読込 ReadProcessMemory( hProc, tbButtonInfoLocal2.lParam, ptNotify, (IntPtr)Marshal.SizeOf(tNotify), out dwBytes); //構造体へ変換 tNotify2 = (TRAYNOTIFY) Marshal.PtrToStructure( ptNotify, typeof(TRAYNOTIFY)); } finally { Marshal.FreeCoTaskMem(ptNotify); //共有メモリ解放 } //クリックするためには通知領域がアクティブでなければならない SetForegroundWindow(tNotify2.hWnd); //左クリック PostMessage(tNotify2.hWnd, tNotify2.uCallbackMessage, (IntPtr)tNotify2.uID, (IntPtr)PM_Message.WM_LBUTTONDOWN); PostMessage(tNotify2.hWnd, tNotify2.uCallbackMessage, (IntPtr)tNotify2.uID, (IntPtr)PM_Message.WM_LBUTTONUP); return true; } } return false; //該当なし } finally { VirtualFreeEx(hProc, pszSysTitle, (IntPtr)titleSize, MemoryFreeTypes.Release); //メモリ解放 } } finally { Marshal.FreeCoTaskMem(pszTitle); //共有メモリ解放 } } finally { VirtualFreeEx(hProc, ptbSysInfo, (IntPtr)Marshal.SizeOf(tbButtonInfoLocal), MemoryFreeTypes.Release); //メモリ解放 } } finally { VirtualFreeEx(hProc, ptbSysButton, (IntPtr)Marshal.SizeOf(tbButtonLocal), MemoryFreeTypes.Release); //メモリ解放 } } finally { CloseHandle(hProc); //Explorerのプロセス閉じる } }
//タスクトレイアイコンのクリック処理 public static bool ClickTasktrayIcon(string tooltip) { const string TRAY_WINDOW = "Shell_TrayWnd"; const string TRAY_NOTIFYWINDOW = "TrayNotifyWnd"; const string TRAY_PAGER = "SysPager"; const string TOOLBAR_CONTROL = "ToolbarWindow32"; //タスクバーのハンドル取得 var taskbarWin = FindWindow(TRAY_WINDOW, null); if (taskbarWin.Equals(IntPtr.Zero)) { return(false); } //通知領域のハンドル取得 var trayWin = FindWindowEx(taskbarWin, IntPtr.Zero, TRAY_NOTIFYWINDOW, null); if (trayWin.Equals(IntPtr.Zero)) { return(false); } //SysPagerの有無確認。(XP/2000はSysPagerあり) var tempWin = FindWindowEx(trayWin, IntPtr.Zero, TRAY_PAGER, null); if (tempWin.Equals(IntPtr.Zero)) { tempWin = trayWin; } //タスクトレイがツールバーで出来ているか確認 // → ツールバーでなければ終了 var toolWin = FindWindowEx(tempWin, IntPtr.Zero, TOOLBAR_CONTROL, null); if (toolWin.Equals(IntPtr.Zero)) { return(false); } //タスクトレイのプロセス(Explorer)を取得し、外部から参照するために開く int expPid = 0; GetWindowThreadProcessId(toolWin, out expPid); var hProc = OpenProcess(ProcessAccess.VMOperation | ProcessAccess.VMRead | ProcessAccess.VMWrite, false, expPid); if (hProc.Equals(IntPtr.Zero)) { return(false); } //プロセスを閉じるためにtry-finally try { var tbButtonLocal = new TBBUTTON(); //本プロセス内のタスクバーボタン情報作成(サイズ特定でのみ使用) //Explorer内のタスクバーボタン格納メモリ確保 var ptbSysButton = VirtualAllocEx(hProc, IntPtr.Zero, (IntPtr)Marshal.SizeOf(tbButtonLocal), AllocationTypes.Reserve | AllocationTypes.Commit, MemoryProtectionTypes.ReadWrite); if (ptbSysButton.Equals(IntPtr.Zero)) { return(false); //メモリ確保失敗 } try { var tbButtonInfoLocal = new TBBUTTONINFO(); //本プロセス内ツールバーボタン詳細情報作成 //Explorer内のタスクバーボタン詳細情報格納メモリ確保 var ptbSysInfo = VirtualAllocEx(hProc, IntPtr.Zero, (IntPtr)Marshal.SizeOf(tbButtonInfoLocal), AllocationTypes.Reserve | AllocationTypes.Commit, MemoryProtectionTypes.ReadWrite); if (ptbSysInfo.Equals(IntPtr.Zero)) { return(false); //メモリ確保失敗 } try { const int titleSize = 256; //Tooltip文字列長 var title = ""; //Tooltip文字列 //共有メモリにTooltip読込メモリ確保 var pszTitle = Marshal.AllocCoTaskMem(titleSize); if (pszTitle.Equals(IntPtr.Zero)) { return(false); //メモリ確保失敗 } try { //Explorer内にTooltip読込メモリ確保 var pszSysTitle = VirtualAllocEx(hProc, IntPtr.Zero, (IntPtr)titleSize, AllocationTypes.Reserve | AllocationTypes.Commit, MemoryProtectionTypes.ReadWrite); if (pszSysTitle.Equals(IntPtr.Zero)) { return(false); //メモリ確保失敗 } try { //通知領域ボタン数取得 var iCount = (int)SendMessage(toolWin, (int)Sm_Message.TB_BUTTONCOUNT, new IntPtr(0), new IntPtr(0)); //左から順に情報取得 for (var i = 0; i < iCount; i++) { var dwBytes = 0; //読み書きバイト数 var tbButtonLocal2 = new TBBUTTON(); //ボタン情報 var tbButtonInfoLocal2 = new TBBUTTONINFO(); //ボタン詳細情報 //共有メモリにボタン情報読込メモリ確保 var ptrLocal = Marshal.AllocCoTaskMem(Marshal.SizeOf(tbButtonLocal)); if (ptrLocal.Equals(IntPtr.Zero)) { return(false); //メモリ確保失敗 } try { Marshal.StructureToPtr(tbButtonLocal, ptrLocal, true); //共有メモリ初期化 //ボタン情報取得(idCommandを取得するため) SendMessage( toolWin, (int)Sm_Message.TB_GETBUTTON, new IntPtr(i), ptbSysButton); //Explorer内のメモリを共有メモリに読み込み ReadProcessMemory( hProc, ptbSysButton, ptrLocal, (IntPtr)Marshal.SizeOf(tbButtonLocal), out dwBytes); //共有メモリの内容を構造体に変換 tbButtonLocal2 = (TBBUTTON)Marshal.PtrToStructure( ptrLocal, typeof(TBBUTTON)); } finally { Marshal.FreeCoTaskMem(ptrLocal); //共有メモリ解放 } //ボタン詳細情報を取得するためのマスク等を設定 tbButtonInfoLocal.cbSize = Marshal.SizeOf(tbButtonInfoLocal); tbButtonInfoLocal.dwMask = (int)(ToolbarButtonMask.TBIF_COMMAND | ToolbarButtonMask.TBIF_LPARAM | ToolbarButtonMask.TBIF_TEXT); tbButtonInfoLocal.pszText = pszSysTitle; //Tooltip書き込み先領域 tbButtonInfoLocal.cchText = titleSize; //マスク設定等をExplorerのメモリへ書き込み WriteProcessMemory( hProc, ptbSysInfo, ref tbButtonInfoLocal, (IntPtr)Marshal.SizeOf(tbButtonInfoLocal), out dwBytes); //ボタン詳細情報取得 SendMessage( toolWin, (int)Sm_Message.TB_GETBUTTONINFO, tbButtonLocal2.idCommand, ptbSysInfo); //共有メモリにボタン詳細情報を読み込む領域確保 var ptrInfo = Marshal.AllocCoTaskMem(Marshal.SizeOf(tbButtonInfoLocal)); if (ptrInfo.Equals(IntPtr.Zero)) { return(false); //共有メモリ確保失敗 } try { Marshal.StructureToPtr(tbButtonInfoLocal, ptrInfo, true); //共有メモリ初期化 //Explorer内のメモリを共有メモリに読み込み ReadProcessMemory( hProc, ptbSysInfo, ptrInfo, (IntPtr)Marshal.SizeOf(tbButtonInfoLocal), out dwBytes); //共有メモリの内容を構造体に変換 tbButtonInfoLocal2 = (TBBUTTONINFO)Marshal.PtrToStructure( ptrInfo, typeof(TBBUTTONINFO)); } finally { Marshal.FreeCoTaskMem(ptrInfo); //共有メモリ解放 } //Tooltipの内容をExplorer内のメモリから共有メモリへ読込 ReadProcessMemory(hProc, pszSysTitle, pszTitle, (IntPtr)titleSize, out dwBytes); //ローカル変数へ変換 title = Marshal.PtrToStringAnsi(pszTitle, titleSize); //Tooltipが指定文字列を含んでいればクリック if (title.Contains(tooltip)) { //PostMessageでクリックを送るために、ボタン詳細情報のlParamでポイントされているTRAYNOTIFY情報が必要 var tNotify = new TRAYNOTIFY(); var tNotify2 = new TRAYNOTIFY(); //共有メモリ確保 var ptNotify = Marshal.AllocCoTaskMem(Marshal.SizeOf(tNotify)); if (ptNotify.Equals(IntPtr.Zero)) { return(false); //メモリ確保失敗 } try { Marshal.StructureToPtr(tNotify, ptNotify, true); //初期化 //lParamのメモリを読込 ReadProcessMemory( hProc, tbButtonInfoLocal2.lParam, ptNotify, (IntPtr)Marshal.SizeOf(tNotify), out dwBytes); //構造体へ変換 tNotify2 = (TRAYNOTIFY) Marshal.PtrToStructure( ptNotify, typeof(TRAYNOTIFY)); } finally { Marshal.FreeCoTaskMem(ptNotify); //共有メモリ解放 } //クリックするためには通知領域がアクティブでなければならない SetForegroundWindow(tNotify2.hWnd); //左クリック PostMessage(tNotify2.hWnd, tNotify2.uCallbackMessage, (IntPtr)tNotify2.uID, (IntPtr)PM_Message.WM_LBUTTONDOWN); PostMessage(tNotify2.hWnd, tNotify2.uCallbackMessage, (IntPtr)tNotify2.uID, (IntPtr)PM_Message.WM_LBUTTONUP); return(true); } } return(false); //該当なし } finally { VirtualFreeEx(hProc, pszSysTitle, (IntPtr)titleSize, MemoryFreeTypes.Release); //メモリ解放 } } finally { Marshal.FreeCoTaskMem(pszTitle); //共有メモリ解放 } } finally { VirtualFreeEx(hProc, ptbSysInfo, (IntPtr)Marshal.SizeOf(tbButtonInfoLocal), MemoryFreeTypes.Release); //メモリ解放 } } finally { VirtualFreeEx(hProc, ptbSysButton, (IntPtr)Marshal.SizeOf(tbButtonLocal), MemoryFreeTypes.Release); //メモリ解放 } } finally { CloseHandle(hProc); //Explorerのプロセス閉じる } }