2011-08-23 2 views
5

.NET 응용 프로그램 용 자동화 프레임 워크를 작성하고 싶습니다. 응용 프로그램 사용자를 시작하려면 시스템 트레이의 아이콘을 마우스 오른쪽 버튼으로 클릭하고 상황에 맞는 메뉴에서 옵션을 선택해야합니다. 좀 resaerch을 수행하고있는 유일한 방법C#을 사용하여 시스템 트레이에서 아이콘을 마우스 오른쪽 버튼으로 클릭하는 방법

[DllImport("user32.dll", SetLastError = true)] 
    static extern IntPtr FindWindowEx(IntPtr hWndParent, IntPtr hWndChildAfter, string lpClassName, string lpWindowName); 

    [DllImport("user32.dll", SetLastError = true)] 
    static extern IntPtr FindWindow(string lpClassName, string lpWindowName); 

    [DllImport("user32.dll", SetLastError = true)] 
    static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); 


    [DllImport("kernel32.dll")] 
    static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, int dwProcessId); 

    [Flags] 
    enum ProcessAccessFlags : uint 
    { 
     All = 0x001F0FFF, 
     Terminate = 0x00000001, 
     CreateThread = 0x00000002, 
     VMOperation = 0x00000008, 
     VMRead = 0x00000010, 
     VMWrite = 0x00000020, 
     DupHandle = 0x00000040, 
     SetInformation = 0x00000200, 
     QueryInformation = 0x00000400, 
     Synchronize = 0x00100000 
    } 


    [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)] 
    static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress, int dwSize, FreeType dwFreeType); 

    [Flags] 
    public enum FreeType 
    { 
     Decommit = 0x4000, 
     Release = 0x8000, 
    } 

    const uint TB_GETBUTTON = 1047; 
    const uint TB_GETBUTTONTEXTW = 1099; 
    const uint TB_BUTTONCOUNT = 1048; 
    const uint TB_PRESSBUTTON = 1027; 
    const uint TB_HIDEBUTTON = 1028; 
    const uint VM_COMMAND = 273; 
    const uint WM_RBUTTONDOWN = 0x204; 
    const uint WM_RBUTTONUP = 0x205; 
    const uint MK_RBUTTON = 2; 
    const uint WM_COMMAND = 0x0111; 
    const uint BM_CLICK = 245; 
    const uint TB_HIGHLIGHTBUTTON = 0x0407; 


    [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)] 
    static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, 
     uint dwSize, AllocationType flAllocationType, MemoryProtection flProtect); 

    [DllImport("user32.dll", EntryPoint = "PostMessage")] 
    public static extern int PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); 


    [DllImport("kernel32.dll", SetLastError = true)] 
    static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, uint dwSize, out IntPtr lpNumberOfBytesRead); 

    [Flags] 
    public enum AllocationType 
    { 
     Commit = 0x1000, 
     Reserve = 0x2000, 
     Decommit = 0x4000, 
     Release = 0x8000, 
     Reset = 0x80000, 
     Physical = 0x400000, 
     TopDown = 0x100000, 
     WriteWatch = 0x200000, 
     LargePages = 0x20000000 
    } 

    [Flags] 
    public enum MemoryProtection 
    { 
     Execute = 0x10, 
     ExecuteRead = 0x20, 
     ExecuteReadWrite = 0x40, 
     ExecuteWriteCopy = 0x80, 
     NoAccess = 0x01, 
     ReadOnly = 0x02, 
     ReadWrite = 0x04, 
     WriteCopy = 0x08, 
     GuardModifierflag = 0x100, 
     NoCacheModifierflag = 0x200, 
     WriteCombineModifierflag = 0x400 
    } 


    [DllImport("kernel32.dll", SetLastError = true)] 
    [return: MarshalAs(UnmanagedType.Bool)] 
    static extern bool CloseHandle(IntPtr hObject); 

    [StructLayout(LayoutKind.Sequential)] 
    internal struct TBBUTTON 
    { 
     public Int32 iBitmap; 
     public Int32 idCommand; 
     public byte fsState; 
     public byte fsStyle; 
     public byte bReserved1; 
     public byte bReserved2; 
     public UInt32 dwData; 
     public IntPtr iString; 
    } 

    [DllImport("user32.dll")] 
    private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); 


    //getting systemtray icon 
    static IntPtr GetSystemTrayHandle() 
    { 
     IntPtr hWndTray = FindWindow("Shell_TrayWnd", null); 
     if (hWndTray != IntPtr.Zero) 
     { 
      hWndTray = FindWindowEx(hWndTray, IntPtr.Zero, "TrayNotifyWnd", null); 
      if (hWndTray != IntPtr.Zero) 
      { 
       hWndTray = FindWindowEx(hWndTray, IntPtr.Zero, "SysPager", null); 
       if (hWndTray != IntPtr.Zero) 
       { 
        hWndTray = FindWindowEx(hWndTray, IntPtr.Zero, "ToolbarWindow32", null); 
        return hWndTray; 
       } 
      } 
     } 

     return IntPtr.Zero; 
    } 

    public static List<string> texts = new List<string>(); 

    private static unsafe bool GetTBButton(IntPtr hToolbar, int i, ref TBBUTTON tbButton, ref string text, ref IntPtr ipWindowHandle) 
    { 
     // One page 
     const int BUFFER_SIZE = 0x1000; 

     byte[] localBuffer = new byte[BUFFER_SIZE]; 

     UInt32 processId = 0; 
     UInt32 threadId = GetWindowThreadProcessId(hToolbar, out processId); 

     IntPtr hProcess = OpenProcess(ProcessAccessFlags.All, false, (int)processId); 
     if (hProcess == IntPtr.Zero) { Debug.Assert(false); return false; } 

     IntPtr ipRemoteBuffer = VirtualAllocEx(
      hProcess, 
      IntPtr.Zero, 
      (uint)new UIntPtr(BUFFER_SIZE), 
      AllocationType.Commit, 
      MemoryProtection.ReadWrite); 

     if (ipRemoteBuffer == IntPtr.Zero) { Debug.Assert(false); return false; } 

     // TBButton 
     fixed (TBBUTTON* pTBButton = &tbButton) 
     { 
      IntPtr ipTBButton = new IntPtr(pTBButton); 

      int b = (int)SendMessage(hToolbar, TB_GETBUTTON, (IntPtr)i, ipRemoteBuffer); 
      // SendMessage(hToolbar, VM_COMMAND, (IntPtr)tbButton.idCommand, ipRemoteBuffer); 


      if (b == 0) { Debug.Assert(false); return false; } 

      // this is fixed 
      Int32 dwBytesRead = 0; 
      IntPtr ipBytesRead = new IntPtr(&dwBytesRead); 

      bool b2 = ReadProcessMemory(
       hProcess, 
       ipRemoteBuffer, 
       ipTBButton, 
       (uint)new UIntPtr((uint)sizeof(TBBUTTON)), 
       out ipBytesRead); 

      if (!b2) { Debug.Assert(false); return false; } 
     } 

     // button text 
     fixed (byte* pLocalBuffer = localBuffer) 
     { 
      IntPtr ipLocalBuffer = new IntPtr(pLocalBuffer); 

      int chars = (int)SendMessage(hToolbar, TB_GETBUTTONTEXTW, (IntPtr)tbButton.idCommand, ipRemoteBuffer); 

      //SendMessage(hToolbar, BM_CLICK, (IntPtr)tbButton.idCommand, IntPtr.Zero); 

      // int getmes = PostMessage(hToolbar, TB_HIDEBUTTON, (IntPtr)tbButton.idCommand, ipRemoteBuffer); 



      if (chars == -1) { Debug.Assert(false); return false; } 

      // this is fixed 
      Int32 dwBytesRead = 0; 
      IntPtr ipBytesRead = new IntPtr(&dwBytesRead); 

      bool b4 = ReadProcessMemory(
       hProcess, 
       ipRemoteBuffer, 
       ipLocalBuffer, 
       (uint)new UIntPtr(BUFFER_SIZE), 
       out ipBytesRead); 

      if (!b4) { Debug.Assert(false); return false; } 

      text = Marshal.PtrToStringUni(ipLocalBuffer, chars); 

      if (text.Contains("Pen")) 
      { 
       int buttonid = tbButton.idCommand; 
       SendMessage(hToolbar, TB_HIGHLIGHTBUTTON, (IntPtr)tbButton.idCommand, IntPtr.Zero); 
      } 
      texts.Add(text); 

      if (text == " ") text = String.Empty; 
     } 

     VirtualFreeEx(
      hProcess, 
      ipRemoteBuffer, 
      (int)UIntPtr.Zero, 
      FreeType.Release); 

     CloseHandle(hProcess); 

     return true; 
    } 



    static void Main(string[] args) 
    { 

     IntPtr _ToolbarWindowHandle = GetSystemTrayHandle(); 

     UInt32 count = (uint)SendMessage(_ToolbarWindowHandle, TB_BUTTONCOUNT, IntPtr.Zero, IntPtr.Zero); 

     for (int i = 0; i < count; i++) 
     { 
      TBBUTTON tbButton = new TBBUTTON(); 
      string text = String.Empty; 
      IntPtr ipWindowHandle = IntPtr.Zero; 

      bool b = GetTBButton(_ToolbarWindowHandle, i, ref tbButton, ref text, ref ipWindowHandle); 

     } 

     foreach (var item in texts) 
     { 
      Console.WriteLine(item); 
     } 
    } 
} 

은 어떤 방법이 트레이 :에있는 아이콘의 툴팁을 알고하는 방법을 발견했다 마우스 오른쪽 버튼으로 클릭 C#을 사용 트레이 아이콘을 onsystem? 답변에 감사드립니다 .......

답변

3

다른 프로그램의 트레이 아이콘 (출처 : Raymond Chen)에 액세스하는 프로그램 방식은 없습니다. 당신이 시도하는 것은 망가 뜨리거나 망가뜨릴 수있는 해킹 일뿐입니다.

트레이 아이콘의 오른쪽 클릭을 자동화 할 필요가없는 방법을 찾으십시오. 어쩌면 문제의 프로그램은 API 또는 명령 줄 매개 변수를 통해 제어 할 수 있습니다.

+0

특히 트레이가 시각적으로 그 자체를 새로 고침하지 않기 때문에. – kenny

+0

그리고 실제로 Windows 7 사용자가이 응용 프로그램의 아이콘을 전혀 표시하지 않도록 알림 영역을 사용자 정의한 경우 ... – AakashM

+0

이 자동화 프레임 워크를 실행하고 사용자가 수행하는 아이콘 트레이에서 오른쪽 클릭으로 시나리오를 테스트하려고합니다. C#에서는 WINAPI32를 사용할 수 있다고 생각했습니다. –

관련 문제