码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2015-06-15 18:38:39      阅读:112      评论:0      收藏:0      [点我收藏+]

标签:

这个程序主要还是靠钩子实现,然后利用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();
        }
    }
}

 

 

 

 

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

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

标签:

原文地址:http://www.cnblogs.com/my-project1/p/4578685.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!