示例#1
0
 private static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, ref TBBUTTONINFOW lpBuffer, IntPtr nSize, out IntPtr lpNumberOfBytesRead);
示例#2
0
    public static List <string> ScanToolbarButtons()
    {
        List <string> tooltips = new List <string>();
        var           handle   = GetSystemTrayHandle();

        if (handle == IntPtr.Zero)
        {
            return(null);
        }
        var count = SendMessage(handle, TB_BUTTONCOUNT, IntPtr.Zero, IntPtr.Zero).ToInt32();

        if (count == 0)
        {
            return(null);
        }
        GetWindowThreadProcessId(handle, out var pid);
        var hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pid);

        if (hProcess == IntPtr.Zero)
        {
            throw new Win32Exception(Marshal.GetLastWin32Error());
        }
        var size   = (IntPtr)Marshal.SizeOf <TBBUTTONINFOW>();
        var buffer = VirtualAllocEx(hProcess, IntPtr.Zero, size, MEM_COMMIT, PAGE_READWRITE);

        if (buffer == IntPtr.Zero)
        {
            CloseHandle(hProcess);
            throw new Win32Exception(Marshal.GetLastWin32Error());
        }
        for (int i = 0; i < count; i++)
        {
            var btn = new TBBUTTONINFOW();
            btn.cbSize = size.ToInt32();
            btn.dwMask = TBIF_BYINDEX | TBIF_COMMAND;
            if (WriteProcessMemory(hProcess, buffer, ref btn, size, out var written))
            {
                // we want the identifier
                var res = SendMessage(handle, TB_GETBUTTONINFOW, (IntPtr)i, buffer);
                if (res.ToInt32() >= 0)
                {
                    if (ReadProcessMemory(hProcess, buffer, ref btn, size, out var read))
                    {
                        // now get display text using the identifier
                        // first pass we ask for size
                        var textSize = SendMessage(handle, TB_GETBUTTONTEXTW, (IntPtr)btn.idCommand, IntPtr.Zero);
                        if (textSize.ToInt32() != -1)
                        {
                            // we need to allocate for the terminating zero and unicode
                            var utextSize  = (IntPtr)((1 + textSize.ToInt32()) * 2);
                            var textBuffer = VirtualAllocEx(hProcess, IntPtr.Zero, utextSize, MEM_COMMIT, PAGE_READWRITE);
                            if (textBuffer != IntPtr.Zero)
                            {
                                res = SendMessage(handle, TB_GETBUTTONTEXTW, (IntPtr)btn.idCommand, textBuffer);
                                if (res == textSize)
                                {
                                    var localBuffer = Marshal.AllocHGlobal(utextSize.ToInt32());
                                    if (ReadProcessMemory(hProcess, textBuffer, localBuffer, utextSize, out read))
                                    {
                                        var text = Marshal.PtrToStringUni(localBuffer);
                                        tooltips.Add(text);
                                    }
                                    Marshal.FreeHGlobal(localBuffer);
                                }
                                VirtualFreeEx(hProcess, textBuffer, IntPtr.Zero, MEM_RELEASE);
                            }
                        }
                    }
                }
            }
        }
        VirtualFreeEx(hProcess, buffer, IntPtr.Zero, MEM_RELEASE);
        CloseHandle(hProcess);
        return(tooltips);
    }