powershell 注册全局热键——提升效率小工具

powershell 注册全局热键

01 前言

在处理一些重复工作问题的时候,想搞一个小工具,配合全局快捷键来提高效率。因为是Windows系统,想到C#,但是又不想用VS开发,因为那样不够灵活,没办法随时修改随时用,所以只能另寻他法。那么,不如用powershell来搞搞。

02 正文

因为涉及到全局热键,所以还是需要写一点C#,引入一些API,同时加了一个简单的窗体。

环境:Windows 11

代码如下:


<#
注册全局热键

by hokis

2024-04-30 21:35

#>

$code = @'
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

public class GlobalHotkey
{
    public const int MOD_ALT = 0x0001;    // Alt键
    public const int MOD_CTRL = 0x0002;   // Ctrl键
    public const int MOD_SHIFT = 0x0004;  // Shift键
    public const int MOD_WIN = 0x0008;    // Windows键
    private const int WM_HOTKEY = 0x0312;

    private Action<object, EventArgs> hotkeyAction;
    private int id;

    [DllImport("user32.dll")]
    private static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, Keys vk);

    [DllImport("user32.dll")]
    private static extern bool UnregisterHotKey(IntPtr hWnd, int id);

    public GlobalHotkey(IntPtr hWnd, Keys key, int modifier, Action<object, EventArgs> action)
    {
        hotkeyAction = action;
        id = this.GetHashCode();

        RegisterHotKey(hWnd, id, modifier, key);
        Application.AddMessageFilter(new MessageFilter(this));
    }

    public void Unregister(IntPtr hWnd)
    {
        UnregisterHotKey(hWnd, id);
    }

    private class MessageFilter : IMessageFilter
    {
        private GlobalHotkey hotkey;

        public MessageFilter(GlobalHotkey hotkey)
        {
            this.hotkey = hotkey;
        }

        public bool PreFilterMessage(ref Message m)
        {
            if (m.Msg == WM_HOTKEY && (int)m.WParam == hotkey.id)
            {
                hotkey.hotkeyAction(null, EventArgs.Empty);
                return true;
            }
            return false;
        }
    }

}
'@

Add-Type -TypeDefinition $code -ReferencedAssemblies 'System.Windows.Forms'

Add-Type -AssemblyName 'System.Windows.Forms'


#全局对象
[GlobalHotkey]$Global:hotkey = $null

 <#
 热键被按下,事件处理
 #>
$action = [System.Action[System.Object,System.EventArgs]]{
    param(
        $obj,
        $er
    )
    Write-Host '热键被按下了...'
    #提醒
    [System.Media.SystemSounds]::Beep.Play()
}

<#
    .Synopsis
       窗体结构
    .DESCRIPTION
       窗体结构

#>
function Get-Windows
{
    [CmdletBinding()]
    Param
    (
        # title 窗口标题
        [Parameter(Mandatory=$true,
                    ValueFromPipelineByPropertyName=$true,
                    Position=0)]
        [string]
        $title,

        [int]
        $width = 100,

        [int]
        $height = 50,
        
        # 不透明度,1为不透明,0为透明
        [double]
        $opacity = 1,

        [System.Action[System.Object,System.EventArgs]]
        $hotkeyAction,

        #是否置顶
        [switch]
        $toTop
    )
    
    Begin
    {
    }
    Process
    {

        #主窗体
        [System.Windows.Forms.Application]::EnableVisualStyles()
	    [System.Windows.Forms.Form]$mainForm = New-Object 'System.Windows.Forms.Form'

        #控件
        [System.Windows.Forms.Button]$sureBtn = New-Object 'System.Windows.Forms.Button'
        [System.Windows.Forms.Button]$cancelBtn = New-Object 'System.Windows.Forms.Button'

	    #大小
        $mainForm.ClientSize=('{0},{1}' -f $width,$height)
        
        #最大化按钮
	    $mainForm.MaximizeBox = $False
        #最小化按钮
        $mainForm.MinimizeBox = $False
        #名称
	    $mainForm.Name = "mainForm"
        #显示icon
	    $mainForm.ShowIcon = $False
        #透明度
        $mainForm.Opacity = $opacity

        #标题
	    $mainForm.Text = $title
        #是否置顶
	    $mainForm.TopMost = $toTop
        #不可调整大小
        $mainForm.FormBorderStyle=[System.Windows.Forms.BorderStyle]::FixedSingle
        #显示位置,屏幕居中
        $mainForm.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen
        
        #加入控件
        $mainForm.Controls.Add($sureBtn)
        $mainForm.Controls.Add($cancelBtn)

       
        #确定按钮
        $sureBtn.Text = '确定'
        $sureBtn.Size = '40, 30'
        $sureBtn.Location = '5, 5'
        $sureBtn.add_Click({
            #确定按钮事件
            if($Global:hotkey -and $sureBtn.Enabled){
                $sureBtn.Enabled = $False
                Write-Host '热键已注册~'
                return
            }
            
            #创建热键 F10
            #$Global:hotkey = [GlobalHotkey]::new($mainForm.Handle,[System.Windows.Forms.Keys]::F10,0,$hotkeyAction)
            
            #创建热键 Ctrl+F10
            #$Global:hotkey = [GlobalHotkey]::new($mainForm.Handle,[System.Windows.Forms.Keys]::F10,[GlobalHotkey]::MOD_CTRL,$hotkeyAction)
            
            #创建热键 Alt+F10
            #$Global:hotkey = [GlobalHotkey]::new($mainForm.Handle,[System.Windows.Forms.Keys]::F10,[GlobalHotkey]::MOD_ALT,$hotkeyAction)
            
            #创建热键 Ctrl+Alt+F10
            $Global:hotkey = [GlobalHotkey]::new($mainForm.Handle,[System.Windows.Forms.Keys]::F10,[GlobalHotkey]::MOD_CTRL + [GlobalHotkey]::MOD_ALT ,$hotkeyAction)

            $sureBtn.Enabled = $False
            Write-Host '注册成功!'
        })

        $cancelBtn.Text = '取消'
        $cancelBtn.Size = '40, 30'
        $cancelBtn.Location = '60, 5'
        $cancelBtn.add_Click({
            #取消按钮事件
            if($Global:hotkey){
                $Global:hotkey.Unregister($mainForm.Handle)
                $sureBtn.Enabled = $true
                Write-Host '已取消热键..'
            }
            $Global:hotkey = $null
        })

        $mainForm.add_FormClosed({
            #窗体关闭事件
            if($Global:hotkey){
                $Global:hotkey.Unregister($mainForm.Handle)
                $Global:hotkey = $null
            }
        })

        #显示窗口
        [void]$mainForm.ShowDialog()   
        $mainForm = $null
    }
    End
    {
    }
}

#标题
#Get-Windows -title '全局热键' -hotkeyAction $action

#置顶
#Get-Windows -title '全局热键' -hotkeyAction $action -toTop

#透明度
#Get-Windows -title '全局热键' -hotkeyAction $action -opacity 0.5

Get-Windows -title '全局热键' -hotkeyAction $action -opacity 1 -toTop

脚本使用说明

  • powershell 5.1下测试通过
  • 代码另存为 run.ps1,右键,“使用 PowerShell 运行”。弹出界面后,点“确定”按钮注册全局热键,点“取消”可以取消热键。
  • 如果不能执行脚本,提示“无法加载文件 C:\XXX\run.ps1,因为在此系统上禁止运行脚本……”。请先修改powershell执行策略(参考此处)

修改说明

  • 本例中注册的全局热键为:Ctrl+Alt+F10,如需修改,请修改$sureBtn.add_Click({...})中的部分内容。
  • 窗体的样式可以在最后部分调整
  • 热键被按下的事件处理,在
    $action = [System.Action[System.Object,System.EventArgs]]{
    param(
    $obj,
    $er
    )
    # 热键被按下时,事件处理
    Write-Host ‘热键被按下了…’
    #声音提醒
    [System.Media.SystemSounds]::Beep.Play()
    }
    中修改。
  • 窗体还可以增加输入框等控件,以适应不同的场景,有条件可以自行扩展。

效果图

  1. 运行界面:
    运行

  2. 点“确定”注册热键
    注册热键

  3. 按下热键
    按下热键

  4. 取消热键
    取消热键

03 后记

搞完这个,马上做事效率就高了。不说了,继续打工了。

欢迎留言交流~
------END------

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/585425.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Spring ai 快速入门及使用,构建你自己的ai

第一步&#xff1a;创建springboot项目 jdk必须是17及以上 1.8用不了 第二步 选择web和ai的依赖 选择openai 第三步 需要配置openai key 配置 分享个免费或的apikey的地方New API 会免费赠送1刀的token spring.application.namespringAI spring.ai.openai.base-urlhttps://ap…

推荐一个好用的命令行工具ShellGPT

ShellGPT 配置安装常用功能聊天写命令并执行 高级功能函数调用角色管理 总结 这两天突然想到&#xff0c;现有的很多工具都在被大模型重构&#xff0c;比如诞生了像perplexity.ai 这种新交互形式的搜索引擎&#xff0c;就连wps也推出了AI服务&#xff0c;甚至都可以直接生成ppt…

JavaScript转换和校验数字

本节我们使用的案例还是继续之前的银行家应用程序&#xff0c;只不过我们呢增加了两个账号&#xff0c;代码如下&#xff1a; const account1 {owner: Jonas Schmedtmann,movements: [200, 455.23, -306.5, 25000, -642.21, -133.9, 79.97, 1300],interestRate: 1.2, // %pin…

Leetcode 145:二叉树的后序遍历(迭代法)

给你一棵二叉树的根节点 root &#xff0c;返回其节点值的 后序遍历 。 思路&#xff1a; 迭代法的思路是&#xff0c;使用栈&#xff0c;一层一层的将树节点遍历入栈。 比如下面这个树&#xff0c;使用迭代法&#xff0c;1&#xff09;第一层&#xff0c;让根节点入栈。2&a…

20240428如何利用IDM下载磁链视频

缘起&#xff1a; https://weibo.com/tv/show/1034:4864336909500449 中国获奖独立纪录片《阿辉》揭秘红灯区“教父”的生存法则 5,751次观看 1年前 发布于 陕西 身为里中横 67.7万粉丝 互联网科技博主 微博原创视频博主 头条文章作者 https://weibo.com/tv/show/1034:4864…

树莓派驱动开发----spi flash设备w25q64开发

这期使用的是spi驱动开发框架&#xff0c;其实spi和iic合起来有一个 Regmap 子系统&#xff0c;下回讲这个&#xff01;&#xff01; 使用方法 &#xff1a;./w25q64App /dev/w25q64-device <cmd> <address> <cnt> <data> ... 可读写擦&#xff0…

代码审计之SAST自动化

前言: 很久没写文章了&#xff0c;有点忙&#xff0c;落个笔&#xff0c;分享一些捣鼓或说适配好的一些好玩的东西。 脚本工具不开源&#xff0c;给一些思路&#xff0c;希望能给大家带来一些收获。 笔者能力有限&#xff0c;如有错误&#xff0c;欢迎斧正。 正文&#xff1a…

文件分块+断点续传 实现大文件上传全栈解决方案(前端+nodejs)

1. 文件分块 将大文件切分成较小的片段&#xff08;通常称为分片或块&#xff09;&#xff0c;然后逐个上传这些分片。这种方法可以提高上传的稳定性&#xff0c;因为如果某个分片上传失败&#xff0c;只需要重新上传该分片而不需要重新上传整个文件。同时&#xff0c;分片上传…

linux 搭建知识库文档系统 mm-wiki

目录 一、前言 二、常用的知识库文档工具 2.1 PingCode 2.2 语雀 2.3 Tettra 2.4 Zoho Wiki 2.5 Helpjuice 2.6 SlimWiki 2.7 Document360 2.8 MM-Wiki 2.9 其他工具补充 三、MM-Wiki 介绍 3.1 什么是MM-Wiki 3.2 MM-Wiki 特点 四、搭建MM-Wiki前置准备 4.1 前置…

带环链表及例题

环形链表&#xff0c;链表中的尾节点指向链表中的某个节点导致形成循环的链表。 通过图可以这样表示。 我们一般采用快慢指针的方式解决带环链表的题目&#xff0c;下面直接上例题 环形链表 力扣链接&#xff1a; . - 力扣&#xff08;LeetCode&#xff09; 让我们判断一个…

渗透测试之sql注入绕过技巧

在sql注入中&#xff0c;通常会将某些关键的字符过滤掉&#xff0c;以此来达到预防sql注入的目的。这时我们就可以通过某些技巧来绕过。 绕过技巧1&#xff1a; 这个是在某个比赛中出现的&#xff0c;当时并没有多少人成功绕过。 如下&#xff1a; 如下图&#xff1a;在php中…

Django前后端项目部署

Django前后端分离项目部署 本文采用阿里云服务器&#xff0c;centos7.9操作系统 本文默认服务器已安装nginx,mysql并且可以正常运行Django vue uwsgi nginx注意&#xff1a;先部署后端&#xff0c;使用postman测试请求没有问题后在修改vue中的axios文件中baseURL&#xff0…

PLC通过Modbus转Profinet网关连接变频器与电机通讯

Modbus转Profinet网关&#xff08;XD-MDPN100&#xff09;是一种能够实现Modbus协议和Profinet协议之间转换的设备。Modbus转Profinet网关可提供单个或多个RS485接口&#xff0c;PLC作为控制中枢&#xff0c;变频器作为控制电机转速&#xff0c;通过Modbus转Profinet网关&#…

美国站群服务器的定义、功能以及在网站运营中的应用

美国站群服务器的定义、功能以及在网站运营中的应用 在当今互联网的蓬勃发展中&#xff0c;站群服务器已成为网站运营和SEO优化中不可或缺的重要工具之一。尤其是美国站群服务器&#xff0c;在全球范围内备受关注。本文将深入探讨美国站群服务器的定义、功能以及在网站运营中的…

【城市】应届生第一次打工需要知道的常识(薪资结构,社保,五险二金,个税,专项扣除)

【城市】应届生第一次打工需要知道的常识&#xff08;薪资结构&#xff0c;社保&#xff0c;五险二金&#xff0c;个税&#xff0c;专项扣除&#xff09; 文章目录 1、什么是应届生 & 如何界定应届生2、社保&#xff0c;五险一金&#xff0c;五险二金3、薪资结构&#xff0…

运存与内存?内存与存储? 傻傻分不清

主页: 元存储博客 图片来源: Blackblaze 文章目录 名词为何“内存”的含义混乱内存和存储含义内存和存储作用RAM 与 存储差异速度和性能容量和尺寸易失性和持久性常见问题:总结名词 内存: Memory,如内存条 存储器: Storage, 包括硬盘等 为何“内存”的含义混乱 <

class089 贪心经典题目专题1【左程云算法】

class089 贪心经典题目专题1【左程云算法】 前言版权推荐class089 贪心经典题目专题1code1 179. 最大数code2 1029. 两地调度code3 1553. 吃掉 N 个橘子的最少天数code4 253. 会议室IIcode5 630. 课程表 IIIcode6 1167. 连接棒材的最低费用(leetcode测试)code6 P1090 连接棒材的…

C进阶-数据的存储

文章目录 1. 数据类型介绍类型的基本归类 2. 整型在内存中的存储:原码,反码,补码2.1. 原码,反码,补码 2.2. 大小端介绍大端字节序存储小端字节序存储例:设计程序判断是大端还是小端? 2.3. 练习练习1练习2练习3练习4 3. 浮点型在内存中的存储 1. 数据类型介绍 数据类型数据类型…

YARN详解

YARN 简介 YARN 是Yet Another Resource Negotiator的缩写。 YARN是第二代MapReduce,即MRv2,是在第一代MapReduce基础上演变而来的,主要是为了解决原始Hadoop扩展性较差,不支持多计算框架而提出的;通俗讲就是资源管理器. YARN核心思想: 将 MR1 中资源管理和作业调度两个功能分…

node.js 解析post请求 方法二

前提&#xff1a;以前面发的node.js解析post请求方法一为模板&#xff0c;具体见 http://t.csdnimg.cn/ABaIn 此文我们运用第二种方法&#xff1a;使用第三方模块formidable对post请求进行解析。 1》代码难点 *** 在Node.js中使用formidable模块来解析POST请求主要涉及到处理…