引言
设计灵感来源于:uTools、listary
软件架构:Python
软件功能:快捷启动,脚本化模块,可自由新增模块
缺陷:只对windows平台支持,虽然python可以跨平台,但是开发过程中,采用了WindowsAPI,手头没有mac设备,就放弃了兼容其它操作系统。
优势:完全开放,模块开发更加容易
内置的模块也在完善中
其实它们外观都是大同小异的
架构&模式
主进程(提供窗口和快捷键监听,提供模块检索功能)
启动器,接收主程序调用请求,并且执行模块,看门狗服务
模块,以子进程启动,使系统隔离,子模块的缺陷不会引起主进程的阻塞
悬浮窗和搜索框
支持二级菜单
可自由创建方法实现,只要你肯做,也可以做出GUI界面,甚至采用QT等先进框架
因为要从无到有,所以美化就搁置了
系统稳定性的保障,子模块如果没有相应了,则关掉它,并且提示
关键字搜索
当然,目前只是实现为主,美化得往后放放了,自己一个人做,难面有些吃力
|-conf # 配置文件
|--config.json # 系统配置文件
|-logs # 日志文件
|--2022-12-16.txt # 每日日志文件
|-res # 资源文件
|--logo.png # 悬浮窗和搜索框右侧的logo
|-tools # 模块目录,可自行增减
|--imgs # 模块需要的图片资源
|---ip.png
|---net.png
|---hosts.png
|---...
|--main.py # 系统模块
|--network.py # 网络模块
|--rsa.py # rsa加解密模块
|-utils # 系统工具类
|--logger.py # 日志模块
|--mProcess.py # 启动器模块
|--system.py # 系统主要功能实现
|--window.py # 窗口部分的实现
|-main.py # 程序入口
模块功能解析部分
这部分采用了以空间换时间的方法
子模块的解析采用了三层冗余存储
{"module":{} # 根据模块名称构成的模块字典
"methods": {}, # 根据序列号和方法名构建的方法字典
"serials": {} # 根据序列号构成的模块字典
}
{
'module': {
'myTools 系统模块': {
'module': 'myTools 系统模块',
'description': '程序操作',
'version': 1.0,
'author': 'zunmx',
'import': 'system',
'serial': 'ef6787ca66a799997775c7dfaae8ff74',
'email': 'admin@zunmx.top',
'methods': [{
'entry': 'exit',
'description': '退出程序'
}, {
'entry': 'reload',
'description': '重新加载程序'
}, {
'entry': 'reboot',
'description': '重新启动电脑'
}, {
'entry': 'shutdown',
'description': '关闭计算机'
}],
'package': 'tools.main'
},
'网络相关模块': {
'module': '网络相关模块',
'description': '提供网络相关服务',
'version': 1.0,
'icon': 'imgs\\net.png',
'author': 'zunmx',
'email': 'admin@zunmx.top',
'serial': '5c7b953e6de21c0f51a9b9c2884d7bef',
'methods': [{
'entry': 'get_ip',
'description': '获取本机IP地址列表',
'icon': 'imgs\\ip.png',
'return': 'json'
}, {
'entry': 'get_hosts',
'description': '获取本机Hosts',
'icon': 'imgs\\hosts.png',
'return': 'text'
}, {
'entry': 'bd',
'description': '百度搜索',
'icon': 'imgs\\baidu.png',
'params': {
'key': '待搜索的关键字'
},
'return': 'none'
}, {
'entry': 'bing',
'description': '必应搜索',
'icon': 'imgs\\bing.png',
'params': {
'key': '待搜索的关键字'
},
'return': 'none'
}],
'package': 'tools.network'
},
'RSA 加密解密模块': {
'module': 'RSA 加密解密模块',
'description': 'RSA 加密解密模块',
'version': 1.0,
'icon': 'imgs\\encrypted.png',
'author': 'zunmx',
'serial': '0402d2f8ab47d3ea9420cabada6313c9',
'methods': [{
'entry': 'rsa',
'description': 'rsa 加密解密模块',
'icon': 'imgs\\encrypted.png',
'return': 'none'
}],
'package': 'tools.rsa'
}
},
'methods': {
'ef6787ca66a799997775c7dfaae8ff74$@$exit': {
'entry': 'exit',
'description': '退出程序'
},
'ef6787ca66a799997775c7dfaae8ff74$@$reload': {
'entry': 'reload',
'description': '重新加载程序'
},
'ef6787ca66a799997775c7dfaae8ff74$@$reboot': {
'entry': 'reboot',
'description': '重新启动电脑'
},
'ef6787ca66a799997775c7dfaae8ff74$@$shutdown': {
'entry': 'shutdown',
'description': '关闭计算机'
},
'5c7b953e6de21c0f51a9b9c2884d7bef$@$get_ip': {
'entry': 'get_ip',
'description': '获取本机IP地址列表',
'icon': 'imgs\\ip.png',
'return': 'json'
},
'5c7b953e6de21c0f51a9b9c2884d7bef$@$get_hosts': {
'entry': 'get_hosts',
'description': '获取本机Hosts',
'icon': 'imgs\\hosts.png',
'return': 'text'
},
'5c7b953e6de21c0f51a9b9c2884d7bef$@$bd': {
'entry': 'bd',
'description': '百度搜索',
'icon': 'imgs\\baidu.png',
'params': {
'key': '待搜索的关键字'
},
'return': 'none'
},
'5c7b953e6de21c0f51a9b9c2884d7bef$@$bing': {
'entry': 'bing',
'description': '必应搜索',
'icon': 'imgs\\bing.png',
'params': {
'key': '待搜索的关键字'
},
'return': 'none'
},
'0402d2f8ab47d3ea9420cabada6313c9$@$rsa': {
'entry': 'rsa',
'description': 'rsa 加密解密模块',
'icon': 'imgs\\encrypted.png',
'return': 'none'
}
},
'serials': {
'ef6787ca66a799997775c7dfaae8ff74': {
'module': 'myTools 系统模块',
'description': '程序操作',
'version': 1.0,
'author': 'zunmx',
'import': 'system',
'serial': 'ef6787ca66a799997775c7dfaae8ff74',
'email': 'admin@zunmx.top',
'methods': [{
'entry': 'exit',
'description': '退出程序'
}, {
'entry': 'reload',
'description': '重新加载程序'
}, {
'entry': 'reboot',
'description': '重新启动电脑'
}, {
'entry': 'shutdown',
'description': '关闭计算机'
}],
'package': 'tools.main'
},
'5c7b953e6de21c0f51a9b9c2884d7bef': {
'module': '网络相关模块',
'description': '提供网络相关服务',
'version': 1.0,
'icon': 'imgs\\net.png',
'author': 'zunmx',
'email': 'admin@zunmx.top',
'serial': '5c7b953e6de21c0f51a9b9c2884d7bef',
'methods': [{
'entry': 'get_ip',
'description': '获取本机IP地址列表',
'icon': 'imgs\\ip.png',
'return': 'json'
}, {
'entry': 'get_hosts',
'description': '获取本机Hosts',
'icon': 'imgs\\hosts.png',
'return': 'text'
}, {
'entry': 'bd',
'description': '百度搜索',
'icon': 'imgs\\baidu.png',
'params': {
'key': '待搜索的关键字'
},
'return': 'none'
}, {
'entry': 'bing',
'description': '必应搜索',
'icon': 'imgs\\bing.png',
'params': {
'key': '待搜索的关键字'
},
'return': 'none'
}],
'package': 'tools.network'
},
'0402d2f8ab47d3ea9420cabada6313c9': {
'module': 'RSA 加密解密模块',
'description': 'RSA 加密解密模块',
'version': 1.0,
'icon': 'imgs\\encrypted.png',
'author': 'zunmx',
'serial': '0402d2f8ab47d3ea9420cabada6313c9',
'methods': [{
'entry': 'rsa',
'description': 'rsa 加密解密模块',
'icon': 'imgs\\encrypted.png',
'return': 'none'
}],
'package': 'tools.rsa'
}
}
}
模块定义
比如网络模块
import requests
import os
import webbrowser
class Entry: # 固定的
def boot(self): # 固定的
app = {"module": "网络相关模块", # 模块名称
"description": "提供网络相关服务", # 模块描述
"version": 1.0, # 模块版本
"icon": "imgs\\net.png", # 模块默认图标
"author": "zunmx", # 模块作者
"email": "admin@zunmx.top", # 电子邮箱
"serial": "5c7b953e6de21c0f51a9b9c2884d7bef", # 模块序列号,所有模块的序列号都是唯一的
"methods": [
{
"entry": "get_ip", # 方法入口名称, 在这个类中需要存在这个方法
"description": "获取本机IP地址列表", # 方法描述
"icon": "imgs\\ip.png", # 方法图标
"return": "json" # 方法返回值
},
{
"entry": "get_hosts",
"description": "获取本机Hosts",
"icon": "imgs\\hosts.png",
"return": "text"
},
{
"entry": "bd",
"description": "百度搜索",
"icon": "imgs\\baidu.png",
"params": { # 如果需要二级菜单,就有这项
"key": "待搜索的关键字" # key是菜单名,后面的是描述
},
"return": "none"
},
{
"entry": "bing",
"description": "必应搜索",
"icon": "imgs\\bing.png",
"params": {
"key": "待搜索的关键字"
},
"return": "none"
}
]}
return app
def __init__(self):
pass
def get_ip(self): # 与上面定义的entry要保持一致
get = requests.get("http://www.zunmx.top/test.php")
return {"公网IP:": get.text.split("<br/>")[0]}
def get_hosts(self):
with open(os.getenv("windir") + r"\system32\drivers\etc\hosts", 'r', encoding='utf8') as f:
return f.read()
def bd(self, params):
webbrowser.open(f"https://www.baidu.com/s?wd={params['key']}") # params是传过来的值,dict类型,所以直接取params['key']就可以了,key是上面定义时候的键
def bing(self, params):
webbrowser.open(f"https://cn.bing.com/search?q={params['key']}")
待办
枚举已安装的软件,快捷启动
模块启动次数排序
子进程任务管理器
自定义文件启动器
文件的PE信息提取
节省内存的方案
方法格式化校验 eval 可能造成直接执行代码漏洞
模块开关,子功能的启动和禁用
模糊查询,拼音首字母
服务式后台运行模块
github
算了,独立开发真是麻烦,shi山代码,懒得搞了。