程序完整代码:Masterain98/PyClipboardSender

前言
Lockdown Browser 的功能之一就是限制系统剪贴板的使用。作为系统组件的一部分,Windows 剪贴板实际上一直在运行中,因此我们可以使用第三方软件收集剪贴板内容。在最新的 Windows 10 系统中,用户可以在登录微软帐号后在不同的 Windows 10 设备之间通过 Win + V
快捷键同步剪贴板。但是这一功能在旧版的系统中并不存在,常见的第三方云剪贴板软件也被拉进 Lockdown Broswer 黑名单,所以自己整一个类似的小工具是有必要的。
思路
因为仅仅是考虑到少数几个设备之间的传输,且大概率是在内网环境下由个人使用,所以做成帐号登录形式的多设备同步是没必要的。我们可以将接受剪贴板的设备考虑为一个服务端,发送剪贴板内容的设备考虑为一个客户端,端对端地直接传输数据。HTTP 请求是一个常见易用的方案,以 json
的形式 POST 请求也容易处理数据。而在剪贴板功能上,我们可以直接使用 pyperclip
库中的功能。
服务端
首先需要为服务器做一个配置文件
config.json
- 需要包含两个字段来储存密码和客户端白名单作为验证
- {
- "passwd" : "123456",
- "allowedPC" : "MasterainPC1,MasterainPC2, MasterainPC3"
- }
- 主程序中导入必要的库
- import pyperclip # 用于Windows剪贴板相关功能
- import json # 用于处理json数据
- from flask import Flask, jsonify, request # Flask作为Web程序,jsonify和request处理HTTP请求
- 设置 Flask 接收 HTTP 请求的函数
- app = Flask(__name__)
- app.config["JSON_AS_ASCII"] = False
-
- # 剪贴板函数,接收一个HTTP POST请求
- # content为剪贴板内容
- # passwd为用于验证的密码字段
- # pcName为用于验证的计算机名白名单
- @app.route("/clipboardReceiver", methods=["POST"])
- def clipboardReceiver():
- # Expect to receive json posts
- content = request.json.get("content").strip()
- passwd = request.json.get("passwd").strip()
- pcName = request.json.get("pcName").strip()
-
- # 处理验证内容
- if server_passwd != "" and server_passwd == passwd or server_passwd == "":
- # 当白名单为空时,允许所有计算机客户端发送内容
- if server_allowedPC == "":
- # 将content中的内容加载到本地剪贴板中
- pyperclip.copy(content)
- return jsonify({"code": 2000, "msg": "Clipboard content received"})
- elif server_allowedPC != "" and pcName in server_allowedPC_list:
- pyperclip.copy(content)
- return jsonify({"code": 2000, "msg": "Clipboard content received"})
- else:
- return jsonify({"code": 2001, "msg": "Client not in white list"})
- else:
- return jsonify({"code": 2002, "msg": "Wrong password"})
- 主程序
- if __name__ == '__main__':
- # 读取本地config.json
- configFile = json.loads(config.read())
- server_passwd = configFile["passwd"].replace(' ', '')
- server_allowedPC = configFile["allowedPC"].replace(' ', '')
- server_allowedPC_list = server_allowedPC.split(",")
-
- # 将Flask程序跑在本地5951端口上
- app.run(host="0.0.0.0", port=5951, debug=True)
客户端
和服务端一样,创建一个
config.json
配置文件- 包含服务端的目标 IP(理论上域名也行)和服务端密码
- {
- "server": "192.168.50.219",
- "passwd" : "123456"
- }
- 主程序中加载必要的库
- # 剪贴板库
- import pyperclip
- # 处理json
- import json
- # HTTP请求
- import requests
- # 获取本地计算机名
- import socket
- # time.sleep()
- import time
- 主程序中以一个 Infinite loop 来不断读取客户端本地的剪贴板内容,当监测到内容变化时发起一个 HTTP POST 将内容发送到目标服务端
- if __name__ == '__main__':
- """
- 省略读取本地config.json的过程
- """
- # 获取计算机名
- hostname = socket.gethostname()
- # 初始化
- lastRecord = ""
- while True:
- # 读取本地剪贴板内容
- clipboard_content = pyperclip.paste()
-
- if clipboard_content != lastRecord:
- # 将内容加载到json中并发送请求
- payload = {"content": clipboard_content, "passwd": passwd, "pcName": hostname}
- lastRecord = clipboard_content
- response = requests.post(targetURL, data=json.dumps(payload), headers=headers).text
- # 处理返回的结果(其实非必要)
- returnInfoJson = json.loads(response)
- responseCode = returnInfoJson.get("code")
- print("Return Code " + str(responseCode))
- time.sleep(0.5)
模拟请求
- 在收到
2000
的返回码时,成功将测试内容
加载到剪贴板中
转载请标注来源