2011-08-23 32 views
5

Tôi muốn viết khuôn khổ tự động hóa cho ứng dụng .NET. Để bắt đầu người dùng ứng dụng nên nhấp chuột phải vào biểu tượng trong khay hệ thống và chọn tùy chọn từ trình đơn ngữ cảnh. Tôi đã thực hiện một số resaerch và chỉ tìm thấy cách làm thế nào để biết tooltip của biểu tượng trong khay .:Cách tự động nhấp chuột phải vào biểu tượng trong khay hệ thống bằng cách sử dụng 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ó cách nào để kích chuột phải vào biểu tượng trên khay onsystem sử dụng C#? Xin cảm ơn câu trả lời .......

Trả lời

3

Không có cách nào có lập trình để truy cập vào biểu tượng khay của các chương trình khác (nguồn: Raymond Chen). Bất cứ điều gì bạn cố gắng là gì, nhưng một hack có khả năng phá vỡ và thất bại.

Cố gắng tìm cách không liên quan đến việc phải tự động nhấp chuột phải vào biểu tượng khay. Có lẽ chương trình được đề cập có thể được kiểm soát thông qua một số API hoặc thông qua các tham số dòng lệnh.

+0

đặc biệt vì khay không tự làm mới trực quan. – kenny

+0

và thực sự là gì nếu trên Windows 7 người dùng đã tùy chỉnh khu vực thông báo để không hiển thị biểu tượng của ứng dụng này ... – AakashM

+0

Khung tự động này tôi sẽ chạy và tôi muốn thử nghiệm các tình huống bằng cách bấm phải vào khay biểu tượng khi người dùng thực hiện. Tôi nghĩ rằng bằng cách sử dụng WINAPI32 nó có thể có thể trong C#. –

Các vấn đề liên quan