精华内容
下载资源
问答
  • C#键盘钩子之局部钩子和全局钩子

    千次阅读 2018-05-12 15:46:39
    最近碰巧要使用键盘钩子,于是在网上搜索了一番,发现大多数博客的文章都是雷同的,根本就没有讲清楚全局钩子和局部钩子的区别,于是特开一贴,讲全局钩子和局部钩子捋一捋。也供后面的人学习。 应为大部分应用都...

    最近碰巧要使用键盘钩子,于是在网上搜索了一番,发现大多数博客的文章都是雷同的,根本就没有讲清楚全局钩子和局部钩子的区别,于是特开一贴,讲全局钩子和局部钩子捋一捋。也供后面的人学习。
    因为大部分应用都应该采用局部钩子,所以我这儿使用的是局部钩子,而全局钩子的例子网上到处都是。
    大部分网上参考文章都只是展示了全局钩子的写法,而线程钩子的写法和介绍相对少一些,特别是关键语句上如果定义的不正确是没有任何效果的,在自己反复尝试后决定留下一个正确的版本分享出来
    代码如下

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Reflection;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;
    
    namespace AssistToolSet.Util
    {
        /// <summary>
        /// 键盘钩子类
        /// </summary>
        public class Hook
        {
            public delegate int HookProc(WH_CODE nCode, Int32 wParam, IntPtr lParam);
            public enum WH_CODE : int
            {
                WH_JOURNALRECORD = 0,
                WH_JOURNALPLAYBACK = 1,
                /// <summary>
                /// 进程钩子
                /// </summary>
                WH_KEYBOARD = 2,
    
                /// <summary>
                /// 底层键盘钩子 全局钩子就是用这个
    
                /// </summary>
                WH_KEYBOARD_LL = 13,
            }
    
            public enum HC_CODE : int
            {
                HC_ACTION = 0,
                HC_GETNEXT = 1,
                HC_SKIP = 2,
                HC_NOREMOVE = 3,
                HC_NOREM = 3,
                HC_SYSMODALON = 4,
                HC_SYSMODALOFF = 5
            }
    
            /// <summary>
            /// 安装钩子
            /// </summary>
            [DllImport("user32.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
            public static extern IntPtr SetWindowsHookEx(WH_CODE idHook, HookProc lpfn, IntPtr pInstance, uint threadId);
    
            /// <summary>
            /// 卸载钩子
            /// </summary>
            [DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)]
            public static extern bool UnhookWindowsHookEx(IntPtr pHookHandle);
            /// <summary>
            /// 传递钩子
            /// </summary>
            [DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)]
            public static extern int CallNextHookEx(IntPtr pHookHandle, WH_CODE nCodem, Int32 wParam, IntPtr lParam);
    
            /// <summary>
            /// 获取全部按键状态
            /// </summary>
            /// <param name="pbKeyState"></param>
            /// <returns>非0表示成功</returns>
            [DllImport("user32.dll")]
            public static extern int GetKeyboardState(byte[] pbKeyState);
    
            /// <summary>
            /// 获取程序集模块的句柄
            /// </summary>
            /// <param name="lpModuleName"></param>
            /// <returns></returns>
            [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            public static extern IntPtr GetModuleHandle(string lpModuleName);
    
            /// <summary>
            /// 获取当前进程中的当前线程ID
            /// </summary>
            /// <returns></returns>
            [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
            public static extern uint GetCurrentThreadId();
    
            #region 私有变量
    
            private byte[] mKeyState = new byte[256];
            private Keys mKeyData = Keys.None; //专门用于判断按键的状态
    
            /// <summary>
            /// 键盘钩子句柄
            /// </summary>
            private IntPtr mKetboardHook = IntPtr.Zero;
    
            /// <summary>
            /// 键盘钩子委托实例
            /// </summary>
            private HookProc mKeyboardHookProcedure;
    
            #endregion
    
            #region 键盘事件
    
            public event KeyEventHandler OnKeyDown;
            public event KeyEventHandler OnKeyUp;
    
            #endregion
    
            /// <summary>
            /// 构造函数
            /// </summary>
            public Hook()
            {
                GetKeyboardState(this.mKeyState);
            }
    
            ~Hook()
            {
                UnInstallHook();
            }
    
            /// <summary>
            /// 键盘钩子处理函数
            /// </summary>
            private int KeyboardHookProc(WH_CODE nCode, Int32 wParam, IntPtr lParam)
            {
            /*全局钩子应该这样设定
             KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
            */
                // 定义为线程钩子时,wParam的值是击打的按键,与Keys里的对应按键相同
                if ((nCode == (int)HC_CODE.HC_ACTION) && (this.OnKeyDown != null || this.OnKeyUp != null))
                {
                    mKeyData = (Keys)wParam;
                    KeyEventArgs keyEvent = new KeyEventArgs(mKeyData);
                    //这里简单的通过lParam的值的正负情况与按键的状态相关联
                    if (lParam.ToInt32() > 0 && this.OnKeyDown != null)
                    {
                        this.OnKeyDown(this, keyEvent);
                    }
                    else if (lParam.ToInt32() < 0 && this.OnKeyUp != null)
                    {
                        this.OnKeyUp(this, keyEvent);
                    }
                }
                if (ShortcutManagement.s_bHotkeyUsed)
                {
                    ShortcutManagement.s_bHotkeyUsed = false;
                    return 1;
                }
    
                return CallNextHookEx(this.mKetboardHook, nCode, wParam, lParam);
            }
            /// <summary>
            /// 安装钩子
            /// </summary>
            /// <returns></returns>
            public bool InstallHook()
            {
                //线程钩子时一定要通过这个取得的值才是操作系统下真实的线程
                uint result = GetCurrentThreadId();
    
                if (this.mKetboardHook == IntPtr.Zero)
                {
                    this.mKeyboardHookProcedure = new HookProc(this.KeyboardHookProc);
                    //注册线程钩子时第三个参数是空
                    this.mKetboardHook = SetWindowsHookEx(WH_CODE.WH_KEYBOARD, this.mKeyboardHookProcedure, IntPtr.Zero, result);
                    /*
                    如果是全局钩子应该这样使用
                    this.mKetboardHook = SetWindowsHookEx(WH_CODE.WH_KEYBOARD_LL, mKeyboardHookProcedure,GetModuleHandle(System.Diagnostics.Process.GetCurrentProcess().MainModule.ModuleName), 0);
                    */
                    if (this.mKetboardHook == IntPtr.Zero)
                    {
                        return false;
                    }
                }
                return true;
            }
    
            /// <summary>
            /// 卸载钩子
            /// </summary>
            /// <returns>true表示成功 </returns>
            public bool UnInstallHook()
            {
                bool result = true;
                if (this.mKetboardHook != IntPtr.Zero)
                {
                    result = UnhookWindowsHookEx(this.mKetboardHook) && result;
                    this.mKetboardHook = IntPtr.Zero;
                }
                return result;
            }
        }
    
    }
    

    通过这次认知,意识到,以后如果要做这些接触相关的api的时候,我们应该尽量去查官方文档,而不是一开始就是查看别人的博客。应该以官方文档为主。一定要记住键盘钩子事件。32位和64位的系统不一样。

    展开全文
  • 编写钩子程序的步骤分为三步:定义钩子函数、安装钩子和卸载钩子。 1.定义钩子函数  钩子函数是一种特殊的回调函数。钩子监视的特定事件发生后,系统会调用钩子函数进行处理。不同事件的钩子函数的形式是各不...
  • 免费送了 包含两种钩子程序 键盘钩子和鼠标钩子 需要的朋友可以看看
  • form表单源码解析: 局部钩子: 全局钩子: 转载于:https://www.cnblogs.com/zhangsanfeng/p/9240855.html

     

    form表单源码解析:

     

    局部钩子:

     

     

     

    全局钩子:

     

     

     

    转载于:https://www.cnblogs.com/zhangsanfeng/p/9240855.html

    展开全文
  • 最近碰巧要使用键盘钩子,于是在网上搜索了一番,发现大多数博客的文章都是雷同的,根本就没有讲清楚全局钩子和局部钩子的区别,于是特开一贴,讲全局钩子和局部钩子捋一捋。也供后面的人学习。 因为大部分应用都...

    源自:https://blog.csdn.net/programvae/article/details/80292076

    最近碰巧要使用键盘钩子,于是在网上搜索了一番,发现大多数博客的文章都是雷同的,根本就没有讲清楚全局钩子和局部钩子的区别,于是特开一贴,讲全局钩子和局部钩子捋一捋。也供后面的人学习。
       因为大部分应用都应该采用局部钩子,所以我这儿使用的是局部钩子,而全局钩子的例子网上到处都是。
       大部分网上参考文章都只是展示了全局钩子的写法,而线程钩子的写法和介绍相对少一些,特别是关键语句上如果定义的不正确是没有任何效果的,在自己反复尝试后决定留下一个正确的版本分享出来
      
      代码如下

     

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Reflection;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;
    
    namespace AssistToolSet.Util
    {
        /// <summary>
        /// 键盘钩子类
        /// </summary>
        public class Hook
        {
            public delegate int HookProc(WH_CODE nCode, Int32 wParam, IntPtr lParam);
            public enum WH_CODE : int
            {
                WH_JOURNALRECORD = 0,
                WH_JOURNALPLAYBACK = 1,
                /// <summary>
                /// 进程钩子
                /// </summary>
                WH_KEYBOARD = 2,
    
                /// <summary>
                /// 底层键盘钩子 全局钩子就是用这个
    
                /// </summary>
                WH_KEYBOARD_LL = 13,
            }
    
            public enum HC_CODE : int
            {
                HC_ACTION = 0,
                HC_GETNEXT = 1,
                HC_SKIP = 2,
                HC_NOREMOVE = 3,
                HC_NOREM = 3,
                HC_SYSMODALON = 4,
                HC_SYSMODALOFF = 5
            }
    
            /// <summary>
            /// 安装钩子
            /// </summary>
            [DllImport("user32.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
            public static extern IntPtr SetWindowsHookEx(WH_CODE idHook, HookProc lpfn, IntPtr pInstance, uint threadId);
    
            /// <summary>
            /// 卸载钩子
            /// </summary>
            [DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)]
            public static extern bool UnhookWindowsHookEx(IntPtr pHookHandle);
            /// <summary>
            /// 传递钩子
            /// </summary>
            [DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)]
            public static extern int CallNextHookEx(IntPtr pHookHandle, WH_CODE nCodem, Int32 wParam, IntPtr lParam);
    
            /// <summary>
            /// 获取全部按键状态
            /// </summary>
            /// <param name="pbKeyState"></param>
            /// <returns>非0表示成功</returns>
            [DllImport("user32.dll")]
            public static extern int GetKeyboardState(byte[] pbKeyState);
    
            /// <summary>
            /// 获取程序集模块的句柄
            /// </summary>
            /// <param name="lpModuleName"></param>
            /// <returns></returns>
            [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            public static extern IntPtr GetModuleHandle(string lpModuleName);
    
            /// <summary>
            /// 获取当前进程中的当前线程ID
            /// </summary>
            /// <returns></returns>
            [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
            public static extern uint GetCurrentThreadId();
    
            #region 私有变量
    
            private byte[] mKeyState = new byte[256];
            private Keys mKeyData = Keys.None; //专门用于判断按键的状态
    
            /// <summary>
            /// 键盘钩子句柄
            /// </summary>
            private IntPtr mKetboardHook = IntPtr.Zero;
    
            /// <summary>
            /// 键盘钩子委托实例
            /// </summary>
            private HookProc mKeyboardHookProcedure;
    
            #endregion
    
            #region 键盘事件
    
            public event KeyEventHandler OnKeyDown;
            public event KeyEventHandler OnKeyUp;
    
            #endregion
    
            /// <summary>
            /// 构造函数
            /// </summary>
            public Hook()
            {
                GetKeyboardState(this.mKeyState);
            }
    
            ~Hook()
            {
                UnInstallHook();
            }
    
            /// <summary>
            /// 键盘钩子处理函数
            /// </summary>
            private int KeyboardHookProc(WH_CODE nCode, Int32 wParam, IntPtr lParam)
            {
            /*全局钩子应该这样设定
             KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
            */
                // 定义为线程钩子时,wParam的值是击打的按键,与Keys里的对应按键相同
                if ((nCode == (int)HC_CODE.HC_ACTION) && (this.OnKeyDown != null || this.OnKeyUp != null))
                {
                    mKeyData = (Keys)wParam;
                    KeyEventArgs keyEvent = new KeyEventArgs(mKeyData);
                    //这里简单的通过lParam的值的正负情况与按键的状态相关联
                    if (lParam.ToInt32() > 0 && this.OnKeyDown != null)
                    {
                        this.OnKeyDown(this, keyEvent);
                    }
                    else if (lParam.ToInt32() < 0 && this.OnKeyUp != null)
                    {
                        this.OnKeyUp(this, keyEvent);
                    }
                }
                if (ShortcutManagement.s_bHotkeyUsed)
                {
                    ShortcutManagement.s_bHotkeyUsed = false;
                    return 1;
                }
    
                return CallNextHookEx(this.mKetboardHook, nCode, wParam, lParam);
            }
            /// <summary>
            /// 安装钩子
            /// </summary>
            /// <returns></returns>
            public bool InstallHook()
            {
                //线程钩子时一定要通过这个取得的值才是操作系统下真实的线程
                uint result = GetCurrentThreadId();
    
                if (this.mKetboardHook == IntPtr.Zero)
                {
                    this.mKeyboardHookProcedure = new HookProc(this.KeyboardHookProc);
                    //注册线程钩子时第三个参数是空
                    this.mKetboardHook = SetWindowsHookEx(WH_CODE.WH_KEYBOARD, this.mKeyboardHookProcedure, IntPtr.Zero, result);
                    /*
                    如果是全局钩子应该这样使用
                    this.mKetboardHook = SetWindowsHookEx(WH_CODE.WH_KEYBOARD_LL, mKeyboardHookProcedure,GetModuleHandle(System.Diagnostics.Process.GetCurrentProcess().MainModule.ModuleName), 0);
                    */
                    if (this.mKetboardHook == IntPtr.Zero)
                    {
                        return false;
                    }
                }
                return true;
            }
    
            /// <summary>
            /// 卸载钩子
            /// </summary>
            /// <returns>true表示成功 </returns>
            public bool UnInstallHook()
            {
                bool result = true;
                if (this.mKetboardHook != IntPtr.Zero)
                {
                    result = UnhookWindowsHookEx(this.mKetboardHook) && result;
                    this.mKetboardHook = IntPtr.Zero;
                }
                return result;
            }
        }
    
    }
    --------------------- 
    作者:PGEva 
    来源:CSDN 
    原文:https://blog.csdn.net/programvae/article/details/80292076 
    版权声明:本文为博主原创文章,转载请附上博文链接!
    View Code

     

     

    通过这次认知,意识到,以后如果要做这些接触相关的api的时候,我们应该尽量去查官方文档,而不是一开始就是查看别人的博客。应该以官方文档为主。一定要记住键盘钩子事件。

    32位和64位的系统不一样。

    转载于:https://www.cnblogs.com/kuangwong/p/10292680.html

    展开全文
  • 自定义钩子分为:项目钩子和全局钩子 自定义全局钩子: 全局钩子目录结构: (注意:excludes目录结构是我们自定义的目录,规则逻辑在update.d/update.py脚本里实现的,非gitlab官方提供功能) /opt/gitlab/...

    钩子介绍

    自定义钩子分为:项目钩子和全局钩子

    自定义全局钩子:

    全局钩子目录结构:

    (注意:excludes目录结构是我们自定义的目录,规则逻辑在update.d/update.py脚本里实现的,非gitlab官方提供功能)

    /opt/gitlab/embedded/service/gitlab-shell/custom_hooks
                                                                                 ├── excludes
                                                                                 │            └── excludes.txt
                                                                                 └── update.d
                                                                                               └── update.py

    钩子目录:

    自定全局钩子目录: /opt/gitlab/embedded/service/gitlab-shell/custom_hooks  ,其中 update.d/update.py  是我们自定义的钩子脚本, 脚本使用python语言。

    如何扩展和修改全局钩子指定目录?

    1.修改 /etc/gitlab/gitlab.rb  配置文件中的配置项:gitlab_shell['custom_hooks_dir'] = "/opt/gitlab/embedded/service/gitlab-shell/custom_hooks"

    2. 执行 sudo gitlab-ctl reconfigure 命令来使配置生效。

     

         Tips:不要尝试直接修改 <gitlab-shell>/config.yml 的文件内容,文件中有说明: 
         This file is managed by gitlab-ctl. Manual changes will be erased! To change the contents below, edit /etc/gitlab/gitlab.rb and runsudo gitlab-ctl reconfigure.

    3.在自定的 custom_hooks_dir 目录(即我们的custom_hooks目录)下可创建三个文件夹对应三类 server hook name :

      • pre-receive.d
      • update.d
      • post-receive.d
    • 在每个文件夹下可创建任意文件,在对应的 hook 时期,gitlab 就会主动调用
    • 文件名以 ~ 结尾的文件会被忽略
    • 如果想看这部分的实现细节可以看 <gitlab-shell>/lib/gitlab_custom_hook.rb 文件

    如何对单个项目排除全局钩子?

    在 /opt/gitlab/embedded/service/gitlab-shell/custom_hooks/excludes/excludes.txt   文件中新加一行你要排除的git的地址即可:例如: https://git.test.abc/example.git 。 (该功能是自定义实现的,非官方提供)

    自定义项目钩子

    项目钩子的目录为固定目录:

    <project>.git/custom_hooks/   例如我们的项目自定义目录为: /var/opt/gitlab/git-data/repositories/frontend/testWeb.git/custom_hooks/update   ,update是我们自定义的钩子脚本。

     

    钩子的执行顺序

    钩子将按照以下的顺序执行

    1. <project>.git/hooks/ - symlink to gitlab-shell/hooks global dir
    2. <project>.git/hooks/<hook_name> - executed by git itself, this is gitlab-shell/hooks/<hook_name>
    3. <project>.git/custom_hooks/<hook_name> - per project hook (this is already existing behavior)
    4. <project>.git/custom_hooks/<hook_name>.d/* - per project hooks
    5. <project>.git/hooks/<hook_name>.d/* OR <custom_hooks_dir>/<hook_name.d>/* - global hooks: all executable files (minus editor backup files)

    钩子校验规则

    1、提交合并代码到test分支前,需要先合并代码到dev验证通过后方能push到test

    2、提交合并代码到master分支前,需要先合并代码到dev、test验证通过后方能push到master

    3、不同分支不能相互合并(如果需要合并,请合并后删除一个不需要的分支方能提交)

    4、合并代码到dev、test、master,merge过程出错了怎么办?

    可以直接在dev、test、master分支上修改代码,但是需要在备注comment里填写FIX_MERGE_ERROR 就可以直接提交(但请不要正常的代码也使用这个命令!!!!!否则后果很严重)

     

    git钩子原理

    在编写钩子的过程中发现钩子原理如下:

    1.gitlab默认安装完毕后在server端会有两个比较重要的目录。

    <project>.git 目录例如:/var/opt/gitlab/git-data/repositories/test/automation.git (我们称这个目录为git的project) 目录树结构如下:

    ├── branches
    ├── config
    ├── description
    ├── HEAD
    ├── hooks -> /opt/gitlab/embedded/service/gitlab-shell/hooks    
    ├── hooks.old.1500269284
    │   ├── applypatch-msg.sample
    │   ├── commit-msg.sample
    │   ├── post-update.sample
    │   ├── pre-applypatch.sample
    │   ├── pre-commit.sample
    │   ├── prepare-commit-msg.sample
    │   ├── pre-push.sample
    │   ├── pre-rebase.sample
    │   ├── pre-receive.sample
    │   └── update.sample
    ├── info
    │   └── exclude
    ├── objects
    │   ├── info
    │   └── pack
    └── refs
    ├── heads
    └── tags

    这个目录结构和git本地项目.git 的目录结构相似。目录中保存了git操作相关的版本信息。在git本地修改的元数据信息提交后都会保存在该目录中。

    /opt/gitlab/embedded/service/gitlab-shell/hooks

    改目录是git默认钩子的目录。在git的低版本( GitLab 8.15.以下)中扩展全局钩子可以该目录的hooks目录中直接修改或新加,但是可能影响到原有的钩子,因此不建议使用,推荐方式见本章1.3 如何修改全局钩子。

    2.git 钩子的脚本代码中:  0 正常退出,用户可以 push;非 0 异常退出,中断提交(pre-receive 和 update)

    3.通过本人研究发下,钩子(脚本中调用的shell的命令)其实是在server端的 <project>.git  git目录 执行的。举例:当执行automation项目的全局钩子时钩子内执行的shell命令会在/var/opt/gitlab/git-data/repositories/test/automation.git 目录中执行,可以通过在钩子中pwd来打印当前钩子的执行目录发现的。

     

    钩子的python代码:

      1 #!/usr/bin/env python
      2 # coding=utf-8
      3 '''
      4 该脚本在pre-receive或post-receive钩子中被调用,也可以直接将该文件作为git的钩子使用
      5 若钩子为shell脚本,则需要加入以下代码调用该脚本:
      6 while read line;do
      7         echo $line | python $PATH/pre-receive.py
      8 done
      9 当用户执行git push的时候会在远程版本库上触发此脚本
     10 该脚本的主要作用:获取用户提交至版本库的文件列表,提交者及时间信息
     11 '''
     12 
     13 import sys, subprocess
     14 import re
     15 import os
     16 
     17 __author__ = "zhanghuiwen"
     18 excludPath ="/opt/gitlab/embedded/service/gitlab-shell/custom_hooks/excludes/excludes.txt";
     19 baseGitUrl="http://172.26.0.80:8081"
     20 
     21 
     22 class Trigger(object):
     23 
     24 
     25     def __init__(self):
     26         '''
     27         初始化文件列表信息,提交者信息,提交时间,当前操作的分支
     28         '''
     29         self.pushAuthor = ""
     30         self.pushTime = ""
     31         self.fileList = []
     32         self.ref = ""
     33 
     34 
     35 
     36     def __getGitInfo(self):
     37         '''
     38         '''
     39         self.oldObject = sys.argv[2]
     40         self.newObject = sys.argv[3]
     41         self.ref = sys.argv[1]
     42 
     43     # 跳过排除的项目
     44     def _skipExcludeProjects_(self):
     45         '''
     46          跳过扫描的项目
     47         '''
     48         rev = subprocess.Popen("pwd", shell=True, stdout=subprocess.PIPE);
     49         gitServerRepoPath = rev.stdout.readline();  # 路径'/var/opt/gitlab/git-data/repositories/alpha/testhook.git'
     50         paths = gitServerRepoPath.split("repositories");
     51         projectPath = paths[1];  # /alpha/testhook.git
     52         rev.stdout.close();
     53 
     54         # 读取配置中的文件
     55         lines = open(excludPath, "r");
     56         for line in lines:
     57             realLine = line.strip("\n");
     58             result = realLine.replace(baseGitUrl,"")
     59             if projectPath.strip(" ").strip("\n") == result.strip(" ").strip("\n"):
     60                 lines.close()
     61                 print ("例外项目允许不经过dev和test直接提交")
     62                 exit(0)
     63             else:
     64                 pass
     65         lines.close()
     66         # 继续执行
     67 
     68     def __getPushInfo(self):
     69         '''
     70         git show命令获取push作者,时间,以及文件列表
     71         文件的路径为相对于版本库根目录的一个相对路径
     72         '''
     73         rev = subprocess.Popen('git rev-list ' + self.oldObject + '..' + self.newObject, shell=True,
     74                                stdout=subprocess.PIPE)
     75         pushList = rev.stdout.readlines()
     76         pushList = [x.strip() for x in pushList]
     77         # 循环获取每次提交的文件列表
     78         for pObject in pushList:
     79             p = subprocess.Popen('git show ' + pObject, shell=True, stdout=subprocess.PIPE)
     80             pipe = p.stdout.readlines()
     81             pipe = [x.strip() for x in pipe]
     82             self.pushAuthor = pipe[1].strip("Author:").strip()
     83             self.pushTime = pipe[2].strip("Date:").strip()
     84 
     85             self.fileList.extend(['/'.join(fileName.split("/")[1:]) for fileName in pipe if
     86                                   fileName.startswith("+++") and not fileName.endswith("null")])
     87 
     88         uBranch = self.ref.split('/')[len(self.ref.split('/')) - 1]
     89         print '提交分支:  %s' % uBranch
     90         print '提交变动from:%s to:%s' % (self.oldObject, self.newObject)
     91         print '提交的commit:%s' % pushList
     92         # if uBranch == 'dev':
     93         #    return
     94         # 循环获取每次提交的文件列表
     95         for pObject in pushList:
     96             # 判断是否是merge commit,如果是merge commit则忽略
     97             gitCatFileCmd = ('git cat-file -p %s') % (pObject)
     98             p = subprocess.Popen(gitCatFileCmd, shell=True, stdout=subprocess.PIPE)
     99             pipe = p.stdout.readlines()
    100             pipe = [x.strip() for x in pipe]
    101             i = 0
    102             for branch in pipe:
    103                 if branch.startswith('parent '):
    104                     i += 1
    105             if i >= 2:
    106                 continue
    107 
    108             # 如果提交的带上的msg是FIX_MERGE_ERROR则可以通行(避免合错分支引起的问题)
    109             msgLine = pipe[-1]
    110             print msgLine
    111             if msgLine == 'FIX_MERGE_ERROR':
    112                 continue
    113                 # if not re.match(r'^(\w+)-(\d+)', msgLine):
    114                 #       print '\033[1;35m %s 提交的信息没有带上jira编号,请确认添加 \033[0m' % pObject
    115                 #       exit(-1)
    116             listCmd = ('git branch --contains %s') % (pObject)
    117             p = subprocess.Popen(listCmd, shell=True, stdout=subprocess.PIPE)
    118             pipe = p.stdout.readlines()
    119             pipe = [x.strip() for x in pipe]
    120             print 'commit:%s->所属分支:%s' % (pObject, pipe)
    121             # 如果是master分支push提交,必须先提交dev、test
    122             if 'master' == uBranch:
    123                 if 'dev' not in pipe or 'test' not in pipe:
    124                     print '\033[1;35m 合并到master的分支必须先在dev、test上经过验证合并才能提交,具体错误提交的hash:%s \033[0m' % pObject
    125                     exit(-1)
    126             elif 'test' == uBranch:
    127                 if 'dev' not in pipe:
    128                     print '\033[1;35m 合并到test的分支必须先在dev上经过验证合并才能提交,具体错误提交的hash:%s \033[0m' % pObject
    129                     exit(-1)
    130             branchs = set()
    131             isMaster = True
    132             for branch in pipe:
    133                 branch = branch.replace('* ', '')
    134                 if 'master' == branch:
    135                     isMaster = False
    136                     break
    137                 if 'test' == branch or 'dev' == branch or 'dev-permission' == branch or 'test-permission' == branch:
    138                     continue
    139                     # elif uBranch != 'master' and uBranch != 'test' and uBranch != 'dev' and branch != uBranch:
    140                     # print '\033[1;35m 提交失败!你合并提交的分支来自于多个分支,请确认,你的分支%s,其他分支%s \033[0m' % (uBranch, branch)
    141                     # exit(-1)
    142                 branchs.add(branch)
    143             if len(branchs) >= 2 and isMaster:
    144                 print '\033[1;35m 提交失败!你合并提交的分支来自于多个分支,请确认%s \033[0m' % pipe
    145                 exit(-1)
    146 
    147     def getGitPushInfo(self):
    148         '''
    149         返回文件列表信息,提交者信息,提交时间
    150         '''
    151         self.__getGitInfo()
    152         self._skipExcludeProjects_()
    153         self.__getPushInfo()
    154         print '========================================='
    155         print "Time:", self.pushTime
    156         print "Author:", self.pushAuthor
    157         print "Ref:", self.ref
    158         print "Files:", self.fileList
    159         print '========================================='
    160 
    161 
    162 if __name__ == "__main__":
    163     t = Trigger()
    164     t.getGitPushInfo()
    View Code

     

    转载于:https://www.cnblogs.com/zhangshiwen/p/7747864.html

    展开全文
  • VS2005钩子 键盘钩子和鼠标钩子的简单实现 可安装卸载
  • 全局钩子和局部钩子

    2013-12-16 17:22:00
    局部钩子: SetWindowsHookEx(User32.HookType.WH_KEYBOARD, MouseHookProced,0, AppDomain.GetCurrentThreadId()); 注意事项:第一个参数是WH_KEYBOARD类似的局部钩子参数, 第二个是回调...
  • 钩子和行为

    2018-03-30 15:43:28
    来战吧,嘿嘿嘿要设置一个钩子,只需要在相关的位置添加一行代码(事先需要引入think\facade\Hook类):use think\facade\Hook;步骤:一:在tags.php文件下定义行为名称如果应用目录下面模块目录下面的tags.php都定义...
  • 我把鼠标钩子和键盘钩子封装成了两个工具类,有兴趣的朋友可以参考一下。项目的链接 使用的时候需要给定委托,委托的返回参数你可以参考DLL包下的两个类中的常量。注意,给定的委托函数内部不要写复杂的程序,委托的...
  • 设置全局键盘钩子和消息钩子

    千次阅读 2015-07-24 16:22:49
    前几天因为工作需要用到钩子,而且是全局钩子,用来监视别人的程序键盘消息。需要注意几点 1.如果只需要监视自己的应用程序,在自己程序里设置钩子就行。 2.如果需要监视别人的应用程序,一定要做成DLL形式的全局...
  • vc++键盘钩子和鼠标钩子

    千次阅读 2012-12-06 09:53:40
    该例的钩子都是写在一个DLL中的,应用程序独立开来的全局钩子。 一般情况下,如果要截获鼠标普通按键,刚可以用下边的方法 鼠标: LRESULT CALLBACK MouseProc(   int nCode, // hook code  ...
  • 最后你会发现那些说的服务器钩子其实还是客户端钩子,因为他们都说的是把工程检出,然后进入.git/hook目录下发去写钩子,这样全部是自己客户端的自定义规则,无法实现共享分发,你不可能让所有人把你的钩子安装在...
  • 记录并回放鼠标操作 WH_JOURNALRECORWH_JOURNALPLAYBACK 钩子的应用实例代码 好像是来自codeproject.com时间久了 忘了
  • git 配置本地钩子和服务器端钩子

    千次阅读 2017-11-17 11:41:16
    踩过的坑:  1、服务器端配置钩子的时候记得添加权限 ...pre-receive是你需要授权的文件,当只有-rwxrwxr-x权限的时候,客户端push,服务器端不会调用钩子。pre-receive/update/post-receive分别服
  • 钩子

    2018-05-03 22:06:23
    hook函数教程(一)什么是钩子一、什么是钩子 我们可以首先从字面上了解钩子钩子是干什么的呢?日常生活中,我们的钩子是用来钩住某种东西的,比如,说,鱼钩...最常见的就是鼠标键盘钩子,用Hook钩子钩住鼠标...
  • VC++中键盘钩子和鼠标钩子

    千次阅读 2011-08-21 09:42:16
    该例的钩子都是写在一个DLL中的,应用程序独立开来的全局钩子。 一般情况下,如果要截获鼠标普通按键,刚可以用下边的方法 鼠标: LRESULT CALLBACK MouseProc( int nCode, // hook code WPARAM
  • Delphi安装卸载钩子

    2021-05-18 04:34:06
    摘要:Delphi源码,系统相关,钩子 Delphi安装卸载钩子的源码实例,包括有一个钩子类的DLL源文件,主程序调用这个钩子DLL,并安装钩子与卸载的实例,可学习下如何调用一个DLL库文件。
  • 当需要对model_class中字段作进一步验证,作进一步的约束时,需要使用到钩子,即claan_xxxclean方法.其返回的errors有点不是那么好处理.看示例. 1.Model_class: class Permission(models.Model): """ ...
  • 键盘钩子程序源码

    2016-06-23 13:00:27
    键盘钩子程序源码
  • thinkphp钩子和行为

    2020-02-16 11:47:35
    一 <?...namespace app\index\behavior; use think\Request; class Test { public function run(Request $request, $params) ... echo '我是钩子函数'; } } class Index extends Controller { p...
  • Windows和X11下进程间键盘钩子和全局热键,修改相关窗口句柄之后就可以直接运行。 需要运行起来手工获得句柄,并将句柄修改到键盘钩子进程。
  • Windows和Linux上的钩子和模拟键盘事件
  • 请求钩子和装饰器路由实现和cookie和session 装饰器路由的实现 请求钩子 cookie和session 接收请求的参数 无状态引入(状态保持) 应用场景:网站登陆账号,下次不需要重复登陆 cookie -...
  • 线程钩子和键盘钩子(dll注入)模块+例程
  • TP5.1钩子和行为

    2020-04-05 17:17:12
    系统核心设计提供了一些可能会需要的钩子(位置),尽可能的方便应用的扩展而不必改动框架核心,如:app_init、app_begin等 添加新的钩子的方式有两种: ...类中的方法名和钩子的名称一致,如果该方...
  • 1.同个服务器下的钩子 a.设置gogs上的配置 shell : #!/bin/sh export GIT_WORK_TREE=网站根路径 export GIT_DIR=${GIT_WORK_TREE}/.git cd ${GIT_WORK_TREE} git pull b.设置网站下的git的分支拉取路径 vi ...
  • 本文通过注册页面的form组件,查看其中使用的全局钩子和局部钩子。 # Create your views here. class RegForm(forms.Form): username = forms.CharField( min_length=3, label="用户名", help_text=‘...
  • 一、局部钩子 命名规则为clean_对象名称,例如上面定义了username、pwd对象,那么可以定义clean_username、clean_pwd的局部钩子进行规则校验 1、例子:定义一个手机号校验的局部钩子 def clean_phone(self): ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 11,410
精华内容 4,564
关键字:

钩子和钩子