Mac監控鍵盤輸入並執行動作

NetRookieX發表於2023-02-26

背景

電腦的安全是非常重要的,特別是裡面的敏感資料,若是被有心之人利用,那後果不堪設想。
所以我們部門定下了一個規矩,誰離開工位要是不鎖屏,就可以在部門群傳送一個訊息:我請大家吃雞翅。

oh,技術出身怎麼可以讓這種事情發生。

簡介

最新程式碼我放到了這裡:https://github.com/GuoFlight/ListenKey ,歡迎Star與交流。

程式碼邏輯是,監聽到指定的字串就會「執行動作」。

程式碼實現

執行環境:Mac+Python3.(Windows也可,但要修改小部分程式碼)
倉庫中我還實現了啟停指令碼control.sh。這裡只介紹主要邏輯。
將以下程式碼後臺執行,當鍵盤輸入"jichi", "qingdajia", "dajia", "weizheng"這些字串時,Mac就會鎖屏。

#!/usr/bin/python3
from pynput.keyboard import Listener
import os
import time
import signal
from multiprocessing import Pool

#####################################
# 程式作用:監聽鍵盤,若輸入了指定的字串,則執行相應的動作
# 作者:京城郭少
#####################################

class ListenKey:
    def __init__(self, listenStr="", actionFunc=None):
        self.listenStr = listenStr
        self.actionFunc = actionFunc
        self.index = 0

    def on_press(self, key):
        # print("監聽到了",key)  # DEBUG
        if self.listenStr == "" or self.actionFunc == None:
            return
        pressKey = None
        try:
            pressKey = key.char
        except AttributeError:
            pressKey = key
        if pressKey == self.listenStr[self.index]:
            # print("本次按鍵符合條件")  # DEBUG
            if self.index == len(self.listenStr) - 1:
                self.index = 0
                self.actionFunc()
                now = time.strftime("%Y-%m-%d  %H:%M:%S", time.localtime())
                print("【%s】執行動作" % (now),flush=True)  # DEBUG
            else:
                self.index = (self.index + 1) % (len(self.listenStr))
        else:
            self.index = 0

    def on_release(self, key):
        return

    def start_listen(self):
        # print("開始監聽")       #DEBUG
        with Listener(on_press=self.on_press, on_release=self.on_release) as listener:
            listener.join()

#指定動作
def actionFunc():
    #os.system("shutdown -s now")
    os.system("osascript -e 'tell application \"System Events\" to key code 12 using {control down,command down}'")
    #print("hello",flush=True)

#處理訊號
def handle_exit(sig, stack_frame):
    print('eixt',flush=True)
    p.terminate()
    exit(0)


if __name__ == '__main__':
    keywords = ["jichi", "qingdajia", "dajia", "weizheng"]
    
    signal.signal(signal.SIGINT, handle_exit)
    signal.signal(signal.SIGQUIT, handle_exit)
    signal.signal(signal.SIGTERM, handle_exit)
    # signal.signal(signal.SIGKILL, handle_exit)
    listenKey = []
    p = Pool(6)  # 最多同時執行6個程式
    for i in keywords:
        listenKey.append(ListenKey(i, actionFunc))
    for i in listenKey:
        p.apply_async(i.start_listen)  # 在程式池中新增程式
    p.close()
    p.join()  # 等待子程式結束再往下執行

京城郭少


相關文章