Files

142 lines
4.8 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ==============================================
# =============== Windows系统API ===============
# ==============================================
import os
import subprocess
from PySide2.QtCore import QStandardPaths as Qsp, QFile, QFileInfo
from umi_log import logger
from umi_about import UmiAbout
from .key_translator import getKeyName
# 环境的类型:
# "APPDATA" 用户,低权限要求
# "ProgramData" 全局,高权限要求
EnvType = "APPDATA" # or "ProgramData"
# ==================== 快捷方式 ====================
class _Shortcut:
@staticmethod # 获取地址
def _getPath(position):
# 桌面
if position == "desktop":
return Qsp.writableLocation(Qsp.DesktopLocation)
startMenu = os.path.join(
os.getenv(EnvType), "Microsoft", "Windows", "Start Menu"
)
# 开始菜单
if position == "startMenu":
return startMenu
# 开机自启
elif position == "startup":
return os.path.join(startMenu, "Programs", "Startup")
# 创建快捷方式返回成功与否的字符串。position取值
# desktop 桌面
# startMenu 开始菜单
# startup 开机自启
@staticmethod
def createShortcut(position):
lnkName = UmiAbout["name"]
appPath = UmiAbout["app"]["path"]
if not appPath or not os.path.exists(appPath):
return f"[Error] 未找到程序exe文件。请尝试手动创建快捷方式。\n[Error] Exe path not exist. Please try creating a shortcut manually.\n\n{appPath}"
lnkPathBase = _Shortcut._getPath(position)
lnkPathBase = os.path.join(lnkPathBase, lnkName)
lnkPath = lnkPathBase + ".lnk"
i = 1
while os.path.exists(lnkPath): # 快捷方式已存在
lnkPath = lnkPathBase + f" ({i}).lnk" # 添加序号
i += 1
appFile = QFile(appPath)
res = appFile.link(lnkPath)
if not res:
return f"[Error] {appFile.errorString()}\n请尝试以管理员权限启动软件。\nPlease try starting the software as an administrator.\nappPath: {appPath}\nlnkPath: {lnkPath}"
return "[Success]"
# 删除快捷方式,返回删除文件的个数
@staticmethod
def deleteShortcut(position):
lnkName = UmiAbout["name"]
lnkDir = _Shortcut._getPath(position)
num = 0
for fileName in os.listdir(lnkDir):
lnkPath = os.path.join(lnkDir, fileName)
try:
if not os.path.isfile(lnkPath): # 排除非文件
continue
info = QFileInfo(lnkPath)
if not info.isSymLink(): # 排除非快捷方式
continue
originName = os.path.basename(info.symLinkTarget())
if lnkName in originName: # 快捷方式指向的文件名包含appName删之
os.remove(lnkPath)
num += 1
except Exception:
logger.error(
f"删除快捷方式失败。 lnkPath: {lnkPath}",
exc_info=True,
stack_info=True,
)
continue
return num
# ==================== 硬件控制 ====================
class _HardwareCtrl:
# 关机
@staticmethod
def shutdown():
os.system("shutdown /s /t 0")
# 休眠
@staticmethod
def hibernate():
os.system("shutdown /h")
# ==================== 对外接口 ====================
class Api:
# 快捷方式。接口: createShortcut deleteShortcut
# 参数:快捷方式位置, desktop startMenu startup
Shortcut = _Shortcut()
# 硬件控制。接口: shutdown hibernate
HardwareCtrl = _HardwareCtrl()
# 根据系统及硬件,判断最适合的渲染器类型
@staticmethod
def getOpenGLUse():
import platform
# 判断系统版本,若 >win10 则使用 GLES ,否则使用软渲染
version = platform.version()
if "." in version:
ver = version.split(".")[0]
if ver.isdigit() and int(ver) >= 10:
return "AA_UseOpenGLES"
return "AA_UseSoftwareOpenGL"
# 键值转键名
@staticmethod
def getKeyName(key):
return getKeyName(key)
# 让系统运行一个程序,不堵塞当前进程
@staticmethod
def runNewProcess(path, args=""):
subprocess.Popen(
f'start "" "{path}" {args}',
shell=True,
# 确保在一个新的控制台窗口中运行,与当前进程完全独立。
creationflags=subprocess.CREATE_NEW_CONSOLE,
)
# 用系统默认应用打开一个文件或目录,不堵塞当前进程
@staticmethod
def startfile(path):
os.startfile(path)