c#:如何通过挂钩访问写在屏幕上的文本

c#:如何通过挂钩访问写在屏幕上的文本,c#,.net,hook,C#,.net,Hook,我使用挂钩的最终目标是读取外部应用程序接收到的新闻标题,并在我的应用程序中处理这些标题 首先,我一直在尝试访问写入我编写的一个简单控制台应用程序的文本,该应用程序每五秒钟重复输出“我们在xxx号上”,xxx递增 摘自,我使用了下面的代码,关联的指针告诉我发生了变化。但是,我对实际写入的文本感兴趣,当我尝试使用Marshal.ReadIntPtr(hwnd)访问它时,我得到一个System.AccessViolationException:尝试读取或写入受保护的内存… 以下是目前仅次于敬虔的准则、

我使用挂钩的最终目标是读取外部应用程序接收到的新闻标题,并在我的应用程序中处理这些标题

首先,我一直在尝试访问写入我编写的一个简单控制台应用程序的文本,该应用程序每五秒钟重复输出“我们在xxx号上”,xxx递增

摘自,我使用了下面的代码,关联的指针告诉我发生了变化。但是,我对实际写入的文本感兴趣,当我尝试使用
Marshal.ReadIntPtr(hwnd)
访问它时,我得到一个
System.AccessViolationException:尝试读取或写入受保护的内存…

以下是目前仅次于敬虔的准则、解释或帮助:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace testsAndSamples_hookingWinEvents
{
    class Program
    {
        delegate void WinEventDelegate(IntPtr hWinEventHook, uint eventType,
            IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime);

        [DllImport("user32.dll")]
        static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr
           hmodWinEventProc, WinEventDelegate lpfnWinEventProc, uint idProcess,
           uint idThread, uint dwFlags);

        [DllImport("user32.dll")]
        static extern bool UnhookWinEvent(IntPtr hWinEventHook);

        const uint EVENT_OBJECT_NAMECHANGE = 0x800C;
        const uint WINEVENT_OUTOFCONTEXT = 0;

        // Need to ensure delegate is not collected while we're using it,
        // storing it in a class field is simplest way to do this.
        static WinEventDelegate procDelegate = new WinEventDelegate(WinEventProc);

        public static void Main()
        {
            // Listen for name change changes across all processes/threads on current desktop...
            IntPtr hhook = SetWinEventHook(EVENT_OBJECT_NAMECHANGE, EVENT_OBJECT_NAMECHANGE, IntPtr.Zero,
                    procDelegate, 0, 0, WINEVENT_OUTOFCONTEXT);

            // MessageBox provides the necessary mesage loop that SetWinEventHook requires.
            // In real-world code, use a regular message loop (GetMessage/TranslateMessage/
            // DispatchMessage etc or equivalent.)
            MessageBox.Show("hooked");

            UnhookWinEvent(hhook);
        }

        static void WinEventProc(IntPtr hWinEventHook, uint eventType,
            IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
        {
            // filter out non-HWND namechanges... (eg. items within a listbox)
            if (idObject != 0 || idChild != 0)
            {
                return;
            }
            // this doesn't work:
            var hey = Marshal.ReadIntPtr(hwnd);

            Console.WriteLine("Text of hwnd changed {0:x8}", hwnd.ToInt32());
        }
    }

}

HWND是一个不透明的指针,即您不直接读取内存位置,而是使用适当的Win32 API方法。如果注释掉Marshal.ReadIntPtr(hwnd),您是否看到控制台输出的“hwnd文本已更改…”的非零值?是的。我相信它是十六进制的,表示为(数字)x(更多数字),所以这个异常是因为您试图读取指针位置。相反,您将需要查看其他win API方法,这些方法可能会告诉您有关该窗口句柄的信息。是否有关于查找位置的建议?可能需要查看winspy或API monitor来调查包含文本的内容等。您对正在调查的应用程序了解得不够。您可能需要探索其他选项,如API挂钩(例如,截取绘图文本命令或类似命令-API监视器应有助于缩小选项范围)。