钩子程序利用ManuResetEvent同步控制线程

这个程序主要还是靠钩子实现,然后利用manuResetEvent同步控制关机线程 。关机线程用重定向实现

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace magic
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            this.ShowInTaskbar = false;
            this.WindowState = FormWindowState.Minimized;
    
        }

private const int WM_KEYDOWN = 0x100;
        private const int WM_KEYUP = 0x101;
        private const int WM_SYSKEYDOWN = 0x104;
        private const int WM_SYSKEYUP = 0x105;
        private const int VK_SNAPSHOT = 0x2C;
        //全局的事件
        static int hKeyboardHook = 0; //键盘钩子句柄
        //鼠标常量
        public const int WH_KEYBOARD_LL = 13; //keyboard hook constant
        HookProc KeyboardHookProcedure; //声明键盘钩子回调事件.
        Process process = new Process();
        //声明键盘钩子的封送结构类型
        [StructLayout(LayoutKind.Sequential)]
        public class KeyboardHookStruct
        {
            public int vkCode; //表示一个在 1 到 254 间的虚似键盘码
            public int scanCode; //表示硬件扫描码
            public int fags;
            public int time;
            public int dwExtraInfo;
        }
        //装置钩子的函数
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance,
        int threadId);
        //卸下钩子的函数
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern bool UnhookWindowsHookEx(int idHook);
        //下一个钩挂的函数
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);
        [DllImport("user32")]
        public static extern int ToAscii(int uVirtKey, int uScanCode, byte[] lpbKeyState, byte[]
        lpwTransKey, int fuState);
        [DllImport("user32")]
        public static extern int GetKeyboardState(byte[] pbKeyState);
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        private static extern IntPtr GetModuleHandle(string lpModuleName);
        [DllImport("kernel32.dll")]
        static extern int GetTickCount();
        public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);
        public static ManualResetEvent capture_terminate_e;

private void Start_h()
        {
            //安装键盘钩子
            if (hKeyboardHook == 0)
            {
                KeyboardHookProcedure = new HookProc(KeyboardHookProc);
                Process curProcess = Process.GetCurrentProcess();
                ProcessModule curModule = curProcess.MainModule;
                hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, GetModuleHandle(curModule.ModuleName), 0);
                if (hKeyboardHook == 0)
                {
                    Stop_h();
                    throw new Exception("SetWindowsHookEx is failed.");
                }
            }
        }
        private void Stop_h()
        {
            bool retKeyboard = true;
            if (hKeyboardHook != 0)
            {
                retKeyboard = UnhookWindowsHookEx(hKeyboardHook);
                hKeyboardHook = 0;
            }
            //如果卸下钩子失败
            if (!(retKeyboard)) throw new Exception("UnhookWindowsHookEx failed.");
        }
        private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)//钩子的回调函数。注意回调的特点:1:有循环机制。2:由系统调用
        {
            //lParam 参数只是数据的内存地址
            KeyboardHookStruct MyKeyboardHookStruct =
            (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
            Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
            if (wParam == WM_KEYDOWN || wParam == WM_KEYDOWN)//对截获的消息不做处理,只是同步控制关机线程
            {

capture_terminate_e.Set();
            }
            return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
        }
        public void shoutdown()//关机线程
        {
        
            while (!capture_terminate_e.WaitOne())
            {
                return;
            }
            if(capture_terminate_e.WaitOne(100))
            {
                string strCmd = "shutdown /f /s /t 6000";
                process.StandardInput.WriteLine(strCmd);

}

}

private void Form1_Load(object sender, EventArgs e)//在程序开始就让重定向,钩子,和控制关机的线程跑起来
        {
          
            process.StartInfo.FileName = "cmd.exe";//要打开进程的名字;
            process.StartInfo.UseShellExecute = false;//此处注意一旦重定向一定要设置为fals;
         
            process.StartInfo.CreateNoWindow = true;  // 是否在新窗口中启动该进程的值
          
            process.StartInfo.RedirectStandardInput = true;// 重定向输入流
            process.Start();//重定向进程开始
            Start_h();//设置钩子
            capture_terminate_e = new ManualResetEvent(false);

//关机线程开启
            ThreadStart workStart = new ThreadStart(shoutdown);
            Thread workThread = new Thread(workStart);
            workThread.IsBackground = true;
            workThread.Start();
        }
    }
}

希望大家指点下,指出不足之处

时间: 2024-08-28 15:09:54

钩子程序利用ManuResetEvent同步控制线程的相关文章

java应用死循环排查方法或查找程序消耗资源的线程方法

如果遇到线上应用cpu飙升,并出现OutOfMemery怎么办? 首先线上应用的jvm配置要养成良好的习惯,增加一下配置则可以在jvm发生oom的时候自动dump日志了  -XX:+HeapDumpOnOutOfMemoryError   -XX:HeapDumpPath=/export/log/dump/jvm-oom.log 如果遇到线上应用特别消耗cpu资源怎么去排查? ps:首先普及一下linux中的java虚拟机线程实现方式:在Linux下面因为没有真正的线程,是用进程模拟的,有一个是

程序,进程,线程

   程序   进程  线程学习笔记   定义: 一 程序只是一组指令的有序集合. 二 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,是系统进行资源分配和调度的一个独立单位; 三 线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),一个线程可以创建和撤销另一个线程; 一进程与线程区别与联系 (1) 划分尺度:线程更小,所以多线程程序并发性更高; (

程序、进程、线程区别与联系

定义: 一 程序只是一组指令的有序集合. 二 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,是系统进行资源分配和调度的一个独立单位; 三 线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),一个线程可以创建和撤销另一个线程; 一 进程与线程区别与联系 (1) 划分尺度:线程更小,所以多线程程序并发性更高; (2) 资源分配&处理器调度:进程是资源分

【Android】揭秘如何利用Service与线程制造安卓后台通知栏推送

安卓设备的后台通知栏推送很烦,主要是可以通过利用安卓的Service功能,在app被点击Home键或者返回键之后,依旧可以在挂载后台运行.反正Home键或者返回键只能杀死Activity而不能终结Service的,不像Windows点关闭键默认是关闭程序界面+程序线程. 本文的意义相当于在Windows中制造一条线程,或者是对Windows应用程序的关闭键进行重写,让其应用程序的关闭仅仅是隐藏界面,不杀死进程. 理论上,只要这个Service不被安卓系统因内存不足所回收,会一直持续到设备重启,或

android 上的API函数钩子,利用CydiaHook实现

android 上的API函数钩子,利用CydiaHook实现 发布将近一年了,最近发现还是有些人需要的,github上也有些人fork了. 例子代码,发布在github上,地址:https://github.com/zencodex/cydia-android-hook CydiaHook 利用Cydia Substrate SDK 开发,可以HOOK java层或NATIVE层 API接口. 本代码功能 写代码的初衷是因为有个app,需要保存数据到SD卡上,并且app里面有判断SD挂载的状态

14-08-07 关于程序、进程、线程,以及python中实现多线程的办法

考核题目中涉及到多线程编程,于是复习了一下系统编程里面的各种概念. 首先,程序是代码,没有活动.通过编译连接之后被加载到内存里运行时,内存活动的就是进程,这里的进程不仅仅是代码段,还包括涉及的数据等.而线程是在同一个进程下的小程序,它们可以"同时"地运行,其中会有一个主线程来控制. 接下来是多线程或着多进程的实现,两者原理基本一样,都是把CPU的时间分片然后进行分配给某个进程或者线程,也就是说在同一个时间只会有一个线程在使用CPU,但是CPU切换线程的频率非常快使得它们看上去是在同一个

一个简单的键盘钩子程序

实现适时监视键盘,并将按键信息保存在TXT文件中的程序       Windows系统是建立在事件驱动的机制上的,说穿了就是整个系统都是通过消息的传递来实现的.而钩子是Windows系统中非常重要的系统接口,用它可以截获并处理送给其他应用程序的消息,来完成普通应用程序难以实现的功能.钩子的种类很多,每种钩子可以截获并处理相应的消息,如键盘钩子可以截获键盘消息,外壳钩子可以截取.启动和关闭应用程序的消息等.本文在VC6编程环境下实现了一个简单的键盘钩子程序,并对Win32全局钩子的运行机制.Win

windows 钩子程序

钩子API: 1.UnhookWindowsHookEx(glhHook); 2.SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,glhInstance,0); 一个简单的键盘钩子程序 实现适时监视键盘,并将按键信息保存在TXT文件中的程序       Windows系统是建立在事件驱动的机制上的,说穿了就是整个系统都是通过消息的传递来实现的.而钩子是Windows系统中非常重要的系统接口,用它可以截获并处理送给其他应用程序的消息,来完成普通应用程序难以实现的

程序员过关斩将--自定义线程池来实现文档转码

背景 我司在很久之前,一位很久之前的同事写过一个文档转图片的服务,具体业务如下: 用户在客户端上传文档,可以是ppt,word,pdf 等格式,用户上传完成可以在客户端预览上传的文档,预览的时候采用的是图片形式(不要和我说用别的方式预览,现在已经来不及了) 当用户把文档上传到云端之后(阿里云),把文档相关的信息记录在数据库,然后等待转码完成 服务器有一个转码服务(其实就是一个windows service)不停的在轮训待转码的数据,如果有待转码的数据,则从数据库取出来,然后根据文档的网络地址下载