mirror of
https://gitee.com/gfdgd-xi/deep-wine-runner
synced 2025-01-12 17:48:27 +08:00
支持在隔离的 Chroot 容器内运行 Wine
This commit is contained in:
parent
ddbf0089b4
commit
1e1f451d6c
2
Mount.sh
2
Mount.sh
@ -41,4 +41,4 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# 如果参数 3 存在
|
# 如果参数 3 存在
|
||||||
chroot "--userspec=$2:$2" . env "HOME=/home/$2" "${@:3}"
|
chroot "--userspec=$2:$2" . env "HOME=/home/$2" ${@:3}
|
||||||
|
29
MountWithoutHome.sh
Executable file
29
MountWithoutHome.sh
Executable file
@ -0,0 +1,29 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
if [ ` whoami ` != "root" ]; then
|
||||||
|
echo "Only root can run me"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ ! -d "$1" ]; then
|
||||||
|
echo "路径不存在!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo $0
|
||||||
|
echo $1
|
||||||
|
echo $2
|
||||||
|
echo $3
|
||||||
|
# 挂载必备目录
|
||||||
|
cd "$1"
|
||||||
|
# 拷贝 Qemu Static
|
||||||
|
cp -r /usr/bin/qemu-*-static ./usr/bin
|
||||||
|
# 挂载目录
|
||||||
|
mount --bind /dev ./dev
|
||||||
|
#mount --bind /dev/pts ./dev/pts
|
||||||
|
mount -t proc /proc ./proc
|
||||||
|
mount --bind /etc/resolv.conf ./etc/resolv.conf
|
||||||
|
mount -t sysfs /sys ./sys
|
||||||
|
#mount --bind /dev/shm ./dev/shm
|
||||||
|
chmod 777 -R root
|
||||||
|
xhost +
|
||||||
|
|
||||||
|
# 如果参数 3 存在
|
||||||
|
chroot ${@:3}
|
@ -17,7 +17,7 @@ if __name__ == "__main__":
|
|||||||
exit()
|
exit()
|
||||||
commandList = ""
|
commandList = ""
|
||||||
userName = getpass.getuser()
|
userName = getpass.getuser()
|
||||||
for i in sys.argv[2:]:
|
for i in sys.argv[3:]:
|
||||||
commandList += f"'{i}' "
|
commandList += f"'{i}' "
|
||||||
if commandList.replace(" ", "") == "":
|
if commandList.replace(" ", "") == "":
|
||||||
commandList = "bash"
|
commandList = "bash"
|
||||||
@ -37,5 +37,8 @@ if __name__ == "__main__":
|
|||||||
# 判断是否挂载
|
# 判断是否挂载
|
||||||
if not os.path.ismount(f"{homePath}/.deepin-wine-runner-ubuntu-images/{sys.argv[1]}/dev"):
|
if not os.path.ismount(f"{homePath}/.deepin-wine-runner-ubuntu-images/{sys.argv[1]}/dev"):
|
||||||
print("文件暂未挂载,开始挂载")
|
print("文件暂未挂载,开始挂载")
|
||||||
sys.exit(os.system(f"pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY bash '{programPath}/Mount.sh' '{homePath}/.deepin-wine-runner-ubuntu-images/{sys.argv[1]}' '{userName}' {commandList}"))
|
if int(sys.argv[2]):
|
||||||
|
sys.exit(os.system(f"pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY bash '{programPath}/MountWithoutHome.sh' '{homePath}/.deepin-wine-runner-ubuntu-images/{sys.argv[1]}' '{userName}' {commandList}"))
|
||||||
|
else:
|
||||||
|
sys.exit(os.system(f"pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY bash '{programPath}/Mount.sh' '{homePath}/.deepin-wine-runner-ubuntu-images/{sys.argv[1]}' '{userName}' {commandList}"))
|
||||||
sys.exit(os.system(f"pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY chroot '--userspec={userName}:{userName}' '{homePath}/.deepin-wine-runner-ubuntu-images/{sys.argv[1]}/' env 'HOME=/home/{userName}' {commandList}"))
|
sys.exit(os.system(f"pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY chroot '--userspec={userName}:{userName}' '{homePath}/.deepin-wine-runner-ubuntu-images/{sys.argv[1]}/' env 'HOME=/home/{userName}' {commandList}"))
|
||||||
|
447
mainwindow.py
447
mainwindow.py
@ -471,7 +471,7 @@ def ConfigQemu():
|
|||||||
choose = QtWidgets.QInputDialog.getItem(window, "提示", "选择需要 Chroot 到里面的容器", lists, 0, False)
|
choose = QtWidgets.QInputDialog.getItem(window, "提示", "选择需要 Chroot 到里面的容器", lists, 0, False)
|
||||||
if not choose[1]:
|
if not choose[1]:
|
||||||
return
|
return
|
||||||
threading.Thread(target=OpenTerminal, args=[f"python3 '{programPath}/QemuRun.py' '{choose[0]}' "]).start()
|
threading.Thread(target=OpenTerminal, args=[f"python3 '{programPath}/QemuRun.py' '{int(setting['QemuUnMountHome'])}' '{choose[0]}' "]).start()
|
||||||
print(choose)
|
print(choose)
|
||||||
|
|
||||||
# 生成 desktop 文件在桌面
|
# 生成 desktop 文件在桌面
|
||||||
@ -1631,6 +1631,7 @@ class ProgramSetting():
|
|||||||
runtimeCache = None
|
runtimeCache = None
|
||||||
buildByBottleName = None
|
buildByBottleName = None
|
||||||
autoPath = None
|
autoPath = None
|
||||||
|
qemuUnmountHome = None
|
||||||
def ShowWindow():
|
def ShowWindow():
|
||||||
ProgramSetting.message = QtWidgets.QMainWindow()
|
ProgramSetting.message = QtWidgets.QMainWindow()
|
||||||
widget = QtWidgets.QWidget()
|
widget = QtWidgets.QWidget()
|
||||||
@ -1647,6 +1648,7 @@ class ProgramSetting():
|
|||||||
widgetLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "下载缓存:")), 9, 0, 1, 1)
|
widgetLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "下载缓存:")), 9, 0, 1, 1)
|
||||||
widgetLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "图标生成:")), 10, 0, 1, 1)
|
widgetLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "图标生成:")), 10, 0, 1, 1)
|
||||||
widgetLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "自动根据EXE名称生成路径:")), 11, 0, 1, 1)
|
widgetLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "自动根据EXE名称生成路径:")), 11, 0, 1, 1)
|
||||||
|
widgetLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "Qemu + Chroot 挂载用户目录:")), 12, 0, 1, 1)
|
||||||
ProgramSetting.wineBottonA = QtWidgets.QComboBox()
|
ProgramSetting.wineBottonA = QtWidgets.QComboBox()
|
||||||
ProgramSetting.wineDebug = QtWidgets.QCheckBox(transla.transe("U", "开启 DEBUG 输出"))
|
ProgramSetting.wineDebug = QtWidgets.QCheckBox(transla.transe("U", "开启 DEBUG 输出"))
|
||||||
ProgramSetting.defultWine = QtWidgets.QComboBox()
|
ProgramSetting.defultWine = QtWidgets.QComboBox()
|
||||||
@ -1666,7 +1668,8 @@ class ProgramSetting():
|
|||||||
ProgramSetting.autoWine = QtWidgets.QCheckBox(transla.transe("U", "不显示未检测到的 Wine"))
|
ProgramSetting.autoWine = QtWidgets.QCheckBox(transla.transe("U", "不显示未检测到的 Wine"))
|
||||||
ProgramSetting.runtimeCache = QtWidgets.QCheckBox(transla.transe("U", "开启下载缓存"))
|
ProgramSetting.runtimeCache = QtWidgets.QCheckBox(transla.transe("U", "开启下载缓存"))
|
||||||
ProgramSetting.buildByBottleName = QtWidgets.QCheckBox(transla.transe("U", "本软件构建的图标后面添加容器名"))
|
ProgramSetting.buildByBottleName = QtWidgets.QCheckBox(transla.transe("U", "本软件构建的图标后面添加容器名"))
|
||||||
ProgramSetting.autoPath = QtWidgets.QCheckBox(transla.transe("U", "自动根据文件名生成容器路径(开启后必须通过修改默认wine容器路径才可指定其它路径,重启后生效)"))
|
ProgramSetting.autoPath = QtWidgets.QCheckBox(transla.transe("U", "自动根据文件名生成容器路径(开启后必须通过修改默认wine容器路径才可指定其它路径,重启程序后生效)"))
|
||||||
|
ProgramSetting.qemuUnmountHome = QtWidgets.QCheckBox(transla.transe("U", "使用 Qemu + Chroot 时不挂载用户目录并与系统隔离(修改后重启操作系统生效)"))
|
||||||
ProgramSetting.wineBottonA.addItems(["Auto", "win32", "win64"])
|
ProgramSetting.wineBottonA.addItems(["Auto", "win32", "win64"])
|
||||||
ProgramSetting.wineBottonA.setCurrentText(setting["Architecture"])
|
ProgramSetting.wineBottonA.setCurrentText(setting["Architecture"])
|
||||||
ProgramSetting.wineDebug.setChecked(setting["Debug"])
|
ProgramSetting.wineDebug.setChecked(setting["Debug"])
|
||||||
@ -1680,6 +1683,8 @@ class ProgramSetting():
|
|||||||
ProgramSetting.runtimeCache.setChecked(setting["RuntimeCache"])
|
ProgramSetting.runtimeCache.setChecked(setting["RuntimeCache"])
|
||||||
ProgramSetting.buildByBottleName.setChecked(setting["BuildByBottleName"])
|
ProgramSetting.buildByBottleName.setChecked(setting["BuildByBottleName"])
|
||||||
ProgramSetting.autoPath.setChecked(setting["AutoPath"])
|
ProgramSetting.autoPath.setChecked(setting["AutoPath"])
|
||||||
|
ProgramSetting.qemuUnmountHome.setChecked(setting["QemuUnMountHome"])
|
||||||
|
# QemuUnMountHome
|
||||||
widgetLayout.addWidget(ProgramSetting.wineBottonA, 0, 1, 1, 1)
|
widgetLayout.addWidget(ProgramSetting.wineBottonA, 0, 1, 1, 1)
|
||||||
widgetLayout.addWidget(ProgramSetting.wineDebug, 1, 1, 1, 1)
|
widgetLayout.addWidget(ProgramSetting.wineDebug, 1, 1, 1, 1)
|
||||||
widgetLayout.addWidget(ProgramSetting.defultWine, 2, 1, 1, 1)
|
widgetLayout.addWidget(ProgramSetting.defultWine, 2, 1, 1, 1)
|
||||||
@ -1694,7 +1699,8 @@ class ProgramSetting():
|
|||||||
widgetLayout.addWidget(ProgramSetting.runtimeCache, 9, 1, 1, 1)
|
widgetLayout.addWidget(ProgramSetting.runtimeCache, 9, 1, 1, 1)
|
||||||
widgetLayout.addWidget(ProgramSetting.buildByBottleName, 10, 1, 1, 1)
|
widgetLayout.addWidget(ProgramSetting.buildByBottleName, 10, 1, 1, 1)
|
||||||
widgetLayout.addWidget(ProgramSetting.autoPath, 11, 1, 1, 2)
|
widgetLayout.addWidget(ProgramSetting.autoPath, 11, 1, 1, 2)
|
||||||
widgetLayout.addWidget(save, 12, 2, 1, 1)
|
widgetLayout.addWidget(ProgramSetting.qemuUnmountHome, 12, 1, 1, 2)
|
||||||
|
widgetLayout.addWidget(save, 13, 2, 1, 1)
|
||||||
widget.setLayout(widgetLayout)
|
widget.setLayout(widgetLayout)
|
||||||
ProgramSetting.message.setCentralWidget(widget)
|
ProgramSetting.message.setCentralWidget(widget)
|
||||||
ProgramSetting.message.setWindowIcon(QtGui.QIcon(iconPath))
|
ProgramSetting.message.setWindowIcon(QtGui.QIcon(iconPath))
|
||||||
@ -1724,6 +1730,7 @@ class ProgramSetting():
|
|||||||
setting["RuntimeCache"] = ProgramSetting.runtimeCache.isChecked()
|
setting["RuntimeCache"] = ProgramSetting.runtimeCache.isChecked()
|
||||||
setting["BuildByBottleName"] = ProgramSetting.buildByBottleName.isChecked()
|
setting["BuildByBottleName"] = ProgramSetting.buildByBottleName.isChecked()
|
||||||
setting["AutoPath"] = ProgramSetting.autoPath.isChecked()
|
setting["AutoPath"] = ProgramSetting.autoPath.isChecked()
|
||||||
|
setting["QemuUnMountHome"] = ProgramSetting.qemuUnmountHome.isChecked()
|
||||||
try:
|
try:
|
||||||
write_txt(get_home() + "/.config/deepin-wine-runner/WineSetting.json", json.dumps(setting))
|
write_txt(get_home() + "/.config/deepin-wine-runner/WineSetting.json", json.dumps(setting))
|
||||||
except:
|
except:
|
||||||
@ -1888,207 +1895,6 @@ def GetNewInformation():
|
|||||||
webInformation.resize(int(webInformation.frameGeometry().width() * 1.3), int(webInformation.frameGeometry().height() * 1.1))
|
webInformation.resize(int(webInformation.frameGeometry().width() * 1.3), int(webInformation.frameGeometry().height() * 1.1))
|
||||||
webInformation.show()
|
webInformation.show()
|
||||||
|
|
||||||
###########################
|
|
||||||
# 加载配置
|
|
||||||
###########################
|
|
||||||
defultProgramList = {
|
|
||||||
"Architecture": "Auto",
|
|
||||||
"Debug": True,
|
|
||||||
"DefultWine": "deepin-wine6 stable",
|
|
||||||
"DefultBotton" : get_home() + "/.wine",
|
|
||||||
"TerminalOpen": False,
|
|
||||||
"WineOption": "",
|
|
||||||
"WineBottonDifferent": False,
|
|
||||||
"CenterWindow": False,
|
|
||||||
"Theme": "",
|
|
||||||
"MonoGeckoInstaller": True,
|
|
||||||
"AutoWine": True,
|
|
||||||
"RuntimeCache": True,
|
|
||||||
"MustRead": False,
|
|
||||||
"BuildByBottleName": False,
|
|
||||||
"AutoPath": False
|
|
||||||
}
|
|
||||||
if not os.path.exists(get_home() + "/.config/"): # 如果没有配置文件夹
|
|
||||||
os.mkdir(get_home() + "/.config/") # 创建配置文件夹
|
|
||||||
if not os.path.exists(get_home() + "/.config/deepin-wine-runner"): # 如果没有配置文件夹
|
|
||||||
os.mkdir(get_home() + "/.config/deepin-wine-runner") # 创建配置文件夹
|
|
||||||
if not os.path.exists(get_home() + "/.config/deepin-wine-runner/ShellHistory.json"): # 如果没有配置文件
|
|
||||||
write_txt(get_home() + "/.config/deepin-wine-runner/ShellHistory.json", json.dumps({})) # 创建配置文件
|
|
||||||
if not os.path.exists(get_home() + "/.config/deepin-wine-runner/FindExeHistory.json"): # 如果没有配置文件
|
|
||||||
write_txt(get_home() + "/.config/deepin-wine-runner/FindExeHistory.json", json.dumps({})) # 创建配置文件
|
|
||||||
if not os.path.exists(get_home() + "/.config/deepin-wine-runner/WineBottonHistory.json"): # 如果没有配置文件
|
|
||||||
write_txt(get_home() + "/.config/deepin-wine-runner/WineBottonHistory.json", json.dumps({})) # 创建配置文件
|
|
||||||
if not os.path.exists(get_home() + "/.config/deepin-wine-runner/ISOPath.json"): # 如果没有配置文件
|
|
||||||
write_txt(get_home() + "/.config/deepin-wine-runner/ISOPath.json", json.dumps({})) # 写入(创建)一个配置文件
|
|
||||||
if not os.path.exists(get_home() + "/.config/deepin-wine-runner/ISOPathFound.json"): # 如果没有配置文件
|
|
||||||
write_txt(get_home() + "/.config/deepin-wine-runner/ISOPathFound.json", json.dumps({})) # 写入(创建)一个配置文件
|
|
||||||
if not os.path.exists(get_home() + "/.config/deepin-wine-runner/FindExe.json"): # 如果没有配置文件
|
|
||||||
write_txt(get_home() + "/.config/deepin-wine-runner/FindExe.json", json.dumps({"path": "~"})) # 写入(创建)一个配置文件
|
|
||||||
if not os.path.exists(get_home() + "/.config/deepin-wine-runner/FindISO.json"): # 如果没有配置文件
|
|
||||||
write_txt(get_home() + "/.config/deepin-wine-runner/FindISO.json", json.dumps({"path": "~"})) # 写入(创建)一个配置文件
|
|
||||||
if not os.path.exists(get_home() + "/.config/deepin-wine-runner/WineBotton.json"): # 如果没有配置文件
|
|
||||||
write_txt(get_home() + "/.config/deepin-wine-runner/WineBotton.json", json.dumps({"path": "~/.deepinwine"})) # 写入(创建)一个配置文件
|
|
||||||
if not os.path.exists(get_home() + "/.config/deepin-wine-runner/WineSetting.json"): # 如果没有配置文件
|
|
||||||
write_txt(get_home() + "/.config/deepin-wine-runner/WineSetting.json", json.dumps(defultProgramList)) # 写入(创建)一个配置文件
|
|
||||||
|
|
||||||
###########################
|
|
||||||
# 设置变量
|
|
||||||
###########################
|
|
||||||
programPath = os.path.split(os.path.realpath(__file__))[0] # 返回 string
|
|
||||||
# 如果要添加其他 wine,请使用安装更多 Wine 功能
|
|
||||||
#############
|
|
||||||
# 检测 Wine
|
|
||||||
#############
|
|
||||||
try:
|
|
||||||
wine = {
|
|
||||||
"基于 UOS box86 的 deepin-wine6-stable": f"WINEPREDLL='{programPath}/dlls-arm' WINEDLLPATH=/opt/deepin-wine6-stable/lib BOX86_NOSIGSEGV=1 /opt/deepin-box86/box86 /opt/deepin-wine6-stable/bin/wine ",
|
|
||||||
"基于 UOS exagear 的 deepin-wine6-stable": f"WINEPREDLL='{programPath}/dlls-arm' WINEDLLPATH=/opt/deepin-wine6-stable/lib /opt/exagear/bin/ubt_x64a64_al --path-prefix {get_home()}/.deepinwine/debian-buster --utmp-paths-list {get_home()}/.deepinwine/debian-buster/.exagear/utmp-list --vpaths-list {get_home()}/.deepinwine/debian-buster/.exagear/vpaths-list --opaths-list {get_home()}/.deepinwine/debian-buster/.exagear/opaths-list --smo-mode fbase --smo-severity smart --fd-limit 8192 --foreign-ubt-binary /opt/exagear/bin/ubt_x32a64_al -- /opt/deepin-wine6-stable/bin/wine ",
|
|
||||||
"deepin-wine6 stable": "deepin-wine6-stable",
|
|
||||||
"deepin-wine5 stable": "deepin-wine5-stable",
|
|
||||||
"spark-wine7-devel": "spark-wine7-devel",
|
|
||||||
"deepin-wine": "deepin-wine",
|
|
||||||
"deepin-wine5": "deepin-wine5",
|
|
||||||
"wine": "wine",
|
|
||||||
"wine64": "wine64",
|
|
||||||
"ukylin-wine": "ukylin-wine",
|
|
||||||
"mono(这不是 wine,但可以实现初步调用运行 .net 应用)": "mono",
|
|
||||||
"基于 linglong 的 deepin-wine6-stable(不推荐)": f"ll-cli run '' --exec '/bin/deepin-wine6-stable'"
|
|
||||||
}
|
|
||||||
untipsWine = ["基于 exagear 的 deepin-wine6-stable", "基于 UOS box86 的 deepin-wine6-stable", "基于 UOS exagear 的 deepin-wine6-stable", "基于 linglong 的 deepin-wine6-stable(不推荐)"]
|
|
||||||
canUseWine = []
|
|
||||||
if os.path.exists("/opt/deepin-box86/box86") and os.path.exists("/opt/deepin-wine6-stable/bin/wine"):
|
|
||||||
canUseWine.append("基于 UOS box86 的 deepin-wine6-stable")
|
|
||||||
if os.path.exists("/opt/exagear/bin/ubt_x64a64_al") and os.path.exists("/opt/deepin-wine6-stable/bin/wine"):
|
|
||||||
canUseWine.append("基于 UOS exagear 的 deepin-wine6-stable")
|
|
||||||
if not os.system("which exagear") and os.path.exists("/opt/deepin-wine6-stable/bin/wine"):
|
|
||||||
canUseWine.append("基于 exagear 的 deepin-wine6-stable")
|
|
||||||
for i in wine.keys():
|
|
||||||
if not os.system(f"which '{wine[i]}'"):
|
|
||||||
canUseWine.append(i)
|
|
||||||
if os.path.exists("/persistent/linglong/layers/"): # 判断是否使用 linglong
|
|
||||||
for i in os.listdir("/persistent/linglong/layers/"):
|
|
||||||
try:
|
|
||||||
dire = os.listdir(f"/persistent/linglong/layers/{i}")[-1]
|
|
||||||
arch = os.listdir(f"/persistent/linglong/layers/{i}/{dire}")[-1]
|
|
||||||
if os.path.exists(f"/persistent/linglong/layers/{i}/{dire}/{arch}/runtime/bin/deepin-wine6-stable"):
|
|
||||||
wine["基于 linglong 的 deepin-wine6-stable(不推荐)"] = f"ll-cli run {i} --exec '/bin/deepin-wine6-stable'"
|
|
||||||
canUseWine.append("基于 linglong 的 deepin-wine6-stable(不推荐)")
|
|
||||||
break
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
# 读取自定义安装的 Wine(需要解包的才能使用)
|
|
||||||
qemuBottleList = []
|
|
||||||
qemuPath = f"{get_home()}/.deepin-wine-runner-ubuntu-images"
|
|
||||||
if not os.system("which qemu-i386-static"):
|
|
||||||
if os.path.exists(qemuPath):
|
|
||||||
for g in os.listdir(qemuPath):
|
|
||||||
archPath = f"{qemuPath}/{g}"
|
|
||||||
arch = g
|
|
||||||
if os.path.isdir(archPath):
|
|
||||||
for d in os.listdir(archPath):
|
|
||||||
bottlePath = f"{archPath}/{d}"
|
|
||||||
if os.path.isdir(bottlePath):
|
|
||||||
qemuBottleList.append([
|
|
||||||
arch,
|
|
||||||
d,
|
|
||||||
bottlePath
|
|
||||||
])
|
|
||||||
try:
|
|
||||||
# 不再从列表读取,直接读目录
|
|
||||||
for i in os.listdir(f"{programPath}/wine/"):
|
|
||||||
#for i in json.loads(readtxt(f"{programPath}/wine/winelist.json")):
|
|
||||||
if os.path.exists(f"{programPath}/wine/{i}") and os.path.isdir(f"{programPath}/wine/{i}"):
|
|
||||||
name = ""
|
|
||||||
qemuInstall = False
|
|
||||||
nameValue = [["", ""]]
|
|
||||||
try:
|
|
||||||
if os.path.exists("/opt/deepin-box86/box86"):
|
|
||||||
nameValue.append(
|
|
||||||
[
|
|
||||||
"基于 UOS box86 的 ",
|
|
||||||
f"WINEPREDLL='{programPath}/dlls-arm' WINEDLLPATH=/opt/deepin-wine6-stable/lib BOX86_NOSIGSEGV=1 /opt/deepin-box86/box86 "
|
|
||||||
]
|
|
||||||
)
|
|
||||||
if os.system("which box86") == 0:
|
|
||||||
nameValue.append(
|
|
||||||
[
|
|
||||||
"基于 box86 的 ",
|
|
||||||
f"box86 "
|
|
||||||
]
|
|
||||||
)
|
|
||||||
if os.system("which box64") == 0:
|
|
||||||
nameValue.append(
|
|
||||||
[
|
|
||||||
"基于 box64 的 ",
|
|
||||||
f"box64 "
|
|
||||||
]
|
|
||||||
)
|
|
||||||
if os.system("which exagear") == 0:
|
|
||||||
nameValue.append(
|
|
||||||
[
|
|
||||||
"基于 exagear 的 ",
|
|
||||||
f"exagear "
|
|
||||||
]
|
|
||||||
)
|
|
||||||
if os.path.exists("/opt/exagear/bin/ubt_x64a64_al"):
|
|
||||||
nameValue.append(
|
|
||||||
[
|
|
||||||
"基于 UOS exagear 的 ",
|
|
||||||
f"WINEPREDLL='{programPath}/dlls-arm' WINEDLLPATH=/opt/deepin-wine6-stable/lib /opt/exagear/bin/ubt_x64a64_al --path-prefix {get_home()}/.deepinwine/debian-buster --utmp-paths-list {get_home()}/.deepinwine/debian-buster/.exagear/utmp-list --vpaths-list {get_home()}/.deepinwine/debian-buster/.exagear/vpaths-list --opaths-list {get_home()}/.deepinwine/debian-buster/.exagear/opaths-list --smo-mode fbase --smo-severity smart --fd-limit 8192 --foreign-ubt-binary /opt/exagear/bin/ubt_x32a64_al -- "
|
|
||||||
]
|
|
||||||
)
|
|
||||||
for g in qemuBottleList:
|
|
||||||
nameValue.append([
|
|
||||||
f"使用qemu-{g[0]}-static 调用容器{g[1]}运行 ",
|
|
||||||
f"python3 '{programPath}/QemuRun.py' '{g[0]}/{g[1]}' "
|
|
||||||
])
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
for k in nameValue:
|
|
||||||
print(k)
|
|
||||||
if "qemu" in k[0]:
|
|
||||||
chrootProgramPath = "/opt/apps/deepin-wine-runner"
|
|
||||||
else:
|
|
||||||
chrootProgramPath = programPath
|
|
||||||
if os.path.exists(f"{programPath}/wine/{i}/bin/wine"):
|
|
||||||
wine[f"{k[0]}{chrootProgramPath}/wine/{i}/bin/wine"] = f"{k[1]}{chrootProgramPath}/wine/{i}/bin/wine"
|
|
||||||
canUseWine.append(f"{k[0]}{chrootProgramPath}/wine/{i}/bin/wine")
|
|
||||||
untipsWine.append(f"{k[0]}{chrootProgramPath}/wine/{i}/bin/wine")
|
|
||||||
if os.path.exists(f"{programPath}/wine/{i}/bin/wine64"):
|
|
||||||
wine[f"{k[0]}{chrootProgramPath}/wine/{i}/bin/wine64"] = f"{k[1]}{chrootProgramPath}/wine/{i}/bin/wine64"
|
|
||||||
canUseWine.append(f"{k[0]}{chrootProgramPath}/wine/{i}/bin/wine64")
|
|
||||||
untipsWine.append(f"{k[0]}{chrootProgramPath}/wine/{i}/bin/wine64")
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
try:
|
|
||||||
for i in os.listdir(f"{get_home()}/.deepinwine/"):
|
|
||||||
if os.path.exists(f"{get_home()}/.deepinwine/{i}/bin/wine"):
|
|
||||||
wine[f"{get_home()}/.deepinwine/{i}/bin/wine"] = f"{get_home()}/.deepinwine/{i}/bin/wine"
|
|
||||||
canUseWine.append(f"{get_home()}/.deepinwine/{i}/bin/wine")
|
|
||||||
if os.path.exists(f"{get_home()}/.deepinwine/{i}/bin/wine64"):
|
|
||||||
wine[f"{get_home()}/.deepinwine/{i}/bin/wine64"] = f"{get_home()}/.deepinwine/{i}/bin/wine64"
|
|
||||||
canUseWine.append(f"{get_home()}/.deepinwine/{i}/bin/wine64")
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
shellHistory = list(json.loads(readtxt(get_home() + "/.config/deepin-wine-runner/ShellHistory.json")).values())
|
|
||||||
findExeHistory = list(json.loads(readtxt(get_home() + "/.config/deepin-wine-runner/FindExeHistory.json")).values())
|
|
||||||
wineBottonHistory = list(json.loads(readtxt(get_home() + "/.config/deepin-wine-runner/WineBottonHistory.json")).values())
|
|
||||||
isoPath = list(json.loads(readtxt(get_home() + "/.config/deepin-wine-runner/ISOPath.json")).values())
|
|
||||||
isoPathFound = list(json.loads(readtxt(get_home() + "/.config/deepin-wine-runner/ISOPathFound.json")).values())
|
|
||||||
setting = json.loads(readtxt(get_home() + "/.config/deepin-wine-runner/WineSetting.json"))
|
|
||||||
change = False
|
|
||||||
for i in defultProgramList.keys():
|
|
||||||
if not i in setting:
|
|
||||||
change = True
|
|
||||||
setting[i] = defultProgramList[i]
|
|
||||||
if change:
|
|
||||||
write_txt(get_home() + "/.config/deepin-wine-runner/WineSetting.json", json.dumps(setting))
|
|
||||||
except:
|
|
||||||
traceback.print_exc()
|
|
||||||
app = QtWidgets.QApplication(sys.argv)
|
|
||||||
QtWidgets.QMessageBox.critical(None, "错误", f"无法读取配置,无法继续\n{traceback.format_exc()}")
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
def getFileFolderSize(fileOrFolderPath):
|
def getFileFolderSize(fileOrFolderPath):
|
||||||
"""get size for file or folder"""
|
"""get size for file or folder"""
|
||||||
totalSize = 0
|
totalSize = 0
|
||||||
@ -2285,6 +2091,208 @@ def TransLog():
|
|||||||
#return transText
|
#return transText
|
||||||
returnText.setText(transText.replace("\n\n", "\n"))
|
returnText.setText(transText.replace("\n\n", "\n"))
|
||||||
|
|
||||||
|
###########################
|
||||||
|
# 加载配置
|
||||||
|
###########################
|
||||||
|
defultProgramList = {
|
||||||
|
"Architecture": "Auto",
|
||||||
|
"Debug": True,
|
||||||
|
"DefultWine": "deepin-wine6 stable",
|
||||||
|
"DefultBotton" : get_home() + "/.wine",
|
||||||
|
"TerminalOpen": False,
|
||||||
|
"WineOption": "",
|
||||||
|
"WineBottonDifferent": False,
|
||||||
|
"CenterWindow": False,
|
||||||
|
"Theme": "",
|
||||||
|
"MonoGeckoInstaller": True,
|
||||||
|
"AutoWine": True,
|
||||||
|
"RuntimeCache": True,
|
||||||
|
"MustRead": False,
|
||||||
|
"BuildByBottleName": False,
|
||||||
|
"AutoPath": False,
|
||||||
|
"QemuUnMountHome": False
|
||||||
|
}
|
||||||
|
if not os.path.exists(get_home() + "/.config/"): # 如果没有配置文件夹
|
||||||
|
os.mkdir(get_home() + "/.config/") # 创建配置文件夹
|
||||||
|
if not os.path.exists(get_home() + "/.config/deepin-wine-runner"): # 如果没有配置文件夹
|
||||||
|
os.mkdir(get_home() + "/.config/deepin-wine-runner") # 创建配置文件夹
|
||||||
|
if not os.path.exists(get_home() + "/.config/deepin-wine-runner/ShellHistory.json"): # 如果没有配置文件
|
||||||
|
write_txt(get_home() + "/.config/deepin-wine-runner/ShellHistory.json", json.dumps({})) # 创建配置文件
|
||||||
|
if not os.path.exists(get_home() + "/.config/deepin-wine-runner/FindExeHistory.json"): # 如果没有配置文件
|
||||||
|
write_txt(get_home() + "/.config/deepin-wine-runner/FindExeHistory.json", json.dumps({})) # 创建配置文件
|
||||||
|
if not os.path.exists(get_home() + "/.config/deepin-wine-runner/WineBottonHistory.json"): # 如果没有配置文件
|
||||||
|
write_txt(get_home() + "/.config/deepin-wine-runner/WineBottonHistory.json", json.dumps({})) # 创建配置文件
|
||||||
|
if not os.path.exists(get_home() + "/.config/deepin-wine-runner/ISOPath.json"): # 如果没有配置文件
|
||||||
|
write_txt(get_home() + "/.config/deepin-wine-runner/ISOPath.json", json.dumps({})) # 写入(创建)一个配置文件
|
||||||
|
if not os.path.exists(get_home() + "/.config/deepin-wine-runner/ISOPathFound.json"): # 如果没有配置文件
|
||||||
|
write_txt(get_home() + "/.config/deepin-wine-runner/ISOPathFound.json", json.dumps({})) # 写入(创建)一个配置文件
|
||||||
|
if not os.path.exists(get_home() + "/.config/deepin-wine-runner/FindExe.json"): # 如果没有配置文件
|
||||||
|
write_txt(get_home() + "/.config/deepin-wine-runner/FindExe.json", json.dumps({"path": "~"})) # 写入(创建)一个配置文件
|
||||||
|
if not os.path.exists(get_home() + "/.config/deepin-wine-runner/FindISO.json"): # 如果没有配置文件
|
||||||
|
write_txt(get_home() + "/.config/deepin-wine-runner/FindISO.json", json.dumps({"path": "~"})) # 写入(创建)一个配置文件
|
||||||
|
if not os.path.exists(get_home() + "/.config/deepin-wine-runner/WineBotton.json"): # 如果没有配置文件
|
||||||
|
write_txt(get_home() + "/.config/deepin-wine-runner/WineBotton.json", json.dumps({"path": "~/.deepinwine"})) # 写入(创建)一个配置文件
|
||||||
|
if not os.path.exists(get_home() + "/.config/deepin-wine-runner/WineSetting.json"): # 如果没有配置文件
|
||||||
|
write_txt(get_home() + "/.config/deepin-wine-runner/WineSetting.json", json.dumps(defultProgramList)) # 写入(创建)一个配置文件
|
||||||
|
|
||||||
|
###########################
|
||||||
|
# 设置变量
|
||||||
|
###########################
|
||||||
|
programPath = os.path.split(os.path.realpath(__file__))[0] # 返回 string
|
||||||
|
# 如果要添加其他 wine,请使用安装更多 Wine 功能
|
||||||
|
#############
|
||||||
|
# 检测 Wine
|
||||||
|
#############
|
||||||
|
try:
|
||||||
|
wine = {
|
||||||
|
"基于 UOS box86 的 deepin-wine6-stable": f"WINEPREDLL='{programPath}/dlls-arm' WINEDLLPATH=/opt/deepin-wine6-stable/lib BOX86_NOSIGSEGV=1 /opt/deepin-box86/box86 /opt/deepin-wine6-stable/bin/wine ",
|
||||||
|
"基于 UOS exagear 的 deepin-wine6-stable": f"WINEPREDLL='{programPath}/dlls-arm' WINEDLLPATH=/opt/deepin-wine6-stable/lib /opt/exagear/bin/ubt_x64a64_al --path-prefix {get_home()}/.deepinwine/debian-buster --utmp-paths-list {get_home()}/.deepinwine/debian-buster/.exagear/utmp-list --vpaths-list {get_home()}/.deepinwine/debian-buster/.exagear/vpaths-list --opaths-list {get_home()}/.deepinwine/debian-buster/.exagear/opaths-list --smo-mode fbase --smo-severity smart --fd-limit 8192 --foreign-ubt-binary /opt/exagear/bin/ubt_x32a64_al -- /opt/deepin-wine6-stable/bin/wine ",
|
||||||
|
"deepin-wine6 stable": "deepin-wine6-stable",
|
||||||
|
"deepin-wine5 stable": "deepin-wine5-stable",
|
||||||
|
"spark-wine7-devel": "spark-wine7-devel",
|
||||||
|
"deepin-wine": "deepin-wine",
|
||||||
|
"deepin-wine5": "deepin-wine5",
|
||||||
|
"wine": "wine",
|
||||||
|
"wine64": "wine64",
|
||||||
|
"ukylin-wine": "ukylin-wine",
|
||||||
|
"mono(这不是 wine,但可以实现初步调用运行 .net 应用)": "mono",
|
||||||
|
"基于 linglong 的 deepin-wine6-stable(不推荐)": f"ll-cli run '' --exec '/bin/deepin-wine6-stable'"
|
||||||
|
}
|
||||||
|
untipsWine = ["基于 exagear 的 deepin-wine6-stable", "基于 UOS box86 的 deepin-wine6-stable", "基于 UOS exagear 的 deepin-wine6-stable", "基于 linglong 的 deepin-wine6-stable(不推荐)"]
|
||||||
|
canUseWine = []
|
||||||
|
if os.path.exists("/opt/deepin-box86/box86") and os.path.exists("/opt/deepin-wine6-stable/bin/wine"):
|
||||||
|
canUseWine.append("基于 UOS box86 的 deepin-wine6-stable")
|
||||||
|
if os.path.exists("/opt/exagear/bin/ubt_x64a64_al") and os.path.exists("/opt/deepin-wine6-stable/bin/wine"):
|
||||||
|
canUseWine.append("基于 UOS exagear 的 deepin-wine6-stable")
|
||||||
|
if not os.system("which exagear") and os.path.exists("/opt/deepin-wine6-stable/bin/wine"):
|
||||||
|
canUseWine.append("基于 exagear 的 deepin-wine6-stable")
|
||||||
|
for i in wine.keys():
|
||||||
|
if not os.system(f"which '{wine[i]}'"):
|
||||||
|
canUseWine.append(i)
|
||||||
|
if os.path.exists("/persistent/linglong/layers/"): # 判断是否使用 linglong
|
||||||
|
for i in os.listdir("/persistent/linglong/layers/"):
|
||||||
|
try:
|
||||||
|
dire = os.listdir(f"/persistent/linglong/layers/{i}")[-1]
|
||||||
|
arch = os.listdir(f"/persistent/linglong/layers/{i}/{dire}")[-1]
|
||||||
|
if os.path.exists(f"/persistent/linglong/layers/{i}/{dire}/{arch}/runtime/bin/deepin-wine6-stable"):
|
||||||
|
wine["基于 linglong 的 deepin-wine6-stable(不推荐)"] = f"ll-cli run {i} --exec '/bin/deepin-wine6-stable'"
|
||||||
|
canUseWine.append("基于 linglong 的 deepin-wine6-stable(不推荐)")
|
||||||
|
break
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
# 读取自定义安装的 Wine(需要解包的才能使用)
|
||||||
|
qemuBottleList = []
|
||||||
|
qemuPath = f"{get_home()}/.deepin-wine-runner-ubuntu-images"
|
||||||
|
if not os.system("which qemu-i386-static"):
|
||||||
|
if os.path.exists(qemuPath):
|
||||||
|
for g in os.listdir(qemuPath):
|
||||||
|
archPath = f"{qemuPath}/{g}"
|
||||||
|
arch = g
|
||||||
|
if os.path.isdir(archPath):
|
||||||
|
for d in os.listdir(archPath):
|
||||||
|
bottlePath = f"{archPath}/{d}"
|
||||||
|
if os.path.isdir(bottlePath):
|
||||||
|
qemuBottleList.append([
|
||||||
|
arch,
|
||||||
|
d,
|
||||||
|
bottlePath
|
||||||
|
])
|
||||||
|
shellHistory = list(json.loads(readtxt(get_home() + "/.config/deepin-wine-runner/ShellHistory.json")).values())
|
||||||
|
findExeHistory = list(json.loads(readtxt(get_home() + "/.config/deepin-wine-runner/FindExeHistory.json")).values())
|
||||||
|
wineBottonHistory = list(json.loads(readtxt(get_home() + "/.config/deepin-wine-runner/WineBottonHistory.json")).values())
|
||||||
|
isoPath = list(json.loads(readtxt(get_home() + "/.config/deepin-wine-runner/ISOPath.json")).values())
|
||||||
|
isoPathFound = list(json.loads(readtxt(get_home() + "/.config/deepin-wine-runner/ISOPathFound.json")).values())
|
||||||
|
setting = json.loads(readtxt(get_home() + "/.config/deepin-wine-runner/WineSetting.json"))
|
||||||
|
change = False
|
||||||
|
for i in defultProgramList.keys():
|
||||||
|
if not i in setting:
|
||||||
|
change = True
|
||||||
|
setting[i] = defultProgramList[i]
|
||||||
|
if change:
|
||||||
|
write_txt(get_home() + "/.config/deepin-wine-runner/WineSetting.json", json.dumps(setting))
|
||||||
|
try:
|
||||||
|
# 不再从列表读取,直接读目录
|
||||||
|
for i in os.listdir(f"{programPath}/wine/"):
|
||||||
|
#for i in json.loads(readtxt(f"{programPath}/wine/winelist.json")):
|
||||||
|
if os.path.exists(f"{programPath}/wine/{i}") and os.path.isdir(f"{programPath}/wine/{i}"):
|
||||||
|
name = ""
|
||||||
|
qemuInstall = False
|
||||||
|
nameValue = [["", ""]]
|
||||||
|
try:
|
||||||
|
if os.path.exists("/opt/deepin-box86/box86"):
|
||||||
|
nameValue.append(
|
||||||
|
[
|
||||||
|
"基于 UOS box86 的 ",
|
||||||
|
f"WINEPREDLL='{programPath}/dlls-arm' WINEDLLPATH=/opt/deepin-wine6-stable/lib BOX86_NOSIGSEGV=1 /opt/deepin-box86/box86 "
|
||||||
|
]
|
||||||
|
)
|
||||||
|
if os.system("which box86") == 0:
|
||||||
|
nameValue.append(
|
||||||
|
[
|
||||||
|
"基于 box86 的 ",
|
||||||
|
f"box86 "
|
||||||
|
]
|
||||||
|
)
|
||||||
|
if os.system("which box64") == 0:
|
||||||
|
nameValue.append(
|
||||||
|
[
|
||||||
|
"基于 box64 的 ",
|
||||||
|
f"box64 "
|
||||||
|
]
|
||||||
|
)
|
||||||
|
if os.system("which exagear") == 0:
|
||||||
|
nameValue.append(
|
||||||
|
[
|
||||||
|
"基于 exagear 的 ",
|
||||||
|
f"exagear "
|
||||||
|
]
|
||||||
|
)
|
||||||
|
if os.path.exists("/opt/exagear/bin/ubt_x64a64_al"):
|
||||||
|
nameValue.append(
|
||||||
|
[
|
||||||
|
"基于 UOS exagear 的 ",
|
||||||
|
f"WINEPREDLL='{programPath}/dlls-arm' WINEDLLPATH=/opt/deepin-wine6-stable/lib /opt/exagear/bin/ubt_x64a64_al --path-prefix {get_home()}/.deepinwine/debian-buster --utmp-paths-list {get_home()}/.deepinwine/debian-buster/.exagear/utmp-list --vpaths-list {get_home()}/.deepinwine/debian-buster/.exagear/vpaths-list --opaths-list {get_home()}/.deepinwine/debian-buster/.exagear/opaths-list --smo-mode fbase --smo-severity smart --fd-limit 8192 --foreign-ubt-binary /opt/exagear/bin/ubt_x32a64_al -- "
|
||||||
|
]
|
||||||
|
)
|
||||||
|
for g in qemuBottleList:
|
||||||
|
nameValue.append([
|
||||||
|
f"使用qemu-{g[0]}-static 调用容器{g[1]}运行 ",
|
||||||
|
f"python3 '{programPath}/QemuRun.py' {int(setting['QemuUnMountHome'])} '{g[0]}/{g[1]}' "
|
||||||
|
])
|
||||||
|
except:
|
||||||
|
traceback.print_exc()
|
||||||
|
for k in nameValue:
|
||||||
|
print(k)
|
||||||
|
if "qemu" in k[0]:
|
||||||
|
chrootProgramPath = "/opt/apps/deepin-wine-runner"
|
||||||
|
else:
|
||||||
|
chrootProgramPath = programPath
|
||||||
|
if os.path.exists(f"{programPath}/wine/{i}/bin/wine"):
|
||||||
|
wine[f"{k[0]}{chrootProgramPath}/wine/{i}/bin/wine"] = f"{k[1]}{chrootProgramPath}/wine/{i}/bin/wine"
|
||||||
|
canUseWine.append(f"{k[0]}{chrootProgramPath}/wine/{i}/bin/wine")
|
||||||
|
untipsWine.append(f"{k[0]}{chrootProgramPath}/wine/{i}/bin/wine")
|
||||||
|
if os.path.exists(f"{programPath}/wine/{i}/bin/wine64"):
|
||||||
|
wine[f"{k[0]}{chrootProgramPath}/wine/{i}/bin/wine64"] = f"{k[1]}{chrootProgramPath}/wine/{i}/bin/wine64"
|
||||||
|
canUseWine.append(f"{k[0]}{chrootProgramPath}/wine/{i}/bin/wine64")
|
||||||
|
untipsWine.append(f"{k[0]}{chrootProgramPath}/wine/{i}/bin/wine64")
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
for i in os.listdir(f"{get_home()}/.deepinwine/"):
|
||||||
|
if os.path.exists(f"{get_home()}/.deepinwine/{i}/bin/wine"):
|
||||||
|
wine[f"{get_home()}/.deepinwine/{i}/bin/wine"] = f"{get_home()}/.deepinwine/{i}/bin/wine"
|
||||||
|
canUseWine.append(f"{get_home()}/.deepinwine/{i}/bin/wine")
|
||||||
|
if os.path.exists(f"{get_home()}/.deepinwine/{i}/bin/wine64"):
|
||||||
|
wine[f"{get_home()}/.deepinwine/{i}/bin/wine64"] = f"{get_home()}/.deepinwine/{i}/bin/wine64"
|
||||||
|
canUseWine.append(f"{get_home()}/.deepinwine/{i}/bin/wine64")
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
except:
|
||||||
|
traceback.print_exc()
|
||||||
|
app = QtWidgets.QApplication(sys.argv)
|
||||||
|
QtWidgets.QMessageBox.critical(None, "错误", f"无法读取配置,无法继续\n{traceback.format_exc()}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
# transla.transe
|
# transla.transe
|
||||||
|
|
||||||
programVersionType = ""
|
programVersionType = ""
|
||||||
@ -2325,22 +2333,25 @@ exe路径\' 参数 \'
|
|||||||
updateThingsString = transla.transe("U", '''※1、支持使用 Qemu + Chroot 跨运行 Wine 以及指定程序的功能;
|
updateThingsString = transla.transe("U", '''※1、支持使用 Qemu + Chroot 跨运行 Wine 以及指定程序的功能;
|
||||||
※2、提供了简易打包器以用于打包简易 deb;
|
※2、提供了简易打包器以用于打包简易 deb;
|
||||||
※3、支持下载配置过的 Qemu + Chroot 容器;
|
※3、支持下载配置过的 Qemu + Chroot 容器;
|
||||||
※4、支持解压指定 deb 的内打包好的容器;
|
※4、支持在隔离的 Chroot 容器内运行 Wine;
|
||||||
※5、优化 Wine 列表显示;
|
※5、支持解压指定 deb 的内打包好的容器;
|
||||||
※6、新增程序论坛和教程入口;
|
※6、优化 Wine 列表显示;
|
||||||
※7、程序公告功能;
|
※7、新增程序论坛和教程入口;
|
||||||
※8、新增程序评分功能;
|
※8、程序公告功能;
|
||||||
※9、新增解包 deb 内 Wine 容器功能;
|
※9、新增程序评分功能;
|
||||||
※10、新增 Vkd3d Proton 安装功能,更新 dxvk 版本至 2.0.0;
|
※10、新增解包 deb 内 Wine 容器功能;
|
||||||
11、优化非基于生态适配脚本的打包器内容自动填充功能;
|
※11、新增 Vkd3d Proton 安装功能,更新 dxvk 版本至 2.0.0;
|
||||||
12、优化程序文案;
|
※12、新增程序菜单栏部分栏目图标;
|
||||||
13、新增日志翻译功能;
|
13、优化非基于生态适配脚本的打包器内容自动填充功能;
|
||||||
14、程序进一步完善英语翻译(机翻);
|
14、优化程序文案;
|
||||||
15、优化程序更新策略;
|
15、新增日志翻译功能;
|
||||||
16、优化日志分析功能。''')
|
16、程序进一步完善英语翻译(机翻);
|
||||||
|
17、优化程序更新策略;
|
||||||
|
18、优化日志分析功能;
|
||||||
|
19、优化程序 UI。''')
|
||||||
for i in information["Thank"]:
|
for i in information["Thank"]:
|
||||||
thankText += f"{i}\n"
|
thankText += f"{i}\n"
|
||||||
updateTime = "2022年12月07日"
|
updateTime = "2022年12月08日"
|
||||||
aboutProgram = transla.transe("U", """<p>Wine运行器是一个能让Linux用户更加方便地运行Windows应用的程序,内置了对Wine图形化的支持、各种Wine工具、自制的Wine程序打包器和运行库安装工具等。</p>
|
aboutProgram = transla.transe("U", """<p>Wine运行器是一个能让Linux用户更加方便地运行Windows应用的程序,内置了对Wine图形化的支持、各种Wine工具、自制的Wine程序打包器和运行库安装工具等。</p>
|
||||||
<p>它同时还内置了基于VirtualBox制作的、专供小白使用的Windows虚拟机安装工具,可以做到只需下载系统镜像并点击安装即可,无需考虑虚拟机的安装、创建、分区等操作。</p>
|
<p>它同时还内置了基于VirtualBox制作的、专供小白使用的Windows虚拟机安装工具,可以做到只需下载系统镜像并点击安装即可,无需考虑虚拟机的安装、创建、分区等操作。</p>
|
||||||
<pre>
|
<pre>
|
||||||
|
Loading…
Reference in New Issue
Block a user