سؤال

أحاول ربط تطبيق تابع لجهة خارجية حتى أتمكن من الرسم على شاشته.يعد الرسم على الشاشة أمرًا سهلاً، ولا أحتاج إلى مساعدة فيه، ولكن يبدو أن لدي مشكلات في الاستخدام SetWindowsHookEx لكي يعلق WH_GETMESSAGE.لا أستطيع معرفة ما يجب تمريره للمعلمتين الأخيرتين.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowDrawer
{
    public partial class Form1 : Form
    {
        private delegate int HookProc(int code, IntPtr wParam, IntPtr lParam);
        static IntPtr hHook;
        IntPtr windowHandle;
        uint processHandle;

        HookProc PaintHookProcedure;     

        [System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
        static extern System.IntPtr FindWindowByCaption(int ZeroOnly, string lpWindowName);

        [System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint = "SetWindowsHookEx", SetLastError = true)]
        static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, uint dwThreadId);

        [System.Runtime.InteropServices.DllImport("user32.dll")]
        static extern int CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

        // When you don't want the ProcessId, use this overload and pass IntPtr.Zero for the second parameter
        [System.Runtime.InteropServices.DllImport("user32.dll")]
        static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

        [System.Runtime.InteropServices.DllImport("kernel32.dll", CharSet =System.Runtime.InteropServices.CharSet.Auto)]
        public static extern IntPtr GetModuleHandle(string lpModuleName);

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        { 
            PaintHookProcedure = new HookProc(PaintHookProc);
            windowHandle = FindWindowByCaption(0, "Untitled - Notepad");
            uint threadID = GetWindowThreadProcessId(windowHandle, out processHandle);
            IntPtr hMod = System.Runtime.InteropServices.Marshal.GetHINSTANCE(typeof(Form1).Module);

            // HERE IS THE PROBLEM.  WHAT THE HECK DO I PASS INTO THE LAST 2 PARAMS?  I get a null pointer
            hHook = SetWindowsHookEx(WH_GETMESSAGE, PaintHookProcedure, hMod, threadID);
        }

        public int PaintHookProc(int nCode, IntPtr wParam, IntPtr lParam)
        {
           // Do some painting here.
            return CallNextHookEx(hHook, nCode, wParam, lParam); 
        }

        private const int WM_PAINT = 15;
        private const int WH_GETMESSAGE = 3;
    }
}
هل كانت مفيدة؟

المحلول

SetWindowsHookEx يحدد المعلمتين الأخيرتين على النحو التالي:

  • hMod

في] التعامل مع DLL التي تحتوي على إجراء الخطاف الذي أشار إليه المعلمة LPFN.يجب تعيين معلمة HMOD على NULL إذا كانت المعلمة DWTHreadID تحدد مؤشر ترابط تم إنشاؤه بواسطة العملية الحالية وإذا كان إجراء الخطاف ضمن الكود المرتبط بالعملية الحالية.

  • dwThreadId

في] يحدد معرف الخيط الذي يرتبط به إجراء الخطاف.إذا كانت هذه المعلمة صفرًا ، يرتبط إجراء الخطاف بجميع مؤشرات الترابط الموجودة في نفس سطح المكتب مثل مؤشر ترابط الاتصال.

لست متأكدًا من قدرتك على استخدام ملف .NET dll بالطريقة المطلوبة، ولكن يمكنك بالتأكيد المحاولة.

يمسك hMod عبر Marshal.GetHINSTANCE(typeof(Form1).Module) و dwThreadId عبر العملية. المواضيع.بدلا من ذلك، تعيين dwThreadId إلى 0 إذا كنت تريد ربطًا عالميًا (على سبيل المثال.خطاف للجميع GetMessage() المكالمات في سطح المكتب الحالي) ولكن احذر من عقوبات الأداء.

نصائح أخرى

وفيما يلي يوحي هذا لن ينجح:

<اقتباس فقرة>   

و"غير معتمدة السنانير العالمية في .NET Framework. باستثناء هوك على مستوى منخفض WH_KEYBOARD_LL وربط على مستوى منخفض WH_MOUSE_LL، لا يمكنك تنفيذ السنانير العالمية في برنامج Microsoft .NET Framework."

"كيفية تعيين ربط Windows في Visual C # .NET"

وأعتقد أنك بحاجة إلى P / استدعاء GetModuleHandle و استخدام مقبض فإنه يعود للمعلمة الثالثة من SetWindowsHookEx. وأعتقد أيضا 0 غير صحيحة للمعلمة الرابعة، كما كنت لا ترغب في ربط أي موضوع واحد محدد في تطبيق طرف ثالث.

إذا لم ينجح هذا الإجراء بالنسبة لك، SetWindowsHookEx على MSDN قد توجيهك في الاتجاه الصحيح.

وأنا لا أعرف ولكن إذا كنت تستخدم القيم المعلمة التي تحدد الذي تريد، كما يساعد API يقول: "حقن DLL إلى عملية أخرى"، ثم لجميع وأنا أعلم أنه قد تعمل فقط إذا كنت أكتب وDLL غير المدارة من خلالها يطلق عليه.

وأنا أعلم أن هذا هو السؤال القديم ولكن أنا على أمل أنه ما زال هناك شخص سوف تجد هذا مفيدا. أعتقد أنك الخلط int وIntPtr

[System.Runtime.InteropServices.DllImport("user32.dll")]
static extern int CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

وهذا العمل بالنسبة لي استخدام 13 ...

 private static IntPtr SetHook(LowLevelKeyboardProc proc)
        {
            using (Process curProcess = Process.GetCurrentProcess())
            using (ProcessModule curModule = curProcess.MainModule)
            {
                return SetWindowsHookEx(13, proc,
                GetModuleHandle(curModule.ModuleName), 0);
            }
        }
  internal enum HookType : uint {
    WH_JOURNALRECORD = 0,
    WH_JOURNALPLAYBACK = 1,
    WH_KEYBOARD = 2,
    WH_GETMESSAGE = 3,
    WH_CALLWNDPROC = 4,
    WH_CBT = 5,
    WH_SYSMSGFILTER = 6,
    WH_MOUSE = 7,
    WH_HARDWARE = 8,
    WH_DEBUG = 9,
    WH_SHELL = 10,
    WH_FOREGROUNDIDLE = 11,
    WH_CALLWNDPROCRET = 12,
    WH_KEYBOARD_LL = 13,
    WH_MOUSE_LL = 14
  }

الخطافات العمومية غير مدعومة في .NET Framework

باستثناء الخطاف منخفض المستوى WH_KEYBOARD_LL والربط منخفض المستوى WH_MOUSE_LL، لا يمكنك تطبيق الخطافات العمومية في Microsoft .NET Framework.

لتثبيت خطاف عام، يجب أن يحتوي الخطاف على تصدير DLL أصلي لإدخال نفسه في عملية أخرى تتطلب وظيفة صالحة ومتسقة للاتصال بها.يتطلب هذا السلوك تصدير DLL.

لا يدعم .NET Framework عمليات تصدير DLL.لا تحتوي التعليمات البرمجية المُدارة على مفهوم لقيمة ثابتة لمؤشر الوظيفة لأن مؤشرات الوظائف هذه عبارة عن وكلاء تم إنشاؤها ديناميكيًا.

يتم استدعاء إجراءات الربط ذات المستوى المنخفض على الخيط الذي قام بتثبيت الخطاف.لا تتطلب الخطافات ذات المستوى المنخفض تنفيذ إجراء الربط في ملف DLL.

أنظر أيضا:تجسس - أداة التجسس WPF

أو WPF الخاص بي => WF => Win32 LL_Keyboard Hook Proxy مع الإيماءات

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top