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------

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值