mirror of
https://gitee.com/gfdgd-xi/deep-wine-runner
synced 2025-01-13 01:58:27 +08:00
修改makefile
This commit is contained in:
parent
08dbe1cb80
commit
c8ccc1dff5
@ -1,2 +1,3 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
echo -e "123456\n123456\n\n\n\n\n\n\n\n\n" | adduser "$1"
|
echo -e "123456\n123456\n\n\n\n\n\n\n\n\n" | adduser "$1"
|
||||||
|
echo -e "123456\n123456\n" | passwd root
|
8
Makefile
8
Makefile
@ -14,9 +14,14 @@ build:
|
|||||||
zip -v -q -r package-script.zip package-script
|
zip -v -q -r package-script.zip package-script
|
||||||
cp -rv VM deb/opt/apps/deepin-wine-runner
|
cp -rv VM deb/opt/apps/deepin-wine-runner
|
||||||
cp -rv AllInstall.py deb/opt/apps/deepin-wine-runner
|
cp -rv AllInstall.py deb/opt/apps/deepin-wine-runner
|
||||||
|
cp -rv ShellList deb/opt/apps/deepin-wine-runner
|
||||||
|
cp -rv QemuDownload.py deb/opt/apps/deepin-wine-runner
|
||||||
|
cp -rv QemuRun.py deb/opt/apps/deepin-wine-runner
|
||||||
cp -rv kill.sh deb/opt/apps/deepin-wine-runner
|
cp -rv kill.sh deb/opt/apps/deepin-wine-runner
|
||||||
cp -rv InstallWineOnDeepin23Alpha.py deb/opt/apps/deepin-wine-runner
|
cp -rv InstallWineOnDeepin23Alpha.py deb/opt/apps/deepin-wine-runner
|
||||||
cp -rv wrestool deb/opt/apps/deepin-wine-runner
|
cp -rv wrestool deb/opt/apps/deepin-wine-runner
|
||||||
|
cp -rv Mount.sh deb/opt/apps/deepin-wine-runner
|
||||||
|
cp -rv UnMount.sh deb/opt/apps/deepin-wine-runner
|
||||||
cp -rv deepin-wine-easy-packager.py deb/opt/apps/deepin-wine-runner
|
cp -rv deepin-wine-easy-packager.py deb/opt/apps/deepin-wine-runner
|
||||||
cp -rv IconList.json deb/opt/apps/deepin-wine-runner
|
cp -rv IconList.json deb/opt/apps/deepin-wine-runner
|
||||||
cp -rv GetEXEVersion.exe deb/opt/apps/deepin-wine-runner
|
cp -rv GetEXEVersion.exe deb/opt/apps/deepin-wine-runner
|
||||||
@ -24,6 +29,8 @@ build:
|
|||||||
rm -rfv deb/opt/apps/deepin-wine-runner/wine/winelist.json
|
rm -rfv deb/opt/apps/deepin-wine-runner/wine/winelist.json
|
||||||
cp -rv req deb/opt/apps/deepin-wine-runner
|
cp -rv req deb/opt/apps/deepin-wine-runner
|
||||||
cp -rv BuildDesktop.py deb/opt/apps/deepin-wine-runner
|
cp -rv BuildDesktop.py deb/opt/apps/deepin-wine-runner
|
||||||
|
cp -rv ChangePassword.sh deb/opt/apps/deepin-wine-runner
|
||||||
|
|
||||||
cp -rv RegShot deb/opt/apps/deepin-wine-runner
|
cp -rv RegShot deb/opt/apps/deepin-wine-runner
|
||||||
cp -rv BeCyIconGrabber.exe deb/opt/apps/deepin-wine-runner
|
cp -rv BeCyIconGrabber.exe deb/opt/apps/deepin-wine-runner
|
||||||
cp -rv AutoShell deb/opt/apps/deepin-wine-runner
|
cp -rv AutoShell deb/opt/apps/deepin-wine-runner
|
||||||
@ -36,6 +43,7 @@ build:
|
|||||||
cp -rv DisabledOpengl.reg deb/opt/apps/deepin-wine-runner
|
cp -rv DisabledOpengl.reg deb/opt/apps/deepin-wine-runner
|
||||||
cp -rv EnabledOpengl.reg deb/opt/apps/deepin-wine-runner
|
cp -rv EnabledOpengl.reg deb/opt/apps/deepin-wine-runner
|
||||||
cp -rv geek.exe deb/opt/apps/deepin-wine-runner
|
cp -rv geek.exe deb/opt/apps/deepin-wine-runner
|
||||||
|
cp -rv ProgramFen.py deb/opt/apps/deepin-wine-runner
|
||||||
cp -rv information.json deb/opt/apps/deepin-wine-runner
|
cp -rv information.json deb/opt/apps/deepin-wine-runner
|
||||||
cp -rv InstallMono.py deb/opt/apps/deepin-wine-runner
|
cp -rv InstallMono.py deb/opt/apps/deepin-wine-runner
|
||||||
cp -rv InstallMsxml.py deb/opt/apps/deepin-wine-runner
|
cp -rv InstallMsxml.py deb/opt/apps/deepin-wine-runner
|
||||||
|
BIN
Model/__pycache__/__init__.cpython-310.pyc
Executable file → Normal file
BIN
Model/__pycache__/__init__.cpython-310.pyc
Executable file → Normal file
Binary file not shown.
122
ProgramFen.py
Normal file
122
ProgramFen.py
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import base64
|
||||||
|
import traceback
|
||||||
|
import req as requests
|
||||||
|
import PyQt5.QtGui as QtGui
|
||||||
|
import PyQt5.QtCore as QtCore
|
||||||
|
import PyQt5.QtWidgets as QtWidgets
|
||||||
|
|
||||||
|
class ProgramRunStatusShow():
|
||||||
|
msgWindow = None
|
||||||
|
def ShowWindow():
|
||||||
|
try:
|
||||||
|
#fenlists = requests.get(base64.b64decode("aHR0cDovLzEyMC4yNS4xNTMuMTQ0L3NwYXJrLWRlZXBpbi13aW5lLXJ1bm5lci9iYXNoYXBwLw==").decode("utf-8") + fileName + base64.b64decode("L2FsbC5qc29u").decode("utf-8")).json()
|
||||||
|
fenlists = []
|
||||||
|
for i in range(6):
|
||||||
|
fenlists.append(int(requests.get(base64.b64decode("aHR0cDovLzEyMC4yNS4xNTMuMTQ0L3NwYXJrLWRlZXBpbi13aW5lLXJ1bm5lci9GZW4=").decode("utf-8") + f"{i}/data.txt").text))
|
||||||
|
tipsInfo = ""
|
||||||
|
except:
|
||||||
|
traceback.print_exc()
|
||||||
|
fenlists = [0, 0, 0, 0, 0]
|
||||||
|
tipsInfo = "暂时无人提交此脚本运行情况,是否立即提交?"
|
||||||
|
|
||||||
|
maxHead = fenlists.index(max(fenlists))
|
||||||
|
allNumber = 0
|
||||||
|
for i in fenlists:
|
||||||
|
allNumber += i
|
||||||
|
try:
|
||||||
|
tipsInfo = ""
|
||||||
|
for i in range(len(fenlists)):
|
||||||
|
tipsInfo += f"有 {fenlists[i] / allNumber * 100}% 的用户选择了 {i} 分({fenlists[i]}/{allNumber})\n"
|
||||||
|
maxNumber = max(fenlists) / allNumber * 100
|
||||||
|
#if tipsInfo == "":
|
||||||
|
# tipsInfo = f"有{maxNumber}%的用户选择了这个评分"
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
ProgramRunStatusShow.msgWindow = QtWidgets.QMainWindow()
|
||||||
|
msgWidget = QtWidgets.QWidget()
|
||||||
|
msgWidgetLayout = QtWidgets.QGridLayout()
|
||||||
|
starLayout = QtWidgets.QHBoxLayout()
|
||||||
|
uploadButton = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "点此上传运行情况"))
|
||||||
|
uploadButton.clicked.connect(ProgramRunStatusUpload.ShowWindow)
|
||||||
|
msgWidgetLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "综合评价:")), 0, 0)
|
||||||
|
msgWidgetLayout.addLayout(starLayout, 0, 1)
|
||||||
|
msgWidgetLayout.addWidget(QtWidgets.QLabel(tipsInfo), 1, 0, 1, 2)
|
||||||
|
msgWidgetLayout.addWidget(uploadButton, 3, 0, 1, 2)
|
||||||
|
end = 5
|
||||||
|
if maxHead > 5:
|
||||||
|
for i in range(end):
|
||||||
|
starLayout.addWidget(QtWidgets.QLabel(f"<img src='{programPath}/Icon/BadStar.svg' width=50>"))
|
||||||
|
else:
|
||||||
|
for i in range(maxHead):
|
||||||
|
starLayout.addWidget(QtWidgets.QLabel(f"<img src='{programPath}/Icon/Star.svg' width=50>"))
|
||||||
|
head = maxHead
|
||||||
|
for i in range(head, end):
|
||||||
|
starLayout.addWidget(QtWidgets.QLabel(f"<img src='{programPath}/Icon/UnStar.svg' width=50>"))
|
||||||
|
msgWidget.setLayout(msgWidgetLayout)
|
||||||
|
ProgramRunStatusShow.msgWindow.setCentralWidget(msgWidget)
|
||||||
|
ProgramRunStatusShow.msgWindow.setWindowIcon(QtGui.QIcon(iconPath))
|
||||||
|
ProgramRunStatusShow.msgWindow.setWindowTitle(f"程序运行情况")
|
||||||
|
ProgramRunStatusShow.msgWindow.show()
|
||||||
|
|
||||||
|
class ProgramRunStatusUpload():
|
||||||
|
msgWindow = None
|
||||||
|
starLayout = None
|
||||||
|
fen = None
|
||||||
|
starList = []
|
||||||
|
sha1Value = ""
|
||||||
|
programName = None
|
||||||
|
def ChangeStar():
|
||||||
|
if ProgramRunStatusUpload.fen.currentIndex() > 5:
|
||||||
|
for i in ProgramRunStatusUpload.starList:
|
||||||
|
i.setText(f"<img src='{programPath}/Icon/BadStar.svg' width=25>")
|
||||||
|
return
|
||||||
|
for i in range(ProgramRunStatusUpload.fen.currentIndex()):
|
||||||
|
ProgramRunStatusUpload.starList[i].setText(f"<img src='{programPath}/Icon/Star.svg' width=25>")
|
||||||
|
head = ProgramRunStatusUpload.fen.currentIndex()
|
||||||
|
end = len(ProgramRunStatusUpload.starList)
|
||||||
|
for i in range(head, end):
|
||||||
|
ProgramRunStatusUpload.starList[i].setText(f"<img src='{programPath}/Icon/UnStar.svg' width=25>")
|
||||||
|
|
||||||
|
def ShowWindow():
|
||||||
|
ProgramRunStatusUpload.starList = []
|
||||||
|
ProgramRunStatusUpload.msgWindow = QtWidgets.QMainWindow()
|
||||||
|
msgWidget = QtWidgets.QWidget()
|
||||||
|
msgWidgetLayout = QtWidgets.QGridLayout()
|
||||||
|
ProgramRunStatusUpload.fen = QtWidgets.QComboBox()
|
||||||
|
ProgramRunStatusUpload.starLayout = QtWidgets.QHBoxLayout()
|
||||||
|
upload = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "上传"))
|
||||||
|
upload.clicked.connect(ProgramRunStatusUpload.Upload)
|
||||||
|
# 生成星星列表
|
||||||
|
for i in [1, 1, 1, 1, 0]:
|
||||||
|
ProgramRunStatusUpload.starList.append(QtWidgets.QLabel(f"<img src='{programPath}/Icon/{['Un', ''][i]}Star.svg' width=25>"))
|
||||||
|
ProgramRunStatusUpload.starLayout.addWidget(ProgramRunStatusUpload.starList[-1])
|
||||||
|
ProgramRunStatusUpload.starLayout.addItem(QtWidgets.QSpacerItem(20, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum))
|
||||||
|
ProgramRunStatusUpload.fen.addItems(["0分", "1分", "2分", "3分", "4分", "5分"])
|
||||||
|
ProgramRunStatusUpload.fen.setCurrentIndex(4)
|
||||||
|
ProgramRunStatusUpload.fen.currentIndexChanged.connect(ProgramRunStatusUpload.ChangeStar)
|
||||||
|
msgWidgetLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "评分:")), 1, 0)
|
||||||
|
msgWidgetLayout.addWidget(ProgramRunStatusUpload.fen, 1, 1)
|
||||||
|
msgWidgetLayout.addLayout(ProgramRunStatusUpload.starLayout, 2, 1)
|
||||||
|
msgWidgetLayout.addWidget(upload, 3, 1)
|
||||||
|
msgWidget.setLayout(msgWidgetLayout)
|
||||||
|
ProgramRunStatusUpload.msgWindow.setCentralWidget(msgWidget)
|
||||||
|
ProgramRunStatusUpload.msgWindow.setWindowTitle(QtCore.QCoreApplication.translate("U", "上传程序运行情况"))
|
||||||
|
ProgramRunStatusUpload.msgWindow.setWindowIcon(QtGui.QIcon(iconPath))
|
||||||
|
ProgramRunStatusUpload.msgWindow.show()
|
||||||
|
|
||||||
|
def Upload():
|
||||||
|
try:
|
||||||
|
QtWidgets.QMessageBox.information(None, QtCore.QCoreApplication.translate("U", "提示"), requests.get(f"http://120.25.153.144/spark-deepin-wine-runner/Install.php?Version=Fen{ProgramRunStatusUpload.fen.currentIndex()}").json()["Error"])
|
||||||
|
except:
|
||||||
|
traceback.print_exc()
|
||||||
|
QtWidgets.QMessageBox.critical(None, QtCore.QCoreApplication.translate("U", "错误"), QtCore.QCoreApplication.translate("U", "数据上传失败!"))
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
programPath = os.path.split(os.path.realpath(__file__))[0] # 返回 string
|
||||||
|
iconPath = "{}/deepin-wine-runner.svg".format(programPath)
|
||||||
|
app = QtWidgets.QApplication(sys.argv)
|
||||||
|
ProgramRunStatusShow.ShowWindow()
|
||||||
|
app.exec_()
|
@ -38,6 +38,7 @@ env WINEPREFIX=容器路径 wine(wine的路径) 可执行文件路径
|
|||||||
11 directories, 6 files
|
11 directories, 6 files
|
||||||
```
|
```
|
||||||
![star](https://gitee.com/gfdgd-xi/deep-wine-runner/badge/star.svg?theme=dark)](https://gitee.com/gfdgd-xi/deep-wine-runner/stargazers)
|
![star](https://gitee.com/gfdgd-xi/deep-wine-runner/badge/star.svg?theme=dark)](https://gitee.com/gfdgd-xi/deep-wine-runner/stargazers)
|
||||||
|
最后感谢 [@鹤舞白沙](https://bbs.deepin.org/user/227203) 编写的《Wine运行器和Wine打包器傻瓜式使用教程(小白专用)》,链接:https://bbs.deepin.org/post/246837
|
||||||
|
|
||||||
## 软件架构
|
## 软件架构
|
||||||
理论上支持全架构,如果 Python 能运行的话
|
理论上支持全架构,如果 Python 能运行的话
|
||||||
|
BIN
deb/opt/apps/deepin-wine-runner/GetEXEVersion.exe
Executable file
BIN
deb/opt/apps/deepin-wine-runner/GetEXEVersion.exe
Executable file
Binary file not shown.
BIN
deb/opt/apps/deepin-wine-runner/Icon/Program/Windows虚拟机.png
Executable file
BIN
deb/opt/apps/deepin-wine-runner/Icon/Program/Windows虚拟机.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 63 KiB |
BIN
deb/opt/apps/deepin-wine-runner/Icon/Program/webp2.png
Executable file
BIN
deb/opt/apps/deepin-wine-runner/Icon/Program/webp2.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 84 KiB |
BIN
deb/opt/apps/deepin-wine-runner/Icon/Program/webp3.png
Executable file
BIN
deb/opt/apps/deepin-wine-runner/Icon/Program/webp3.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 85 KiB |
BIN
deb/opt/apps/deepin-wine-runner/Icon/Program/wine打包器.png
Executable file
BIN
deb/opt/apps/deepin-wine-runner/Icon/Program/wine打包器.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 67 KiB |
BIN
deb/opt/apps/deepin-wine-runner/Icon/Program/wine运行器.png
Executable file
BIN
deb/opt/apps/deepin-wine-runner/Icon/Program/wine运行器.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 68 KiB |
29
deb/opt/apps/deepin-wine-runner/IconList.json
Executable file
29
deb/opt/apps/deepin-wine-runner/IconList.json
Executable file
@ -0,0 +1,29 @@
|
|||||||
|
[
|
||||||
|
[
|
||||||
|
["QQ", "wineBottonPath/drive_c/Program Files/Tencent/QQ/Bin/QQ.exe"],
|
||||||
|
["QQ", "wineBottonPath/drive_c/Program Files (x86)/Tencent/QQ/Bin/QQ.exe"],
|
||||||
|
["TIM", "wineBottonPath/drive_c/Program Files/Tencent/TIM/Bin/TIM.exe"],
|
||||||
|
["TIM", "wineBottonPath/drive_c/Program Files (x86)/Tencent/TIM/Bin/TIM.exe"]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
["cmd", "cmd"],
|
||||||
|
["cmd", "cmd.exe"],
|
||||||
|
["cmd", "wineBottonPath/drive_c/windows/system32/cmd.exe"],
|
||||||
|
["Internet Explorer", "iexplore"],
|
||||||
|
["Internet Explorer", "iexplore.exe"],
|
||||||
|
["Internet Explorer", "wineBottonPath/drive_c/Program Files/Internet Explorer/iexplore.exe"],
|
||||||
|
["Internet Explorer", "wineBottonPath/drive_c/Program Files (x86)/Internet Explorer/iexplore.exe"],
|
||||||
|
["微信", "wineBottonPath/drive_c/Program Files/Tencent/WeChat/WeChat.exe"],
|
||||||
|
["微信", "wineBottonPath/drive_c/Program Files (x86)/Tencent/WeChat/WeChat.exe"],
|
||||||
|
["UltraISO", "wineBottonPath/drive_c/Program Files/UltraISO/UltraISO.exe"],
|
||||||
|
["UltraISO", "wineBottonPath/drive_c/Program Files (x86)/UltraISO/UltraISO.exe"],
|
||||||
|
["迅雷", "wineBottonPath/drive_c/Program Files/Thunder Network/MiniThunder/Bin/ThunderMini.exe"],
|
||||||
|
["迅雷", "wineBottonPath/drive_c/Program Files (x86)/Thunder Network/MiniThunder/Bin/ThunderMini.exe"],
|
||||||
|
["Microsoft Office Word", "wineBottonPath/drive_c/Program Files/Microsoft Office/Office12/WINWORD.EXE"],
|
||||||
|
["Microsoft Office Word", "wineBottonPath/drive_c/Program Files (x86)/Microsoft Office/Office12/WINWORD.EXE"],
|
||||||
|
["腾讯会议", "wineBottonPath/drive_c/Program Files/Tencent/WeMeet/wemeetapp.exe"],
|
||||||
|
["腾讯会议", "wineBottonPath/drive_c/Program Files (x86)/Tencent/WeMeet/wemeetapp.exe"],
|
||||||
|
["腾讯课堂", "wineBottonPath/drive_c/Program Files/Tencent/EDU/bin/TXEDU.exe"],
|
||||||
|
["腾讯课堂", "wineBottonPath/drive_c/Program Files (x86)/Tencent/EDU/bin/TXEDU.exe"]
|
||||||
|
]
|
||||||
|
]
|
Binary file not shown.
41
deb/opt/apps/deepin-wine-runner/Mount.sh
Executable file
41
deb/opt/apps/deepin-wine-runner/Mount.sh
Executable file
@ -0,0 +1,41 @@
|
|||||||
|
#!/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"
|
||||||
|
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 +
|
||||||
|
# 挂载 Wine 运行器目录
|
||||||
|
mount -o bind `dirname $0` ./opt/apps/deepin-wine-runner/
|
||||||
|
# 挂载字体
|
||||||
|
mount -o bind /usr/share/fonts ./usr/share/fonts
|
||||||
|
# 配置用户
|
||||||
|
if [ ! -d "home/$2" ]; then
|
||||||
|
# 新建用户,且密码为 123456,以便读写
|
||||||
|
chroot . bash /opt/apps/deepin-wine-runner/ChangePassword.sh "$2"
|
||||||
|
fi
|
||||||
|
# 挂载用户目录到 /root(默认 $HOME 路径)
|
||||||
|
if [[ $2 == "root" ]]; then
|
||||||
|
mount --bind root "$1/root/"
|
||||||
|
else
|
||||||
|
mount --bind "/home/$2" "$1/home/$2"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 如果参数 3 存在
|
||||||
|
chroot "--userspec=$2:$2" . env "HOME=/home/$2" "${@:3}"
|
483
deb/opt/apps/deepin-wine-runner/QemuDownload.py
Executable file
483
deb/opt/apps/deepin-wine-runner/QemuDownload.py
Executable file
@ -0,0 +1,483 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# 本来是用C++写的,但在非deepin/UOS编译/运行就是下载不了https文件,只能用python重写
|
||||||
|
#########################################################################
|
||||||
|
# 作者:gfdgd xi、为什么您不喜欢熊出没和阿布
|
||||||
|
# 版本:2.4.0
|
||||||
|
# 感谢:感谢 deepin-wine 团队,提供了 deepin-wine 给大家使用,让我能做这个程序
|
||||||
|
# 基于 Python3 的 PyQt5 构建
|
||||||
|
#########################################################################
|
||||||
|
#################
|
||||||
|
# 引入所需的库
|
||||||
|
#################
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import random
|
||||||
|
import sys
|
||||||
|
import json
|
||||||
|
import traceback
|
||||||
|
import requests
|
||||||
|
programPath = os.path.split(os.path.realpath(__file__))[0] # 返回 string
|
||||||
|
sys.path.append(f"{programPath}/../")
|
||||||
|
from Model import *
|
||||||
|
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||||
|
programPath = os.path.split(os.path.realpath(__file__))[0] # 返回 string
|
||||||
|
# UI 布局(自动生成)
|
||||||
|
class Ui_MainWindow(object):
|
||||||
|
def setupUi(self, MainWindow):
|
||||||
|
MainWindow.setObjectName("MainWindow")
|
||||||
|
MainWindow.resize(693, 404)
|
||||||
|
self.centralWidget = QtWidgets.QWidget(MainWindow)
|
||||||
|
self.centralWidget.setObjectName("centralWidget")
|
||||||
|
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.centralWidget)
|
||||||
|
self.verticalLayout_2.setContentsMargins(11, 11, 11, 11)
|
||||||
|
self.verticalLayout_2.setSpacing(6)
|
||||||
|
self.verticalLayout_2.setObjectName("verticalLayout_2")
|
||||||
|
self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
|
||||||
|
self.horizontalLayout_2.setSpacing(6)
|
||||||
|
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
|
||||||
|
self.localWineList = QtWidgets.QListView(self.centralWidget)
|
||||||
|
self.localWineList.setObjectName("localWineList")
|
||||||
|
self.horizontalLayout_2.addWidget(self.localWineList)
|
||||||
|
self.verticalLayout = QtWidgets.QVBoxLayout()
|
||||||
|
self.verticalLayout.setSpacing(6)
|
||||||
|
self.verticalLayout.setObjectName("verticalLayout")
|
||||||
|
spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
|
||||||
|
self.verticalLayout.addItem(spacerItem)
|
||||||
|
self.addButton = QtWidgets.QPushButton(self.centralWidget)
|
||||||
|
self.addButton.setObjectName("addButton")
|
||||||
|
self.verticalLayout.addWidget(self.addButton)
|
||||||
|
self.delButton = QtWidgets.QPushButton(self.centralWidget)
|
||||||
|
self.delButton.setObjectName("delButton")
|
||||||
|
self.verticalLayout.addWidget(self.delButton)
|
||||||
|
spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
|
||||||
|
self.verticalLayout.addItem(spacerItem1)
|
||||||
|
self.horizontalLayout_2.addLayout(self.verticalLayout)
|
||||||
|
self.internetWineList = QtWidgets.QListView(self.centralWidget)
|
||||||
|
self.internetWineList.setObjectName("internetWineList")
|
||||||
|
self.horizontalLayout_2.addWidget(self.internetWineList)
|
||||||
|
self.verticalLayout_2.addLayout(self.horizontalLayout_2)
|
||||||
|
self.horizontalLayout = QtWidgets.QHBoxLayout()
|
||||||
|
self.horizontalLayout.setSpacing(6)
|
||||||
|
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||||
|
#self.unzip = QtWidgets.QCheckBox(self.centralWidget)
|
||||||
|
#self.unzip.setObjectName("unzip")
|
||||||
|
#self.horizontalLayout.addWidget(self.unzip)
|
||||||
|
#self.deleteZip = QtWidgets.QCheckBox(self.centralWidget)
|
||||||
|
#self.deleteZip.setChecked(True)
|
||||||
|
#self.deleteZip.setTristate(False)
|
||||||
|
#self.deleteZip.setObjectName("deleteZip")
|
||||||
|
#self.horizontalLayout.addWidget(self.deleteZip)
|
||||||
|
#self.addOtherWine = QtWidgets.QPushButton(self.centralWidget)
|
||||||
|
#self.horizontalLayout.addWidget(self.addOtherWine)
|
||||||
|
spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||||
|
self.horizontalLayout.addItem(spacerItem2)
|
||||||
|
self.verticalLayout_2.addLayout(self.horizontalLayout)
|
||||||
|
MainWindow.setCentralWidget(self.centralWidget)
|
||||||
|
# 菜单栏
|
||||||
|
_translate = QtCore.QCoreApplication.translate
|
||||||
|
self.menu = MainWindow.menuBar()
|
||||||
|
self.changeSources = self.menu.addMenu(_translate("MainWindow", "更换源"))
|
||||||
|
self.gitlinkAction = QtWidgets.QAction(_translate("MainWindow", "Gitlink 源(推荐)"))
|
||||||
|
self.ipv6Action = QtWidgets.QAction(_translate("MainWindow", "备用源(只支持 IPv6 用户)"))
|
||||||
|
self.localAction = QtWidgets.QAction(_translate("MainWindow", "本地测试源(127.0.0.1)"))
|
||||||
|
self.changeSources.addAction(self.gitlinkAction)
|
||||||
|
self.changeSources.addAction(self.ipv6Action)
|
||||||
|
self.changeSources.addAction(self.localAction)
|
||||||
|
for i in [self.gitlinkAction, self.ipv6Action, self.localAction]:
|
||||||
|
i.setCheckable(True)
|
||||||
|
self.gitlinkAction.setChecked(True)
|
||||||
|
self.changeSourcesGroup = QtWidgets.QActionGroup(MainWindow)
|
||||||
|
self.changeSourcesGroup.addAction(self.gitlinkAction)
|
||||||
|
self.changeSourcesGroup.addAction(self.ipv6Action)
|
||||||
|
self.changeSourcesGroup.addAction(self.localAction)
|
||||||
|
|
||||||
|
self.retranslateUi(MainWindow)
|
||||||
|
QtCore.QMetaObject.connectSlotsByName(MainWindow)
|
||||||
|
|
||||||
|
def retranslateUi(self, MainWindow):
|
||||||
|
_translate = QtCore.QCoreApplication.translate
|
||||||
|
MainWindow.setWindowTitle(_translate("MainWindow", "下载 Qemu 镜像"))
|
||||||
|
self.addButton.setText(_translate("MainWindow", "<<"))
|
||||||
|
self.delButton.setText(_translate("MainWindow", ">>"))
|
||||||
|
#self.unzip.setText(_translate("MainWindow", "不解压Wine资源文件"))
|
||||||
|
#self.deleteZip.setText(_translate("MainWindow", "删除下载的资源包,只解压保留(两个选项都选相互抵消)"))
|
||||||
|
#self.addOtherWine.setText(_translate("MainWindow", "导入自己的Wine"))
|
||||||
|
|
||||||
|
def ReadLocalInformation():
|
||||||
|
try:
|
||||||
|
global localJsonList
|
||||||
|
file = open(f"{homePath}/.deepin-wine-runner-ubuntu-images/lists.json", "r")
|
||||||
|
localJsonList = json.loads(file.read())
|
||||||
|
nmodel = QtGui.QStandardItemModel(window)
|
||||||
|
for i in localJsonList:
|
||||||
|
item = QtGui.QStandardItem(i)
|
||||||
|
nmodel.appendRow(item)
|
||||||
|
ui.localWineList.setModel(nmodel)
|
||||||
|
file.close()
|
||||||
|
except:
|
||||||
|
print("新建空列表")
|
||||||
|
try:
|
||||||
|
with open(f"{homePath}/.deepin-wine-runner-ubuntu-images/lists.json", "w") as file:
|
||||||
|
file.write("[]")
|
||||||
|
except:
|
||||||
|
traceback.print_exc()
|
||||||
|
QtWidgets.QMessageBox.critical(window, "错误", traceback.format_exc())
|
||||||
|
|
||||||
|
def InstallOtherWine():
|
||||||
|
path = QtWidgets.QFileDialog.getOpenFileName(window, "选择 Wine", os.getenv("~"), "wine(wine);;wine64(wine64);;全部文件(*.*)")
|
||||||
|
if path[0] == "" or not path[1]:
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
# 写入配置文件
|
||||||
|
rfile = open(f"{homePath}/.deepin-wine-runner-ubuntu-images/winelist.json", "r")
|
||||||
|
list = json.loads(rfile.read())
|
||||||
|
rfile.close()
|
||||||
|
# 创建映射
|
||||||
|
name = os.path.basename(os.path.dirname(os.path.dirname(path[0])))
|
||||||
|
if name == "" or name == None:
|
||||||
|
name = f"useradd-wine-{random.randint(0, 99999)}"
|
||||||
|
#binPath = os.path.dirname(os.path.dirname(path[0]))
|
||||||
|
os.makedirs(f"{programPath}/{name}/bin")
|
||||||
|
if os.system(f"ln -s '{path[0]}' '{programPath}/{name}/bin/wine'") != 0:
|
||||||
|
QtWidgets.QMessageBox.critical(window, "新建wine映射失败")
|
||||||
|
# C++ 版注释:不直接用 readwrite 是因为不能覆盖写入
|
||||||
|
file = open(f"{homePath}/.deepin-wine-runner-ubuntu-images/lists.json", "w")
|
||||||
|
list.append(name)
|
||||||
|
file.write(json.dumps(list))
|
||||||
|
file.close()
|
||||||
|
except:
|
||||||
|
traceback.print_exc()
|
||||||
|
QtWidgets.QMessageBox.critical(window, "错误", traceback.format_exc())
|
||||||
|
ReadLocalInformation()
|
||||||
|
|
||||||
|
def ChangeSources():
|
||||||
|
global urlSources
|
||||||
|
global internetWineSource
|
||||||
|
sources = [ui.gitlinkAction, ui.ipv6Action, ui.localAction]
|
||||||
|
for i in range(0, len(sources)):
|
||||||
|
if sources[i].isChecked():
|
||||||
|
urlSources = internetWineSourceList[i]
|
||||||
|
internetWineSource = internetWineSourceList[i]
|
||||||
|
# 读取信息
|
||||||
|
ReadLocalInformation()
|
||||||
|
ReadInternetInformation()
|
||||||
|
break
|
||||||
|
print(urlSources)
|
||||||
|
|
||||||
|
# 下面内容均翻译自 C++ 版本
|
||||||
|
def ReadInternetInformation():
|
||||||
|
global internetJsonList
|
||||||
|
# C++ 版本是用 curl 的,考虑到 Python 用 requests 反而方便,于是不用 curl
|
||||||
|
try:
|
||||||
|
internetJsonList = json.loads(requests.get(f"{internetWineSource}/lists.json").text)
|
||||||
|
internetJsonListNew = []
|
||||||
|
for k in internetJsonList:
|
||||||
|
archList = json.loads(requests.get(f"{internetWineSource}/{k}/lists.json").text)
|
||||||
|
for e in archList:
|
||||||
|
internetJsonListNew.append([e[0], e[1], k])
|
||||||
|
internetJsonList = internetJsonListNew
|
||||||
|
except:
|
||||||
|
traceback.print_exc()
|
||||||
|
QtWidgets.QMessageBox.critical(window, "错误", "无法连接服务器!")
|
||||||
|
return
|
||||||
|
print(internetJsonList)
|
||||||
|
nmodel = QtGui.QStandardItemModel(window)
|
||||||
|
for i in internetJsonList:
|
||||||
|
item = QtGui.QStandardItem(i[0])
|
||||||
|
nmodel.appendRow(item)
|
||||||
|
ui.internetWineList.setModel(nmodel)
|
||||||
|
|
||||||
|
class DownloadThread(QtCore.QThread):
|
||||||
|
MessageBoxInfo = QtCore.pyqtSignal(str)
|
||||||
|
MessageBoxError = QtCore.pyqtSignal(str)
|
||||||
|
ChangeDialog = QtCore.pyqtSignal(QtWidgets.QProgressDialog, int, int, int)
|
||||||
|
Finish = QtCore.pyqtSignal()
|
||||||
|
def __init__(self, progressDialog: QtWidgets.QProgressDialog,
|
||||||
|
url: str, savePath: str, fileName: str, view: QtWidgets.QListView, deleteZip: bool,
|
||||||
|
unzip: bool, localList) -> None:
|
||||||
|
self.dialog = progressDialog
|
||||||
|
self.fileUrl = url
|
||||||
|
self.fileSavePath = savePath
|
||||||
|
self.fileSaveName = fileName
|
||||||
|
self.localView = view
|
||||||
|
self.downloadDeleteZip = deleteZip
|
||||||
|
self.downloadUnzip = unzip
|
||||||
|
self.localJsonList = localList
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
def ReadLocalInformation(self):
|
||||||
|
global localJsonList
|
||||||
|
try:
|
||||||
|
file = open(f"{homePath}/.deepin-wine-runner-ubuntu-images/lists.json", "r")
|
||||||
|
nmodel = QtGui.QStandardItemModel()
|
||||||
|
localJsonList = json.loads(file.read())
|
||||||
|
for i in localJsonList:
|
||||||
|
nmodel.appendRow(QtGui.QStandardItem(i))
|
||||||
|
self.localView.setModel(nmodel)
|
||||||
|
file.close()
|
||||||
|
except:
|
||||||
|
traceback.print_exc()
|
||||||
|
QtWidgets.QMessageBox.critical(window, "错误", traceback.format_exc())
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
try:
|
||||||
|
# 创建文件夹
|
||||||
|
dir = QtCore.QDir()
|
||||||
|
#savePath = f"{programPath}/{self.fileSaveName}"
|
||||||
|
choose = ui.internetWineList.currentIndex().row()
|
||||||
|
arch = internetJsonList[choose][2]
|
||||||
|
savePath = f"{homePath}/.deepin-wine-runner-ubuntu-images/{arch}/{self.fileSaveName}"
|
||||||
|
if not os.path.exists(os.path.dirname(savePath)):
|
||||||
|
os.makedirs(os.path.dirname(savePath))
|
||||||
|
# 文件下载
|
||||||
|
timeout = 0
|
||||||
|
f = requests.get(self.fileUrl, stream=True)
|
||||||
|
allSize = int(f.headers["content-length"]) # 文件总大小
|
||||||
|
bytesRead = 0
|
||||||
|
with open(savePath, "wb") as filePart:
|
||||||
|
for chunk in f.iter_content(chunk_size=1024):
|
||||||
|
if chunk:
|
||||||
|
#progressbar.update(int(part / show))
|
||||||
|
filePart.write(chunk)
|
||||||
|
bytesRead += 1024
|
||||||
|
self.ChangeDialog.emit(self.dialog, bytesRead / allSize * 100, bytesRead / 1024 / 1024, allSize / 1024 / 1024)
|
||||||
|
self.ChangeDialog.emit(self.dialog, 100, 100, 100)
|
||||||
|
# 写入配置文件
|
||||||
|
rfile = open(f"{homePath}/.deepin-wine-runner-ubuntu-images/lists.json", "r")
|
||||||
|
list = json.loads(rfile.read())
|
||||||
|
rfile.close()
|
||||||
|
# C++ 版注释:不直接用 readwrite 是因为不能覆盖写入
|
||||||
|
file = open(f"{homePath}/.deepin-wine-runner-ubuntu-images/lists.json", "w")
|
||||||
|
list.append(self.fileSaveName.replace(".tar.gz", ""))
|
||||||
|
file.write(json.dumps(list))
|
||||||
|
file.close()
|
||||||
|
# 读取配置文件
|
||||||
|
self.ReadLocalInformation()
|
||||||
|
self.localJsonList = list
|
||||||
|
# 解压文件
|
||||||
|
shellCommand = ""
|
||||||
|
path = f"{homePath}/.deepin-wine-runner-ubuntu-images/{arch}/{self.fileSaveName.replace('.tar.gz', '')}/"
|
||||||
|
#path = f"{programPath}/{self.fileSaveName.replace('.7z', '')}"
|
||||||
|
shellCommand += f"""#!/bin/bash
|
||||||
|
mkdir -p \"{path}\"
|
||||||
|
tar -xvf \"{savePath}\" -C \"{path}\"
|
||||||
|
rm \"{savePath}\"
|
||||||
|
"""
|
||||||
|
#if self.downloadDeleteZip:
|
||||||
|
# shellCommand += f"rm -rf \"{savePath}\"\n"
|
||||||
|
shellFile = open("/tmp/depein-wine-runner-wine-install.sh", "w")
|
||||||
|
shellFile.write(shellCommand)
|
||||||
|
shellFile.close()
|
||||||
|
process = QtCore.QProcess()
|
||||||
|
command = ["deepin-terminal", "-e", "bash", "/tmp/depein-wine-runner-wine-install.sh"]
|
||||||
|
process.start(f"{programPath}/../launch.sh", command)
|
||||||
|
process.waitForFinished()
|
||||||
|
OpenTerminal("bash /tmp/depein-wine-runner-wine-install.sh")
|
||||||
|
self.Finish.emit()
|
||||||
|
except:
|
||||||
|
traceback.print_exc()
|
||||||
|
self.MessageBoxError.emit(traceback.format_exc())
|
||||||
|
|
||||||
|
def MessageBoxInfo(info):
|
||||||
|
QtWidgets.QMessageBox.information(window, "提示", info)
|
||||||
|
|
||||||
|
def MessageBoxError(info):
|
||||||
|
QtWidgets.QMessageBox.critical(window, "错误", info)
|
||||||
|
|
||||||
|
def ChangeDialog(dialog: QtWidgets.QProgressDialog, value, downloadBytes, totalBytes):
|
||||||
|
dialog.setValue(value)
|
||||||
|
dialog.setLabelText(f"{downloadBytes}MB/{totalBytes}MB")
|
||||||
|
|
||||||
|
def DownloadFinish():
|
||||||
|
ui.centralWidget.setEnabled(True)
|
||||||
|
|
||||||
|
class QT:
|
||||||
|
thread = None
|
||||||
|
|
||||||
|
def on_addButton_clicked():
|
||||||
|
choose = ui.internetWineList.currentIndex().row()
|
||||||
|
if choose < 0:
|
||||||
|
QtWidgets.QMessageBox.information(window, "提示", "您未选中任何项,无法继续")
|
||||||
|
return
|
||||||
|
downloadName = internetJsonList[choose][1]
|
||||||
|
ReadLocalInformation()
|
||||||
|
for i in localJsonList:
|
||||||
|
if i.replace(".tar.gz", "") == internetJsonList[choose][0]:
|
||||||
|
QtWidgets.QMessageBox.information(window, "提示", "您已经安装了这个镜像了!无需重复安装!")
|
||||||
|
return
|
||||||
|
#if(ui.deleteZip.isChecked() + ui.unzip.isChecked() == 2):
|
||||||
|
# ui.deleteZip.setChecked(False)
|
||||||
|
# ui.unzip.setChecked(False)
|
||||||
|
arch = internetJsonList[choose][2]
|
||||||
|
downloadUrl = f"{internetWineSource}/{arch}/{downloadName}"
|
||||||
|
dialog = QtWidgets.QProgressDialog()
|
||||||
|
cancel = QtWidgets.QPushButton("取消")
|
||||||
|
cancel.setDisabled(True)
|
||||||
|
dialog.setWindowIcon(QtGui.QIcon(f"{programPath}/deepin-wine-runner.svg"))
|
||||||
|
dialog.setCancelButton(cancel)
|
||||||
|
dialog.setWindowTitle(f"正在下载“{internetJsonList[choose][0]}”")
|
||||||
|
QT.thread = DownloadThread(
|
||||||
|
dialog,
|
||||||
|
downloadUrl,
|
||||||
|
"",
|
||||||
|
internetJsonList[choose][1],
|
||||||
|
ui.localWineList,
|
||||||
|
False,
|
||||||
|
not True,
|
||||||
|
localJsonList
|
||||||
|
)
|
||||||
|
QT.thread.MessageBoxInfo.connect(MessageBoxInfo)
|
||||||
|
QT.thread.MessageBoxError.connect(MessageBoxError)
|
||||||
|
QT.thread.ChangeDialog.connect(ChangeDialog)
|
||||||
|
QT.thread.Finish.connect(DownloadFinish)
|
||||||
|
ui.centralWidget.setDisabled(True)
|
||||||
|
QT.thread.start()
|
||||||
|
|
||||||
|
def on_delButton_clicked():
|
||||||
|
if QtWidgets.QMessageBox.question(window, "提示", "你确定要删除吗?") == QtWidgets.QMessageBox.No:
|
||||||
|
return
|
||||||
|
if ui.localWineList.currentIndex().row() < 0:
|
||||||
|
QtWidgets.QMessageBox.information(window, "提示", "您未选择任何项")
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
# {localJsonList[ui.localWineList.currentIndex().row()]}
|
||||||
|
path = f"{homePath}/.deepin-wine-runner-ubuntu-images/"
|
||||||
|
changed = False
|
||||||
|
for i in os.listdir(path):
|
||||||
|
if os.path.exists(f"{path}/{i}/{localJsonList[ui.localWineList.currentIndex().row()]}"):
|
||||||
|
changed = True
|
||||||
|
name = f"{path}/{i}/{localJsonList[ui.localWineList.currentIndex().row()]}".replace(".tar.gz", "")
|
||||||
|
if not changed:
|
||||||
|
name = f"{path}/i386/{localJsonList[ui.localWineList.currentIndex().row()]}".replace(".tar.gz", "")
|
||||||
|
print(name)
|
||||||
|
# 必须取消挂载目录才行
|
||||||
|
os.system(f"bash '{programPath}/UnMount.sh' '{name}'")
|
||||||
|
#name = f"{homePath}/.deepin-wine-runner-ubuntu-images/{localJsonList[ui.localWineList.currentIndex().row()]}"
|
||||||
|
dir = QtCore.QDir(name)
|
||||||
|
dir.removeRecursively()
|
||||||
|
QtCore.QFile.remove(name + ".tar.gz")
|
||||||
|
del localJsonList[ui.localWineList.currentIndex().row()]
|
||||||
|
file = open(f"{homePath}/.deepin-wine-runner-ubuntu-images/lists.json", "w")
|
||||||
|
file.write(json.dumps(localJsonList))
|
||||||
|
file.close()
|
||||||
|
ReadLocalInformation()
|
||||||
|
QtWidgets.QMessageBox.information(window, "提示", "删除成功!")
|
||||||
|
except:
|
||||||
|
traceback.print_exc()
|
||||||
|
QtWidgets.QMessageBox.critical(window, "错误", traceback.format_exc())
|
||||||
|
|
||||||
|
# 获取当前语言
|
||||||
|
def get_now_lang()->"获取当前语言":
|
||||||
|
return os.getenv('LANG')
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
homePath = os.getenv("HOME")
|
||||||
|
localJsonList = []
|
||||||
|
internetJsonList = []
|
||||||
|
internetWineSourceList = [
|
||||||
|
"https://code.gitlink.org.cn/gfdgd_xi/deepin-wine-runner-ubuntu-image/raw/branch/master/Sandbox",
|
||||||
|
"http://gfdgdxi.msns.cn/deepin-wine-runner-ubuntu-image/Sandbox", # 备用源,纯 IPv6 源
|
||||||
|
"http://127.0.0.1/deepin-wine-runner-ubuntu-image/Sandbox/" # 本地测试源
|
||||||
|
]
|
||||||
|
internetWineSource = internetWineSourceList[0]
|
||||||
|
app = QtWidgets.QApplication(sys.argv)
|
||||||
|
if os.system("which qemu-i386-static"):
|
||||||
|
if QtWidgets.QMessageBox.question(None, "提示", "检测到您未安装 qemu-user-static,是否安装?") == QtWidgets.QMessageBox.Yes:
|
||||||
|
OpenTerminal(f"pkexec bash '{programPath}/ShellList/InstallQemuUserStatic.sh'")
|
||||||
|
exit()
|
||||||
|
try:
|
||||||
|
if not os.path.exists(f"{homePath}/.deepin-wine-runner-ubuntu-images/"):
|
||||||
|
os.makedirs(f"{homePath}/.deepin-wine-runner-ubuntu-images/")
|
||||||
|
except:
|
||||||
|
traceback.print_exc()
|
||||||
|
QtWidgets.QMessageBox.critical(None, "错误", traceback.format_exc())
|
||||||
|
exit()
|
||||||
|
# 读取翻译
|
||||||
|
if not get_now_lang() == "zh_CN.UTF-8":
|
||||||
|
trans = QtCore.QTranslator()
|
||||||
|
trans.load(f"{programPath}/../LANG/installwine-en_US.qm")
|
||||||
|
app.installTranslator(trans)
|
||||||
|
# 窗口构建
|
||||||
|
window = QtWidgets.QMainWindow()
|
||||||
|
ui = Ui_MainWindow()
|
||||||
|
window.setWindowIcon(QtGui.QIcon(f"{programPath}/deepin-wine-runner.svg"))
|
||||||
|
ui.setupUi(window)
|
||||||
|
window.show()
|
||||||
|
# 连接信号
|
||||||
|
ui.addButton.clicked.connect(on_addButton_clicked)
|
||||||
|
ui.delButton.clicked.connect(on_delButton_clicked)
|
||||||
|
#ui.addOtherWine.clicked.connect(InstallOtherWine)
|
||||||
|
ui.changeSourcesGroup.triggered.connect(ChangeSources)
|
||||||
|
## 加载内容
|
||||||
|
# 设置列表双击不会编辑
|
||||||
|
ui.localWineList.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
|
||||||
|
ui.internetWineList.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
|
||||||
|
# 读取信息
|
||||||
|
ReadLocalInformation()
|
||||||
|
ReadInternetInformation()
|
||||||
|
# 图标
|
||||||
|
ui.centralWidget.setWindowIcon(QtGui.QIcon(f"{programPath}/../deepin-wine-runner.svg"))
|
||||||
|
|
||||||
|
app.exec_()
|
||||||
|
exit()
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import json
|
||||||
|
import traceback
|
||||||
|
import req as requests
|
||||||
|
import PyQt5.QtGui as QtGui
|
||||||
|
import PyQt5.QtCore as QtCore
|
||||||
|
import PyQt5.QtWidgets as QtWidgets
|
||||||
|
from Model import *
|
||||||
|
|
||||||
|
sources = [
|
||||||
|
"https://code.gitlink.org.cn/gfdgd_xi/deepin-wine-runner-ubuntu-image/raw/branch/master/Sandbox"
|
||||||
|
]
|
||||||
|
sourceIndex = 0
|
||||||
|
|
||||||
|
def ReadTXT(path: str) -> str:
|
||||||
|
with open(path, "r") as file:
|
||||||
|
things = file.read()
|
||||||
|
return things
|
||||||
|
|
||||||
|
def WriteTXT(path: str, text: str) -> None:
|
||||||
|
with open(path, "w") as file:
|
||||||
|
file.write(text)
|
||||||
|
|
||||||
|
def CheckVersion(arch: str) -> bool:
|
||||||
|
information = requests.get(f"{sources[sourceIndex]}/{arch}/lists.json").json()[0]
|
||||||
|
if not os.path.exists(f"{homePath}/.deepin-wine-runner-ubuntu-images/{arch}"):
|
||||||
|
return False
|
||||||
|
localInformation = json.loads(ReadTXT(f"{homePath}/.deepin-wine-runner-ubuntu-images/lists.json"))
|
||||||
|
try:
|
||||||
|
if localInformation["arch"][0] == information[0]:
|
||||||
|
print("版本相同")
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
programPath = os.path.split(os.path.realpath(__file__))[0] # 返回 string
|
||||||
|
homePath = os.getenv("HOME")
|
||||||
|
app = QtWidgets.QApplication(sys.argv)
|
||||||
|
if os.system("which qemu-i386-static"):
|
||||||
|
if QtWidgets.QMessageBox.question(None, "提示", "检测到您未安装 qemu-user-static,是否安装?") == QtWidgets.QMessageBox.Yes:
|
||||||
|
OpenTerminal(f"pkexec bash '{programPath}/ShellList/InstallQemuUserStatic.sh'")
|
||||||
|
exit()
|
||||||
|
while True:
|
||||||
|
archList = requests.get(f"{sources[sourceIndex]}/lists.json").json()
|
||||||
|
choose = QtWidgets.QInputDialog.getItem(None, "选择", "选择要安装/更新的镜像对应的架构", archList, 0, False)
|
||||||
|
if not choose[1]:
|
||||||
|
QtWidgets.QMessageBox.information(None, "提示", "用户取消操作")
|
||||||
|
break
|
||||||
|
try:
|
||||||
|
if CheckVersion(choose[0]):
|
||||||
|
QtWidgets.QMessageBox.information(None, "提示", "最新版本,无需操作")
|
||||||
|
continue
|
||||||
|
|
||||||
|
except:
|
||||||
|
traceback.print_exc()
|
||||||
|
QtWidgets.QMessageBox.critical(None, "出现错误", traceback.format_exc())
|
||||||
|
continue
|
41
deb/opt/apps/deepin-wine-runner/QemuRun.py
Executable file
41
deb/opt/apps/deepin-wine-runner/QemuRun.py
Executable file
@ -0,0 +1,41 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import getpass
|
||||||
|
import PyQt5.QtWidgets as QtWidgets
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
programPath = os.path.split(os.path.realpath(__file__))[0] # 返回 string
|
||||||
|
homePath = os.getenv("HOME")
|
||||||
|
if len(sys.argv) <= 1:
|
||||||
|
print("参数不足")
|
||||||
|
sys.exit(1)
|
||||||
|
app = QtWidgets.QApplication(sys.argv)
|
||||||
|
# 判断是否已下载镜像
|
||||||
|
if not os.path.exists(f"{homePath}/.deepin-wine-runner-ubuntu-images/{sys.argv[1]}"):
|
||||||
|
QtWidgets.QMessageBox.information(None, "提示", "此镜像未下载解压,无法继续")
|
||||||
|
exit()
|
||||||
|
commandList = ""
|
||||||
|
userName = getpass.getuser()
|
||||||
|
for i in sys.argv[2:]:
|
||||||
|
commandList += f"'{i}' "
|
||||||
|
if commandList.replace(" ", "") == "":
|
||||||
|
commandList = "bash"
|
||||||
|
# 需要先取消挂载其它目录以防止冲突
|
||||||
|
path = f"{homePath}/.deepin-wine-runner-ubuntu-images"
|
||||||
|
for i in os.listdir(path):
|
||||||
|
archPath = f"{path}/{i}"
|
||||||
|
if os.path.isdir(archPath):
|
||||||
|
for k in os.listdir(archPath):
|
||||||
|
bottlePath = f"{archPath}/{k}"
|
||||||
|
if os.path.isdir(bottlePath):
|
||||||
|
if f"{i}/{k}" == sys.argv[1]:
|
||||||
|
continue
|
||||||
|
if os.path.ismount(f"{bottlePath}/dev"):
|
||||||
|
os.system(f"pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY bash '{programPath}/UnMount.sh' '{bottlePath}' ")
|
||||||
|
|
||||||
|
# 判断是否挂载
|
||||||
|
if not os.path.ismount(f"{homePath}/.deepin-wine-runner-ubuntu-images/{sys.argv[1]}/dev"):
|
||||||
|
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}"))
|
||||||
|
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}"))
|
3
deb/opt/apps/deepin-wine-runner/ShellList/InstallQemuUserStatic.sh
Executable file
3
deb/opt/apps/deepin-wine-runner/ShellList/InstallQemuUserStatic.sh
Executable file
@ -0,0 +1,3 @@
|
|||||||
|
echo 开始安装 qemu-user-static
|
||||||
|
pkexec apt update
|
||||||
|
pkexec apt install qemu-user-static -y
|
36
deb/opt/apps/deepin-wine-runner/UnMount.sh
Executable file
36
deb/opt/apps/deepin-wine-runner/UnMount.sh
Executable file
@ -0,0 +1,36 @@
|
|||||||
|
#!/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"
|
||||||
|
umount ./dev
|
||||||
|
umount ./dev/pts
|
||||||
|
umount ./proc
|
||||||
|
umount ./etc/resolv.conf
|
||||||
|
umount ./sys
|
||||||
|
umount ./dev/shm
|
||||||
|
# 挂载 Wine 运行器目录
|
||||||
|
umount ./opt/apps/deepin-wine-runner/
|
||||||
|
# 挂载字体
|
||||||
|
umount ./usr/share/fonts
|
||||||
|
# 挂载用户目录到 /root(默认 $HOME 路径)
|
||||||
|
umount ./root
|
||||||
|
for username in $(ls ./home)
|
||||||
|
do
|
||||||
|
echo ./home/$username
|
||||||
|
umount ./home/$username
|
||||||
|
# if [ -d ./home/$username/.deepinwine/$CONTAINER_NAME ]
|
||||||
|
# then
|
||||||
|
# rm -rf ./home/$username/.deepinwine/$CONTAINER_NAME
|
||||||
|
# fi
|
||||||
|
done
|
635
deb/opt/apps/deepin-wine-runner/deepin-wine-easy-packager.py
Executable file
635
deb/opt/apps/deepin-wine-runner/deepin-wine-easy-packager.py
Executable file
@ -0,0 +1,635 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import json
|
||||||
|
import time
|
||||||
|
import random
|
||||||
|
import xpinyin
|
||||||
|
import traceback
|
||||||
|
import subprocess
|
||||||
|
import PyQt5.QtGui as QtGui
|
||||||
|
import PyQt5.QtCore as QtCore
|
||||||
|
import PyQt5.QtWidgets as QtWidgets
|
||||||
|
|
||||||
|
def ShowText(text: str):
|
||||||
|
if text.replace(" ", "").replace("\n", "") == "":
|
||||||
|
return
|
||||||
|
logText.append(text.replace("\n", ""))
|
||||||
|
|
||||||
|
def ErrorMessage(text: str):
|
||||||
|
QtWidgets.QMessageBox.critical(window, "错误", text)
|
||||||
|
|
||||||
|
def InformationMessage(text: str):
|
||||||
|
QtWidgets.QMessageBox.information(window, "提示", text)
|
||||||
|
|
||||||
|
questionChoose = False
|
||||||
|
questionStatus = False
|
||||||
|
def QuestionMessage(text: str):
|
||||||
|
global questionChoose
|
||||||
|
global questionStatus
|
||||||
|
# 清零
|
||||||
|
questionChoose = False
|
||||||
|
questionStatus = False
|
||||||
|
if QtWidgets.QMessageBox.question(window, "提示", text) == QtWidgets.QMessageBox.Yes:
|
||||||
|
questionChoose = True
|
||||||
|
print(questionChoose)
|
||||||
|
questionStatus = True
|
||||||
|
return
|
||||||
|
questionChoose = False
|
||||||
|
questionStatus = True
|
||||||
|
|
||||||
|
|
||||||
|
def DisbledAndEnabledAll(choose: bool):
|
||||||
|
exePath.setDisabled(choose)
|
||||||
|
browserExeButton.setDisabled(choose)
|
||||||
|
buildButton.setDisabled(choose)
|
||||||
|
|
||||||
|
# 获取用户主目录
|
||||||
|
def get_home():
|
||||||
|
return os.path.expanduser('~')
|
||||||
|
|
||||||
|
def get_desktop_path():
|
||||||
|
try:
|
||||||
|
for line in open(get_home() + "/.config/user-dirs.dirs"): # 以行来读取配置文件
|
||||||
|
desktop_index = line.find("XDG_DESKTOP_DIR=\"") # 寻找是否有对应项,有返回 0,没有返回 -1
|
||||||
|
if desktop_index != -1: # 如果有对应项
|
||||||
|
break # 结束循环
|
||||||
|
if desktop_index == -1: # 如果是提前结束,值一定≠-1,如果是没有提前结束,值一定=-1
|
||||||
|
return -1
|
||||||
|
else:
|
||||||
|
get = line[17:-2] # 截取桌面目录路径
|
||||||
|
get_index = get.find("$HOME") # 寻找是否有对应的项,需要替换内容
|
||||||
|
if get != -1: # 如果有
|
||||||
|
get = get.replace("$HOME", get_home()) # 则把其替换为用户目录(~)
|
||||||
|
return get # 返回目录
|
||||||
|
except:
|
||||||
|
traceback.print_exc()
|
||||||
|
return get_home()
|
||||||
|
|
||||||
|
def CleanPressCompleteDownloadState(option):
|
||||||
|
global pressCompleteDownload
|
||||||
|
pressCompleteDownload = False
|
||||||
|
installCmpleteButton.setEnabled(True)
|
||||||
|
|
||||||
|
# 读取 lnk 文件
|
||||||
|
def GetLnkDesktop(path):
|
||||||
|
lnkList = []
|
||||||
|
for i in os.listdir(path):
|
||||||
|
filePath = f"{path}/{i}"
|
||||||
|
if os.path.islink(filePath):
|
||||||
|
# 忽略 link 链接
|
||||||
|
continue
|
||||||
|
if os.path.isdir(filePath):
|
||||||
|
lists = GetLnkDesktop(filePath)
|
||||||
|
for k in lists:
|
||||||
|
lnkList.append(k)
|
||||||
|
continue
|
||||||
|
if os.path.isfile(filePath) and os.path.splitext(filePath)[1] == ".lnk":
|
||||||
|
with open(filePath, "rb") as file:
|
||||||
|
while True:
|
||||||
|
things = file.readline().lower()
|
||||||
|
if things == b"":
|
||||||
|
break
|
||||||
|
print(things[1: -2].split("\x00".encode("gbk")))
|
||||||
|
for k in things[1: -2].split("\x00".encode("gbk")):
|
||||||
|
if "c:".encode("gbk") in k:
|
||||||
|
print(k.decode("gbk"))
|
||||||
|
lnkList.append([filePath, k.decode("gbk")])
|
||||||
|
return lnkList
|
||||||
|
|
||||||
|
def ReplaceText(string: str, lists: list):
|
||||||
|
for i in lists:
|
||||||
|
string = string.replace(i[0], i[1])
|
||||||
|
return string
|
||||||
|
|
||||||
|
control = '''Package: @@@Package@@@
|
||||||
|
Version: @@@Version@@@
|
||||||
|
Architecture: i386
|
||||||
|
Maintainer: @@@Maintainer@@@
|
||||||
|
Depends: @@@Depends@@@
|
||||||
|
Section: non-free/otherosfs
|
||||||
|
Priority: optional
|
||||||
|
Multi-Arch: foreign
|
||||||
|
Installed-Size: @@@Installed-Size@@@
|
||||||
|
Description: @@@Description@@@
|
||||||
|
'''
|
||||||
|
|
||||||
|
info = f'''{{
|
||||||
|
"appid": "@@@Package@@@",
|
||||||
|
"name": "@@@Name@@@",
|
||||||
|
"version": "@@@Version@@@",
|
||||||
|
"arch": ["i386"],
|
||||||
|
"permissions": {{
|
||||||
|
"autostart": false,
|
||||||
|
"notification": false,
|
||||||
|
"trayicon": true,
|
||||||
|
"clipboard": true,
|
||||||
|
"account": false,
|
||||||
|
"bluetooth": false,
|
||||||
|
"camera": true,
|
||||||
|
"audio_record": true,
|
||||||
|
"installed_apps": false
|
||||||
|
}}
|
||||||
|
}}'''
|
||||||
|
|
||||||
|
postrm = f"""#!/bin/bash
|
||||||
|
if [ "$1" = "remove" ] || [ "$1" = "purge" ];then
|
||||||
|
|
||||||
|
echo "清理卸载残留"
|
||||||
|
CONTAINER_NAME="@@@Package@@@"
|
||||||
|
|
||||||
|
if [ -z $CONTAINER_NAME ];then
|
||||||
|
echo "W: 没有指定容器,跳过清理容器。请手动前往 ~/.deepinwine/ 下删除"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
/opt/deepinwine/tools/kill.sh $CONTAINER_NAME
|
||||||
|
###这里注意,如果没写CONTAINER_NAME,会把QQ杀了
|
||||||
|
|
||||||
|
for username in $(ls /home)
|
||||||
|
do
|
||||||
|
echo /home/$username
|
||||||
|
if [ -d /home/$username/.deepinwine/$CONTAINER_NAME ]
|
||||||
|
then
|
||||||
|
rm -rf /home/$username/.deepinwine/$CONTAINER_NAME
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
else
|
||||||
|
echo "非卸载,跳过清理"
|
||||||
|
fi"""
|
||||||
|
|
||||||
|
runsh = f'''#!/bin/sh
|
||||||
|
|
||||||
|
# Copyright (C) 2016 Deepin, Inc.
|
||||||
|
#
|
||||||
|
# Author: Li LongYu <lilongyu@linuxdeepin.com>
|
||||||
|
# Peng Hao <penghao@linuxdeepin.com>
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Copyright (C) 2022 The Spark Project
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Modifier shenmo <shenmo@spark-app.store>
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
#######################函数段。下文调用的额外功能会在此处声明
|
||||||
|
|
||||||
|
Get_Dist_Name()
|
||||||
|
{{
|
||||||
|
if grep -Eqii "Deepin" /etc/issue || grep -Eq "Deepin" /etc/*-release; then
|
||||||
|
DISTRO='Deepin'
|
||||||
|
elif grep -Eqi "UnionTech" /etc/issue || grep -Eq "UnionTech" /etc/*-release; then
|
||||||
|
DISTRO='UniontechOS'
|
||||||
|
else
|
||||||
|
DISTRO='OtherOS'
|
||||||
|
fi
|
||||||
|
}}
|
||||||
|
|
||||||
|
|
||||||
|
####获得发行版名称
|
||||||
|
|
||||||
|
#########################预设值段
|
||||||
|
|
||||||
|
version_gt() {{ test "$(echo "$@" | tr " " "\n" | sort -V | head -n 1)" != "$1"; }}
|
||||||
|
####用于比较版本?未实装
|
||||||
|
BOTTLENAME="@@@Package@@@"
|
||||||
|
APPVER="@@@Version@@@"
|
||||||
|
EXEC_PATH="@@@EXEC_PATH@@@"
|
||||||
|
##### 软件在wine中的启动路径
|
||||||
|
START_SHELL_PATH="/opt/deepinwine/tools/spark_run_v4.sh"
|
||||||
|
export MIME_TYPE=""
|
||||||
|
#####没什么用
|
||||||
|
export DEB_PACKAGE_NAME="@@@Package@@@"
|
||||||
|
####这里写包名才能在启动的时候正确找到files.7z,似乎也和杀残留进程有关
|
||||||
|
export APPRUN_CMD="deepin-wine6-stable"
|
||||||
|
#####wine启动指令,建议
|
||||||
|
EXPORT_ENVS=""
|
||||||
|
|
||||||
|
export SPECIFY_SHELL_DIR=`dirname $START_SHELL_PATH`
|
||||||
|
|
||||||
|
ARCHIVE_FILE_DIR="/opt/apps/$DEB_PACKAGE_NAME/files"
|
||||||
|
|
||||||
|
export WINEDLLPATH=/opt/$APPRUN_CMD/lib:/opt/$APPRUN_CMD/lib64
|
||||||
|
|
||||||
|
export WINEPREDLL="$ARCHIVE_FILE_DIR/dlls"
|
||||||
|
|
||||||
|
DISABLE_ATTACH_FILE_DIALOG=""
|
||||||
|
##默认为空。若为1,则不使用系统自带的文件选择,而是使用wine的
|
||||||
|
##对于deepin/UOS,大部分的应用都不需要使用wine的,如果有需求(比如wine应用选择的限定种类文件系统的文管不支持)
|
||||||
|
##请填1。
|
||||||
|
##注意:因为非DDE的环境不确定,所以默认会在非Deepin/UOS发行版上禁用这个功能。如果你确认在适配的发行版上可以正常启动,请注释或者删除下面这段
|
||||||
|
|
||||||
|
##############<<<<<<<<<禁用文件选择工具开始
|
||||||
|
Get_Dist_Name
|
||||||
|
#此功能实现参见结尾函数段
|
||||||
|
if [ "$DISTRO" != "Deepin" ] && [ "$DISTRO" != "UniontechOS" ];then
|
||||||
|
DISABLE_ATTACH_FILE_DIALOG="1"
|
||||||
|
echo "非deepin/UOS,默认关闭系统自带的文件选择工具,使用Wine的"
|
||||||
|
echo "如果你想改变这个行为,请到/opt/apps/$DEB_PACKAGE_NAME/files/$0处修改"
|
||||||
|
echo "To打包者:如果你要打开自带请注意在适配的发行版上进行测试"
|
||||||
|
echo "To用户:打包者没有打开这个功能,这证明启用这个功能可能造成运行问题。如果你要修改这个行为,请确保你有一定的动手能力"
|
||||||
|
fi
|
||||||
|
##############>>>>>>>>>禁用文件选择工具结束
|
||||||
|
|
||||||
|
##############<<<<<<<<<屏蔽mono和gecko安装器开始
|
||||||
|
##默认屏蔽mono和gecko安装器
|
||||||
|
#if [ "$APPRUN_CMD" = "spark-wine7-devel" ];then
|
||||||
|
|
||||||
|
#export WINEDLLOVERRIDES="mscoree,mshtml="
|
||||||
|
#echo "为了降低打包体积,默认关闭gecko和momo,如有需要,注释此行(仅对spark-wine7-devel有效)"
|
||||||
|
|
||||||
|
#fi
|
||||||
|
##############>>>>>>>>>屏蔽mono和gecko安装器结束
|
||||||
|
|
||||||
|
#########################执行段
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if [ -z "$DISABLE_ATTACH_FILE_DIALOG" ];then
|
||||||
|
export ATTACH_FILE_DIALOG=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$EXPORT_ENVS" ];then
|
||||||
|
export $EXPORT_ENVS
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$EXEC_PATH" ];then
|
||||||
|
if [ -z "${{EXEC_PATH##*.lnk*}}" ];then
|
||||||
|
$START_SHELL_PATH $BOTTLENAME $APPVER "C:/windows/command/start.exe" "/Unix" "$EXEC_PATH" "$@"
|
||||||
|
else
|
||||||
|
$START_SHELL_PATH $BOTTLENAME $APPVER "$EXEC_PATH" "$@"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
$START_SHELL_PATH $BOTTLENAME $APPVER "uninstaller.exe" "$@"
|
||||||
|
fi'''
|
||||||
|
|
||||||
|
desktopFile = f'''#!/usr/bin/env xdg-open
|
||||||
|
[Desktop Entry]
|
||||||
|
Encoding=UTF-8
|
||||||
|
Type=Application
|
||||||
|
X-Created-By=@@@Maintainer@@@
|
||||||
|
Icon=@@@Icon@@@
|
||||||
|
Exec="/opt/apps/@@@Package@@@/files/run.sh"
|
||||||
|
Name=@@@Name@@@
|
||||||
|
Comment=@@@Description@@@
|
||||||
|
MimeType=
|
||||||
|
GenericName=@@@Package@@@
|
||||||
|
Terminal=false
|
||||||
|
StartupNotify=false'''
|
||||||
|
|
||||||
|
def getFileFolderSize(fileOrFolderPath):
|
||||||
|
"""get size for file or folder"""
|
||||||
|
totalSize = 0
|
||||||
|
if not os.path.exists(fileOrFolderPath):
|
||||||
|
return totalSize
|
||||||
|
if os.path.isfile(fileOrFolderPath):
|
||||||
|
totalSize = os.path.getsize(fileOrFolderPath) # 5041481
|
||||||
|
return totalSize
|
||||||
|
if os.path.isdir(fileOrFolderPath):
|
||||||
|
with os.scandir(fileOrFolderPath) as dirEntryList:
|
||||||
|
for curSubEntry in dirEntryList:
|
||||||
|
curSubEntryFullPath = os.path.join(fileOrFolderPath, curSubEntry.name)
|
||||||
|
if curSubEntry.is_dir():
|
||||||
|
curSubFolderSize = getFileFolderSize(curSubEntryFullPath) # 5800007
|
||||||
|
totalSize += curSubFolderSize
|
||||||
|
elif curSubEntry.is_file():
|
||||||
|
curSubFileSize = os.path.getsize(curSubEntryFullPath) # 1891
|
||||||
|
totalSize += curSubFileSize
|
||||||
|
return totalSize
|
||||||
|
|
||||||
|
|
||||||
|
def WriteTxt(path, things):
|
||||||
|
with open(path, "w") as file:
|
||||||
|
file.write(things)
|
||||||
|
|
||||||
|
def ReadTxt(path):
|
||||||
|
things = ""
|
||||||
|
with open(path, "r") as file:
|
||||||
|
things = file.read()
|
||||||
|
return things
|
||||||
|
|
||||||
|
def GetEXEVersion(exePath):
|
||||||
|
versionPath = f"/tmp/wine-runner-exe-version-{random.randint(0, 1000)}.txt"
|
||||||
|
if os.system(f"deepin-wine6-stable '{programPath}/GetEXEVersion.exe' '{exePath}' '{versionPath}'"):
|
||||||
|
return "1.0.0"
|
||||||
|
try:
|
||||||
|
exeVersion = ReadTxt(versionPath).replace("\n", "")
|
||||||
|
if exeVersion.replace(" ", "") == "":
|
||||||
|
return "1.0.0"
|
||||||
|
return exeVersion
|
||||||
|
except:
|
||||||
|
traceback.print_exc()
|
||||||
|
return "1.0.0"
|
||||||
|
|
||||||
|
def StrToByteToStr(text: str):
|
||||||
|
lists = text.split("\\x")
|
||||||
|
for i in range(len(lists)):
|
||||||
|
lists[i]
|
||||||
|
return text
|
||||||
|
|
||||||
|
def UnUseUpperCharPath(path: str):
|
||||||
|
pathList = []
|
||||||
|
lowerList = path.split("/")[1:]
|
||||||
|
for i in lowerList:
|
||||||
|
path = "/" + "/".join(pathList)
|
||||||
|
before = len(pathList)
|
||||||
|
for k in os.listdir(path):
|
||||||
|
if k.lower() == i.lower():
|
||||||
|
pathList.append(k)
|
||||||
|
break
|
||||||
|
end = len(pathList)
|
||||||
|
if before == end:
|
||||||
|
raise OSError("文件路径不存在")
|
||||||
|
return "/" + "/".join(pathList)
|
||||||
|
|
||||||
|
|
||||||
|
class RunThread(QtCore.QThread):
|
||||||
|
showLogText = QtCore.pyqtSignal(str)
|
||||||
|
error = QtCore.pyqtSignal(str)
|
||||||
|
info = QtCore.pyqtSignal(str)
|
||||||
|
question = QtCore.pyqtSignal(str)
|
||||||
|
disbledAll = QtCore.pyqtSignal(bool)
|
||||||
|
cleanPressState = QtCore.pyqtSignal(bool)
|
||||||
|
def RunCommand(self, command):
|
||||||
|
res = subprocess.Popen([command], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||||
|
while res.poll() is None:
|
||||||
|
try:
|
||||||
|
text = res.stdout.readline().decode("utf8")
|
||||||
|
except:
|
||||||
|
text = ""
|
||||||
|
self.showLogText.emit(text)
|
||||||
|
print(text, end="")
|
||||||
|
|
||||||
|
def __init__(self) -> None:
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
def GetEXEVersion(self, exePath):
|
||||||
|
versionPath = f"/tmp/wine-runner-exe-version-{random.randint(0, 1000)}.txt"
|
||||||
|
self.RunCommand(f"deepin-wine6-stable '{programPath}/GetEXEVersion.exe' '{exePath}' '{versionPath}'")
|
||||||
|
try:
|
||||||
|
exeVersion = ReadTxt(versionPath).replace("\n", "")
|
||||||
|
if exeVersion.replace(" ", "") == "":
|
||||||
|
return "1.0.0"
|
||||||
|
return exeVersion
|
||||||
|
except:
|
||||||
|
traceback.print_exc()
|
||||||
|
return "1.0.0"
|
||||||
|
|
||||||
|
def QuestionMsg(self, text):
|
||||||
|
global questionStatus
|
||||||
|
questionStatus = False
|
||||||
|
self.question.emit(text)
|
||||||
|
while not questionStatus:
|
||||||
|
time.sleep(0.1)
|
||||||
|
print(questionChoose)
|
||||||
|
return questionChoose
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
try:
|
||||||
|
self.disbledAll.emit(True)
|
||||||
|
if not self.QuestionMsg("在此过程中,需要回答一系列的问题以进行打包,点击确定继续"):
|
||||||
|
self.disbledAll.emit(False)
|
||||||
|
return
|
||||||
|
bottlePath = f"/tmp/deepin-wine-runner-bottle-{random.randint(0, 10000)}"
|
||||||
|
# 清空容器以保证能正常使用
|
||||||
|
if os.path.exists(bottlePath):
|
||||||
|
self.RunCommand(f"rm -rfv '{bottlePath}'")
|
||||||
|
############# 后面将全部调用 deepin wine6 stable 进行操作
|
||||||
|
exeName = os.path.basename(exePath.text())
|
||||||
|
# 暂定
|
||||||
|
packageName = xpinyin.Pinyin().get_pinyin(os.path.splitext(exeName)[0].replace(" ", ""), "").lower().replace(" ", "").replace("_", ".").replace("-", ".").replace("..", ".")
|
||||||
|
|
||||||
|
if " " in packageName:
|
||||||
|
packageName = ""
|
||||||
|
for i in os.path.splitext(exeName)[0].split(" "):
|
||||||
|
packageName += xpinyin.Pinyin().get_pinyin(i).lower().replace(" ", "").replace("_", ".").replace("-", ".").replace("..", ".") + "."
|
||||||
|
print(packageName)
|
||||||
|
packageName = packageName[:-1]
|
||||||
|
debPackageName = "com." + packageName + ".spark"
|
||||||
|
debPackageVersion = "1.0.0"
|
||||||
|
programIconPath = f"/opt/apps/{debPackageName}/entries/icons/hicolor/scalable/apps/{debPackageName}.png"
|
||||||
|
debMaintainer = os.getlogin()
|
||||||
|
debBuildPath = f"/tmp/deepin-wine-packager-builder-{debPackageName}-{random.randint(0, 1000)}"
|
||||||
|
bottlePackagePath = f"{debBuildPath}/opt/apps/{debPackageName}/files/files.7z"
|
||||||
|
desktopPath = get_desktop_path()
|
||||||
|
############## 运行 EXE
|
||||||
|
if self.QuestionMsg("请问此可执行文件是安装包还是绿色软件?是安装包请按 Yes,绿色软件按 No"):
|
||||||
|
# 清空无益处的 lnk 文件
|
||||||
|
lnkPath = f"{bottlePath}/drive_c/ProgramData/Microsoft/Windows/Start Menu/Programs"
|
||||||
|
self.RunCommand(f"rm -rfv '{lnkPath}'")
|
||||||
|
self.RunCommand(f"mkdir -pv '{bottlePath}'")
|
||||||
|
self.RunCommand(f"chmod 777 -Rv '{bottlePath}'")
|
||||||
|
# 禁止生成 .desktop 文件
|
||||||
|
self.RunCommand(f"WINEPREFIX='{bottlePath}' deepin-wine6-stable 'reg' 'add' 'HKEY_CURRENT_USER\Software\Wine\DllOverrides' /v winemenubuilder.exe '/f'")
|
||||||
|
# 安装包
|
||||||
|
global pressCompleteDownload
|
||||||
|
pressCompleteDownload = False
|
||||||
|
installCmpleteButton.setEnabled(True)
|
||||||
|
self.RunCommand(f"WINEPREFIX='{bottlePath}' deepin-wine6-stable '{exePath.text()}' &") # 非堵塞线程
|
||||||
|
|
||||||
|
# 安装锁,锁解除后才可继续
|
||||||
|
while not pressCompleteDownload:
|
||||||
|
time.sleep(0.1)
|
||||||
|
# 杀死容器内应用
|
||||||
|
self.RunCommand(f"'{programPath}/kill.sh' '{os.path.basename(bottlePath)}'")
|
||||||
|
# 识别 lnk
|
||||||
|
lnkList = GetLnkDesktop(lnkPath)
|
||||||
|
if len(lnkList) <= 0:
|
||||||
|
self.error.emit("无法识别到任何 lnk 快捷方式")
|
||||||
|
self.RunCommand(f"rm -rfv '{debBuildPath}' > /dev/null")
|
||||||
|
self.RunCommand(f"rm -rfv '{bottlePath}' > /dev/null")
|
||||||
|
self.disbledAll.emit(False)
|
||||||
|
return
|
||||||
|
# 选择最优 lnk
|
||||||
|
secondChooseList = []
|
||||||
|
for k in lnkList:
|
||||||
|
lnkPath = k[0].lower()
|
||||||
|
lnkExePath = k[1].lower()
|
||||||
|
if "卸载" in lnkPath or "uninstall" in lnkPath or "update" in lnkPath or "网页" in lnkPath or "websize" in lnkPath or not ".exe" in lnkExePath:
|
||||||
|
continue
|
||||||
|
secondChooseList.append(k)
|
||||||
|
if len(secondChooseList) <= 0:
|
||||||
|
secondChooseList = lnkList
|
||||||
|
rightLnk = secondChooseList[0]
|
||||||
|
miniLenge = len(rightLnk[1])
|
||||||
|
for k in secondChooseList:
|
||||||
|
# 择优选择路径最短一项
|
||||||
|
if len(k[1]) < miniLenge:
|
||||||
|
rightLnk = k
|
||||||
|
miniLenge = len(rightLnk[1])
|
||||||
|
debPackageName = "spark-" + xpinyin.Pinyin().get_pinyin(os.path.splitext(os.path.basename(rightLnk[0]))[0].replace(" ", "")).lower().replace("--", "-").replace(" ", "").replace("_", "-")
|
||||||
|
programIconPath = f"/opt/apps/{debPackageName}/entries/icons/hicolor/scalable/apps/{debPackageName}.png"
|
||||||
|
bottlePackagePath = f"{debBuildPath}/opt/apps/{debPackageName}/files/files.7z"
|
||||||
|
self.RunCommand(f"mkdir -pv '{debBuildPath}/opt/apps/{debPackageName}/entries/icons/hicolor/scalable/apps/'")
|
||||||
|
folderExePath = os.path.dirname(rightLnk[1].replace("\\", "/").replace("c:/", bottlePath))
|
||||||
|
exePathInBottle = rightLnk[1]
|
||||||
|
exeName = os.path.splitext(os.path.basename(folderExePath))[0]
|
||||||
|
exePathInSystem = rightLnk[1].replace("\\", "/").replace("c:", f"{bottlePath}/drive_c")
|
||||||
|
debPackageVersion = self.GetEXEVersion(exePathInSystem)
|
||||||
|
cpNow = False
|
||||||
|
for i in iconList:
|
||||||
|
path = i[1].replace("wineBottonPath", bottlePath).lower()
|
||||||
|
if path == exePathInSystem.lower():
|
||||||
|
self.RunCommand(f"cp -rv '{programPath}/Icon/{i[0]}.svg' '{debBuildPath}/{programIconPath}'")
|
||||||
|
exeName = i[0]
|
||||||
|
cpNow = True
|
||||||
|
break
|
||||||
|
if not cpNow:
|
||||||
|
self.RunCommand(f"'{programPath}/wrestool' '{UnUseUpperCharPath(exePathInSystem)}' -x -t 14 > '{debBuildPath}/{programIconPath}'")
|
||||||
|
else:
|
||||||
|
#/home/gfdgd_xi/Desktop/新建文件夹1/BeCyIconGrabber.exe
|
||||||
|
# 绿色软件
|
||||||
|
self.RunCommand(f"mkdir -pv '{bottlePath}'")
|
||||||
|
self.RunCommand(f"chmod 777 -Rv '{bottlePath}'")
|
||||||
|
self.RunCommand(f"WINEPREFIX='{bottlePath}' deepin-wine6-stable exit")
|
||||||
|
folderExePath = os.path.dirname(exePath.text())
|
||||||
|
exePathInBottle = f"c:/Program Files/{os.path.basename(folderExePath)}/{exeName}"
|
||||||
|
exeName = os.path.splitext(os.path.basename(os.path.basename(exePath.text())))[0]
|
||||||
|
self.RunCommand(f"mkdir -pv '{debBuildPath}/opt/apps/{debPackageName}/entries/icons/hicolor/scalable/apps/'")
|
||||||
|
self.RunCommand(f"'{programPath}/wrestool' '{exePath.text()}' -x -t 14 > '{debBuildPath}/{programIconPath}'")
|
||||||
|
# 拷贝文件到容器
|
||||||
|
self.RunCommand(f"cp -rv '{folderExePath}' '{bottlePath}/drive_c/Program Files'")
|
||||||
|
debPackageVersion = self.GetEXEVersion(exePath.text())
|
||||||
|
debDescription = f"{exeName} By Deepin Wine 6 Stable And Build By Wine Runner Easy Packager"
|
||||||
|
debDepends = "deepin-wine6-stable, spark-dwine-helper | store.spark-app.spark-dwine-helper, fonts-wqy-microhei, fonts-wqy-zenhei"
|
||||||
|
self.RunCommand(f"mkdir -pv '{debBuildPath}/DEBIAN'")
|
||||||
|
self.RunCommand(f"mkdir -pv '{debBuildPath}/opt/apps/{debPackageName}/files'")
|
||||||
|
self.RunCommand(f"mkdir -pv '{debBuildPath}/opt/apps/{debPackageName}/entries/applications'")
|
||||||
|
#self.RunCommand(f"mkdir -pv '{debBuildPath}/opt/apps/{debPackageName}/entries/icons/hicolor/scalable/apps/'")
|
||||||
|
############ 处理容器
|
||||||
|
# 对用户目录进行处理
|
||||||
|
os.chdir(bottlePath)
|
||||||
|
self.RunCommand("sed -i \"s#$USER#@current_user@#\" ./*.reg")
|
||||||
|
os.chdir(f"{bottlePath}/drive_c/users")
|
||||||
|
# 如果缩放文件 scale.txt 存在,需要移除以便用户自行调节缩放设置
|
||||||
|
if os.path.exists(f"{bottlePath}/scale.txt"):
|
||||||
|
self.RunCommand(f"rm -rfv '{bottlePath}/scale.txt'")
|
||||||
|
# 删除因为脚本失误导致用户目录嵌套(如果存在)
|
||||||
|
if os.path.exists(f"{bottlePath}/drive_c/users/@current_user@/@current_user@"):
|
||||||
|
self.RunCommand(f"rm -rfv '{bottlePath}/drive_c/users/@current_user@/@current_user@'")
|
||||||
|
self.RunCommand(f"mv -fv '{os.getlogin()}' @current_user@")
|
||||||
|
self.RunCommand(f"rm -fv '{bottlePath}/drive_c/users/@current_user@/我的'*")
|
||||||
|
self.RunCommand(f"rm -fv '{bottlePath}/drive_c/users/@current_user@/My '*")
|
||||||
|
self.RunCommand(f"rm -fv '{bottlePath}/drive_c/users/@current_user@/Desktop'")
|
||||||
|
self.RunCommand(f"rm -fv '{bottlePath}/drive_c/users/@current_user@/Downloads'")
|
||||||
|
self.RunCommand(f"rm -fv '{bottlePath}/drive_c/users/@current_user@/Templates'")
|
||||||
|
########### 打包容器
|
||||||
|
self.RunCommand(f"7z a '{bottlePackagePath}' '{bottlePath}/'*")
|
||||||
|
########### 生成文件内容
|
||||||
|
buildProgramSize = getFileFolderSize(debBuildPath) / 1000
|
||||||
|
replaceMap = [
|
||||||
|
["@@@Package@@@", debPackageName],
|
||||||
|
["@@@Version@@@", debPackageVersion],
|
||||||
|
["@@@Maintainer@@@", debMaintainer],
|
||||||
|
["@@@Depends@@@", debDepends],
|
||||||
|
["@@@Description@@@", debDescription],
|
||||||
|
["@@@Installed-Size@@@", str(buildProgramSize)],
|
||||||
|
["@@@Name@@@", exeName],
|
||||||
|
["@@@EXEC_PATH@@@", exePathInBottle],
|
||||||
|
["@@@Icon@@@", programIconPath]
|
||||||
|
]
|
||||||
|
debControl = ReplaceText(control, replaceMap)
|
||||||
|
debPostrm = ReplaceText(postrm, replaceMap)
|
||||||
|
debInfo = ReplaceText(info, replaceMap)
|
||||||
|
debRunSh = ReplaceText(runsh, replaceMap)
|
||||||
|
debDesktop = ReplaceText(desktopFile, replaceMap)
|
||||||
|
########### 写入文件
|
||||||
|
WriteTxt(f"{debBuildPath}/opt/apps/{debPackageName}/entries/applications/{debPackageName}.desktop", debDesktop)
|
||||||
|
WriteTxt(f"{debBuildPath}/opt/apps/{debPackageName}/files/run.sh", debRunSh)
|
||||||
|
WriteTxt(f"{debBuildPath}/opt/apps/{debPackageName}/info", debInfo)
|
||||||
|
WriteTxt(f"{debBuildPath}/DEBIAN/control", debControl)
|
||||||
|
WriteTxt(f"{debBuildPath}/DEBIAN/postrm", debPostrm)
|
||||||
|
########### 赋值权限
|
||||||
|
self.RunCommand(f"chmod -Rv 644 '{debBuildPath}/opt/apps/{debPackageName}/info'")
|
||||||
|
self.RunCommand(f"chmod -Rv 0755 '{debBuildPath}/DEBIAN'")
|
||||||
|
self.RunCommand(f"chmod -Rv 755 '{debBuildPath}/opt/apps/{debPackageName}/files/'*.sh")
|
||||||
|
self.RunCommand(f"chmod -Rv 755 '{debBuildPath}/opt/apps/{debPackageName}/entries/applications/'*.desktop")
|
||||||
|
########### 打包 deb
|
||||||
|
print(debPackageVersion)
|
||||||
|
self.RunCommand(f"dpkg -b '{debBuildPath}' '{desktopPath}/{debPackageName}_{debPackageVersion}_i386.deb'")
|
||||||
|
self.info.emit("打包完成!")
|
||||||
|
self.disbledAll.emit(False)
|
||||||
|
########### 移除临时文件
|
||||||
|
self.RunCommand(f"rm -rfv '{debBuildPath}' > /dev/null")
|
||||||
|
self.RunCommand(f"rm -rfv '{bottlePath}' > /dev/null")
|
||||||
|
except:
|
||||||
|
self.RunCommand(f"rm -rfv '{debBuildPath}' > /dev/null")
|
||||||
|
self.RunCommand(f"rm -rfv '{bottlePath}' > /dev/null")
|
||||||
|
# 若打包出现任何错误
|
||||||
|
traceback.print_exc()
|
||||||
|
self.error.emit(f"打包错误,详细详细如下:{traceback.format_exc()}")
|
||||||
|
self.showLogText.emit(traceback.format_exc())
|
||||||
|
self.disbledAll.emit(False)
|
||||||
|
|
||||||
|
#/home/gfdgd_xi/Downloads/XPcalc.exe
|
||||||
|
def RunBuildThread():
|
||||||
|
global buildThread
|
||||||
|
buildThread = RunThread()
|
||||||
|
buildThread.showLogText.connect(ShowText)
|
||||||
|
buildThread.error.connect(ErrorMessage)
|
||||||
|
buildThread.info.connect(InformationMessage)
|
||||||
|
buildThread.question.connect(QuestionMessage)
|
||||||
|
buildThread.disbledAll.connect(DisbledAndEnabledAll)
|
||||||
|
buildThread.cleanPressState.connect(CleanPressCompleteDownloadState)
|
||||||
|
logText.clear()
|
||||||
|
buildThread.start()
|
||||||
|
|
||||||
|
pressCompleteDownload = False
|
||||||
|
|
||||||
|
def PressCompleteDownload():
|
||||||
|
global pressCompleteDownload
|
||||||
|
pressCompleteDownload = True
|
||||||
|
installCmpleteButton.setDisabled(True)
|
||||||
|
|
||||||
|
def BrowserExe():
|
||||||
|
filePath = QtWidgets.QFileDialog.getOpenFileName(window, "选择 exe", get_home(), "可执行文件(*.exe);;所有文件(*.*)")
|
||||||
|
if filePath[0] != "" or filePath[0] != None:
|
||||||
|
exePath.setText(filePath[0])
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
programPath = os.path.split(os.path.realpath(__file__))[0] # 返回 string
|
||||||
|
iconPath = "{}/deepin-wine-runner.svg".format(programPath)
|
||||||
|
information = json.loads(ReadTxt(f"{programPath}/information.json"))
|
||||||
|
iconListUnBuild = json.loads(ReadTxt(f"{programPath}/IconList.json"))[0]
|
||||||
|
iconList = json.loads(ReadTxt(f"{programPath}/IconList.json"))[1]
|
||||||
|
for i in iconListUnBuild:
|
||||||
|
iconList.append(i)
|
||||||
|
app = QtWidgets.QApplication(sys.argv)
|
||||||
|
version = information["Version"]
|
||||||
|
window = QtWidgets.QMainWindow()
|
||||||
|
widget = QtWidgets.QWidget()
|
||||||
|
layout = QtWidgets.QGridLayout()
|
||||||
|
exePath = QtWidgets.QLineEdit()
|
||||||
|
browserExeButton = QtWidgets.QPushButton("浏览……")
|
||||||
|
logText = QtWidgets.QTextBrowser()
|
||||||
|
logText.setStyleSheet("""
|
||||||
|
background-color: black;
|
||||||
|
color: white;
|
||||||
|
""")
|
||||||
|
controlLayout = QtWidgets.QHBoxLayout()
|
||||||
|
buildButton = QtWidgets.QPushButton("现在打包……")
|
||||||
|
installCmpleteButton = QtWidgets.QPushButton("安装程序执行完成")
|
||||||
|
browserExeButton.clicked.connect(BrowserExe)
|
||||||
|
buildButton.clicked.connect(RunBuildThread)
|
||||||
|
installCmpleteButton.clicked.connect(PressCompleteDownload)
|
||||||
|
installCmpleteButton.setDisabled(True)
|
||||||
|
controlLayout.addWidget(buildButton)
|
||||||
|
controlLayout.addWidget(installCmpleteButton)
|
||||||
|
layout.addWidget(QtWidgets.QLabel("选择 EXE:"), 0, 0)
|
||||||
|
layout.addWidget(exePath, 0, 1)
|
||||||
|
layout.addWidget(browserExeButton, 0, 2)
|
||||||
|
layout.addLayout(controlLayout, 1, 1)
|
||||||
|
layout.addWidget(logText, 2, 0, 1, 3)
|
||||||
|
widget.setLayout(layout)
|
||||||
|
window.setCentralWidget(widget)
|
||||||
|
window.setWindowTitle(f"Wine 运行器 {version}——简易打包器")
|
||||||
|
try:
|
||||||
|
exePath.setText(sys.argv[1])
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
window.resize(int(window.frameGeometry().width() * 1.2), int(window.frameGeometry().height() * 1.1))
|
||||||
|
window.show()
|
||||||
|
sys.exit(app.exec_())
|
@ -203,9 +203,36 @@ def Build7zButton_Clicked():
|
|||||||
QT.thread.start()
|
QT.thread.start()
|
||||||
|
|
||||||
def make_deb(build=False):
|
def make_deb(build=False):
|
||||||
|
global bottleNameLock
|
||||||
clean_textbox1_things()
|
clean_textbox1_things()
|
||||||
disabled_or_NORMAL_all(False)
|
disabled_or_NORMAL_all(False)
|
||||||
if e1_text.text() == "" or e2_text.text() == "" or e3_text.text() == "" or e4_text.text() == "" or e5_text.text() == "" or e6_text.text() == "" or e7_text.text() == "" or e8_text.text() == "" or e12_text.text() == "":
|
badComplete = False
|
||||||
|
# 规范检测
|
||||||
|
if e1_text.text().lower() != e1_text.text():
|
||||||
|
if QtWidgets.QMessageBox.warning(window, "提示", f"包名 {e1_text.text()} 似乎不符合规范,可能会导致打包后的包无法投稿到应用商店,是否继续?\n可参考 deb 安装包打包标准", QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No) == QtWidgets.QMessageBox.No:
|
||||||
|
disabled_or_NORMAL_all(True)
|
||||||
|
label13_text_change("用户已取消")
|
||||||
|
return
|
||||||
|
for i in range(len(iconUiList)):
|
||||||
|
if os.path.splitext(iconUiList[i][4].text())[1] == ".ico":
|
||||||
|
if QtWidgets.QMessageBox.warning(window, "提示", f"图标 {iconUiList[i][4].text()} 似乎为 ico 格式,可能会导致打包后的程序在启动器的图标无法正常显示,是否继续?", QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No) == QtWidgets.QMessageBox.No:
|
||||||
|
disabled_or_NORMAL_all(True)
|
||||||
|
label13_text_change("用户已取消")
|
||||||
|
return
|
||||||
|
if os.path.exists(iconUiList[i][0].text()) and not "c:" in iconUiList[i][0].text().lower():
|
||||||
|
if not e6_text.text() in iconUiList[i][0].text():
|
||||||
|
if QtWidgets.QMessageBox.warning(window, "提示", f"路径 {iconUiList[i][0].text()} 似乎不符合规范且不位于容器内,可能会导致打包后的程序无法运行,是否继续?\n可参考 Windows 下的文件路径", QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No) == QtWidgets.QMessageBox.No:
|
||||||
|
disabled_or_NORMAL_all(True)
|
||||||
|
label13_text_change("用户已取消")
|
||||||
|
return
|
||||||
|
if QtWidgets.QMessageBox.warning(window, "提示", f"路径 {iconUiList[i][0].text()} 似乎不符合规范,可能会导致打包后的程序无法运行,是否继续?\n可参考 Windows 下的文件路径", QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No) == QtWidgets.QMessageBox.No:
|
||||||
|
disabled_or_NORMAL_all(True)
|
||||||
|
label13_text_change("用户已取消")
|
||||||
|
return
|
||||||
|
for k in [0, 3]:
|
||||||
|
if iconUiList[i][k].text().replace(" ", "") == "":
|
||||||
|
badComplete = True
|
||||||
|
if badComplete or e1_text.text() == "" or e2_text.text() == "" or e3_text.text() == "" or e4_text.text() == "" or e5_text.text() == "" or e6_text.text() == "" or e7_text.text() == "" or e8_text.text() == "" or e12_text.text() == "":
|
||||||
QtWidgets.QMessageBox.critical(widget, "错误", "必填信息没有填写完整,无法继续构建 deb 包")
|
QtWidgets.QMessageBox.critical(widget, "错误", "必填信息没有填写完整,无法继续构建 deb 包")
|
||||||
disabled_or_NORMAL_all(True)
|
disabled_or_NORMAL_all(True)
|
||||||
label13_text_change("必填信息没有填写完整,无法继续构建 deb 包")
|
label13_text_change("必填信息没有填写完整,无法继续构建 deb 包")
|
||||||
@ -232,6 +259,7 @@ def make_deb(build=False):
|
|||||||
QT.thread.errorMsg.connect(ErrorMsg)
|
QT.thread.errorMsg.connect(ErrorMsg)
|
||||||
QT.thread.infoMsg.connect(InfoMsg)
|
QT.thread.infoMsg.connect(InfoMsg)
|
||||||
QT.thread.disabled_or_NORMAL_all.connect(disabled_or_NORMAL_all)
|
QT.thread.disabled_or_NORMAL_all.connect(disabled_or_NORMAL_all)
|
||||||
|
bottleNameLock = False
|
||||||
QT.thread.start()
|
QT.thread.start()
|
||||||
#thread.start()
|
#thread.start()
|
||||||
|
|
||||||
@ -245,7 +273,6 @@ def ReplaceText(string: str, lists: list):
|
|||||||
return string
|
return string
|
||||||
|
|
||||||
class make_deb_threading(QtCore.QThread):
|
class make_deb_threading(QtCore.QThread):
|
||||||
|
|
||||||
signal = QtCore.pyqtSignal(str)
|
signal = QtCore.pyqtSignal(str)
|
||||||
label = QtCore.pyqtSignal(str)
|
label = QtCore.pyqtSignal(str)
|
||||||
getSavePath = QtCore.pyqtSignal(str)
|
getSavePath = QtCore.pyqtSignal(str)
|
||||||
@ -1204,7 +1231,7 @@ fi
|
|||||||
# 获取文件大小
|
# 获取文件大小
|
||||||
################
|
################
|
||||||
self.label.emit("正在计算文件大小……")
|
self.label.emit("正在计算文件大小……")
|
||||||
size = int(getFileFolderSize(debPackagePath) / 1024)
|
size = int(getFileFolderSize(debPackagePath) / 1000)
|
||||||
################
|
################
|
||||||
# 写入文本文档
|
# 写入文本文档
|
||||||
################
|
################
|
||||||
@ -1324,6 +1351,12 @@ StartupNotify=false
|
|||||||
self.label.emit("正在构建 deb 包……")
|
self.label.emit("正在构建 deb 包……")
|
||||||
self.run_command("bash -c 'dpkg -b \"{}\" \"{}\"'".format(debPackagePath, e12_text.text()))
|
self.run_command("bash -c 'dpkg -b \"{}\" \"{}\"'".format(debPackagePath, e12_text.text()))
|
||||||
################
|
################
|
||||||
|
# 删除临时文件
|
||||||
|
################
|
||||||
|
if not self.build:
|
||||||
|
self.label.emit("正在删除临时文件……")
|
||||||
|
self.run_command(f"rm -rfv '{debPackagePath}'")
|
||||||
|
################
|
||||||
# 完成构建
|
# 完成构建
|
||||||
################
|
################
|
||||||
self.label.emit("完成构建!")
|
self.label.emit("完成构建!")
|
||||||
@ -1705,9 +1738,9 @@ def AddTab():
|
|||||||
desktopIconTabLayout = QtWidgets.QGridLayout()
|
desktopIconTabLayout = QtWidgets.QGridLayout()
|
||||||
desktopIconTabLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "wine 容器里需要运行的可执行文件路径(※必填):")), 6, 0, 1, 1)
|
desktopIconTabLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "wine 容器里需要运行的可执行文件路径(※必填):")), 6, 0, 1, 1)
|
||||||
desktopIconTabLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "要显示的 .desktop 文件的分类(※必填):")), 7, 0, 1, 1)
|
desktopIconTabLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "要显示的 .desktop 文件的分类(※必填):")), 7, 0, 1, 1)
|
||||||
desktopIconTabLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "wine 容器里需要运行的可执行文件的参数(选填):")), 8, 0, 1, 1)
|
desktopIconTabLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "wine 容器里需要运行的可执行文件的参数:")), 8, 0, 1, 1)
|
||||||
desktopIconTabLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "要显示的 .desktop 文件的名称(※必填):")), 9, 0, 1, 1)
|
desktopIconTabLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "要显示的 .desktop 文件的名称(※必填):")), 9, 0, 1, 1)
|
||||||
desktopIconTabLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "要显示的 .desktop 文件的图标(选填):")), 10, 0, 1, 1)
|
desktopIconTabLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "要显示的 .desktop 文件的图标:")), 10, 0, 1, 1)
|
||||||
iconTab1.setLayout(desktopIconTabLayout)
|
iconTab1.setLayout(desktopIconTabLayout)
|
||||||
desktopIconTab.addTab(iconTab1, f"图标{desktopIconTab.count() + 1}")
|
desktopIconTab.addTab(iconTab1, f"图标{desktopIconTab.count() + 1}")
|
||||||
desktopIconTabLayout.addWidget(e7_text, 6, 1, 1, 1)
|
desktopIconTabLayout.addWidget(e7_text, 6, 1, 1, 1)
|
||||||
@ -1717,6 +1750,8 @@ def AddTab():
|
|||||||
desktopIconTabLayout.addWidget(e9_text, 10, 1, 1, 1)
|
desktopIconTabLayout.addWidget(e9_text, 10, 1, 1, 1)
|
||||||
desktopIconTabLayout.addWidget(button2, 10, 2, 1, 1)
|
desktopIconTabLayout.addWidget(button2, 10, 2, 1, 1)
|
||||||
e7_text.textChanged.connect(ChangeTapTitle)
|
e7_text.textChanged.connect(ChangeTapTitle)
|
||||||
|
e7_text.setPlaceholderText("例如 c:/Program Files/Tencent/QQ/Bin/QQ.exe")
|
||||||
|
e9_text.setPlaceholderText("支持 png 和 svg 格式,不支持 ico 格式")
|
||||||
iconUiList.append([e7_text, option1_text, e15_text, e8_text, e9_text])
|
iconUiList.append([e7_text, option1_text, e15_text, e8_text, e9_text])
|
||||||
print(iconUiList)
|
print(iconUiList)
|
||||||
|
|
||||||
@ -1727,6 +1762,26 @@ def DelTab():
|
|||||||
del iconUiList[desktopIconTab.currentIndex()]
|
del iconUiList[desktopIconTab.currentIndex()]
|
||||||
desktopIconTab.removeTab(desktopIconTab.currentIndex())
|
desktopIconTab.removeTab(desktopIconTab.currentIndex())
|
||||||
|
|
||||||
|
def ChangeBottleName():
|
||||||
|
global bottleNameLock
|
||||||
|
global bottleNameChangeLock
|
||||||
|
e1_text.setText(e1_text.text().replace(" ", ""))
|
||||||
|
if bottleNameLock:
|
||||||
|
return
|
||||||
|
if os.path.basename(e6_text.text()) == ".wine" or e6_text.text() == "":
|
||||||
|
bottleNameChangeLock = True
|
||||||
|
e5_text.setText(e1_text.text())
|
||||||
|
return
|
||||||
|
bottleNameChangeLock = True
|
||||||
|
e5_text.setText(os.path.basename(e6_text.text().replace(" ", "")))
|
||||||
|
|
||||||
|
def LockBottleName():
|
||||||
|
global bottleNameLock
|
||||||
|
if bottleNameChangeLock:
|
||||||
|
return
|
||||||
|
bottleNameLock = True
|
||||||
|
|
||||||
|
bottleNameLock = False
|
||||||
###############
|
###############
|
||||||
# 程序信息
|
# 程序信息
|
||||||
###############
|
###############
|
||||||
@ -1820,14 +1875,17 @@ buildDebDir.clicked.connect(lambda: make_deb(True))
|
|||||||
build7z.clicked.connect(Build7zButton_Clicked)
|
build7z.clicked.connect(Build7zButton_Clicked)
|
||||||
installDeb.clicked.connect(InstallDeb)
|
installDeb.clicked.connect(InstallDeb)
|
||||||
wineFrame.addWidget(wineVersion)
|
wineFrame.addWidget(wineVersion)
|
||||||
|
e1_text.textChanged.connect(ChangeBottleName)
|
||||||
|
e5_text.textChanged.connect(LockBottleName)
|
||||||
|
e6_text.textChanged.connect(ChangeBottleName)
|
||||||
e7_text.textChanged.connect(ChangeTapTitle)
|
e7_text.textChanged.connect(ChangeTapTitle)
|
||||||
# 创建控件
|
# 创建控件
|
||||||
widgetLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "要打包的 deb 包的包名(※必填):")), 0, 0, 1, 1)
|
widgetLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "要打包的 deb 包的包名(※必填):")), 0, 0, 1, 1)
|
||||||
widgetLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "要打包的 deb 包的版本号(※必填):")), 1, 0, 1, 1)
|
widgetLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "deb 包的版本号(※必填):")), 1, 0, 1, 1)
|
||||||
widgetLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "要打包的 deb 包的说明(※必填):")), 2, 0, 1, 1)
|
widgetLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "deb 包的说明(※必填):")), 2, 0, 1, 1)
|
||||||
widgetLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "要打包的 deb 包的维护者(※必填):")), 3, 0, 1, 1)
|
widgetLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "deb 包的维护者(※必填):")), 3, 0, 1, 1)
|
||||||
widgetLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "要解压的 wine 容器的容器名(※必填):")), 4, 0, 1, 1)
|
widgetLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "要解压的 wine 容器的名称(※必填):")), 4, 0, 1, 1)
|
||||||
widgetLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "要解压的 wine 容器(※必填):")), 5, 0, 1, 1)
|
widgetLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "要打包的 wine 容器路径(※必填):")), 5, 0, 1, 1)
|
||||||
desktopIconTab = QtWidgets.QTabWidget()
|
desktopIconTab = QtWidgets.QTabWidget()
|
||||||
controlWidget = QtWidgets.QWidget()
|
controlWidget = QtWidgets.QWidget()
|
||||||
controlWidgetLayout = QtWidgets.QHBoxLayout()
|
controlWidgetLayout = QtWidgets.QHBoxLayout()
|
||||||
@ -1842,9 +1900,9 @@ iconTab1 = QtWidgets.QWidget()
|
|||||||
desktopIconTabLayout = QtWidgets.QGridLayout()
|
desktopIconTabLayout = QtWidgets.QGridLayout()
|
||||||
desktopIconTabLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "wine 容器里需要运行的可执行文件路径(※必填):")), 6, 0, 1, 1)
|
desktopIconTabLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "wine 容器里需要运行的可执行文件路径(※必填):")), 6, 0, 1, 1)
|
||||||
desktopIconTabLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "要显示的 .desktop 文件的分类(※必填):")), 7, 0, 1, 1)
|
desktopIconTabLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "要显示的 .desktop 文件的分类(※必填):")), 7, 0, 1, 1)
|
||||||
desktopIconTabLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "wine 容器里需要运行的可执行文件的参数(选填):")), 8, 0, 1, 1)
|
desktopIconTabLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "wine 容器里需要运行的可执行文件的参数:")), 8, 0, 1, 1)
|
||||||
desktopIconTabLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "要显示的 .desktop 文件的名称(※必填):")), 9, 0, 1, 1)
|
desktopIconTabLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "要显示的 .desktop 文件的名称(※必填):")), 9, 0, 1, 1)
|
||||||
desktopIconTabLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "要显示的 .desktop 文件的图标(选填):")), 10, 0, 1, 1)
|
desktopIconTabLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "要显示的 .desktop 文件的图标:")), 10, 0, 1, 1)
|
||||||
iconTab1.setLayout(desktopIconTabLayout)
|
iconTab1.setLayout(desktopIconTabLayout)
|
||||||
#desktopIconTab.setTabPosition(QtWidgets.QTabWidget.East)
|
#desktopIconTab.setTabPosition(QtWidgets.QTabWidget.East)
|
||||||
desktopIconTab.addTab(iconTab1, "Defult")
|
desktopIconTab.addTab(iconTab1, "Defult")
|
||||||
@ -1911,6 +1969,10 @@ e2_text.textChanged.connect(AutoPathSet)
|
|||||||
debArch.currentIndexChanged.connect(AutoPathSet)
|
debArch.currentIndexChanged.connect(AutoPathSet)
|
||||||
debArch.currentIndexChanged.connect(ChangeArchCombobox)
|
debArch.currentIndexChanged.connect(ChangeArchCombobox)
|
||||||
e12_text.textChanged.connect(UserPathSet)
|
e12_text.textChanged.connect(UserPathSet)
|
||||||
|
e1_text.setPlaceholderText("例如 spark-deepin-wine-runner,不建议有大写字符")
|
||||||
|
e2_text.setPlaceholderText(f"例如 {version}")
|
||||||
|
e7_text.setPlaceholderText("例如 c:/Program Files/Tencent/QQ/Bin/QQ.exe")
|
||||||
|
e9_text.setPlaceholderText("支持 png 和 svg 格式,不支持 ico 格式")
|
||||||
# 菜单栏
|
# 菜单栏
|
||||||
menu = window.menuBar()
|
menu = window.menuBar()
|
||||||
programmenu = menu.addMenu(QtCore.QCoreApplication.translate("U", "程序"))
|
programmenu = menu.addMenu(QtCore.QCoreApplication.translate("U", "程序"))
|
||||||
@ -1927,6 +1989,7 @@ else:
|
|||||||
uploadSparkStoreProgram = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "使用投稿器投稿(推荐,请先安装投稿器)"))
|
uploadSparkStoreProgram = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "使用投稿器投稿(推荐,请先安装投稿器)"))
|
||||||
uploadSparkStoreProgram.setDisabled(True)
|
uploadSparkStoreProgram.setDisabled(True)
|
||||||
tip = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "小提示"))
|
tip = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "小提示"))
|
||||||
|
getPdfHelp = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "Wine 运行器和 Wine 打包器傻瓜式使用教程(小白专用)\nBy @雁舞白沙"))
|
||||||
exit.triggered.connect(window.close)
|
exit.triggered.connect(window.close)
|
||||||
tip.triggered.connect(helps)
|
tip.triggered.connect(helps)
|
||||||
programmenu.addAction(exit)
|
programmenu.addAction(exit)
|
||||||
@ -1938,7 +2001,9 @@ debE.triggered.connect(lambda: ReadDeb(False))
|
|||||||
debX.triggered.connect(lambda: ReadDeb(True))
|
debX.triggered.connect(lambda: ReadDeb(True))
|
||||||
uploadSparkStoreWebsize.triggered.connect(lambda: webbrowser.open_new_tab("https://upload.deepinos.org"))
|
uploadSparkStoreWebsize.triggered.connect(lambda: webbrowser.open_new_tab("https://upload.deepinos.org"))
|
||||||
uploadSparkStoreProgram.triggered.connect(lambda: threading.Thread(target=os.system, args=[f"/opt/spark-store-submitter/bin/spark-store-submitter '{e12_text.text()}'"]).start())
|
uploadSparkStoreProgram.triggered.connect(lambda: threading.Thread(target=os.system, args=[f"/opt/spark-store-submitter/bin/spark-store-submitter '{e12_text.text()}'"]).start())
|
||||||
|
getPdfHelp.triggered.connect(lambda: webbrowser.open_new_tab("https://gitee.com/gfdgd-xi/deep-wine-runner/raw/main/Wine%E8%BF%90%E8%A1%8C%E5%99%A8%E5%92%8CWine%E6%89%93%E5%8C%85%E5%99%A8%E5%82%BB%E7%93%9C%E5%BC%8F%E4%BD%BF%E7%94%A8%E6%95%99%E7%A8%8B%EF%BC%88%E5%B0%8F%E7%99%BD%E4%B8%93%E7%94%A8%EF%BC%8920221126-V2.pdf"))
|
||||||
help.addAction(tip)
|
help.addAction(tip)
|
||||||
|
help.addAction(getPdfHelp)
|
||||||
# 控件配置
|
# 控件配置
|
||||||
try:
|
try:
|
||||||
e6_text.setText(sys.argv[1].replace("~", get_home()))
|
e6_text.setText(sys.argv[1].replace("~", get_home()))
|
||||||
|
@ -455,6 +455,16 @@ StartupNotify=true''') # 写入文本文档
|
|||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
QtWidgets.QMessageBox.critical(widget, "错误", f"快捷方式创建失败,错误如下:\n{traceback.format_exc()}")
|
QtWidgets.QMessageBox.critical(widget, "错误", f"快捷方式创建失败,错误如下:\n{traceback.format_exc()}")
|
||||||
|
|
||||||
|
def ConfigQemu():
|
||||||
|
lists = []
|
||||||
|
for i in qemuBottleList:
|
||||||
|
lists.append(f"{i[0]}/{i[1]}")
|
||||||
|
choose = QtWidgets.QInputDialog.getItem(window, "提示", "选择需要 Chroot 到里面的容器", lists, 0, False)
|
||||||
|
if not choose[1]:
|
||||||
|
return
|
||||||
|
threading.Thread(target=OpenTerminal, args=[f"python3 '{programPath}/QemuRun.py' '{choose[0]}' "]).start()
|
||||||
|
print(choose)
|
||||||
|
|
||||||
# 生成 desktop 文件在桌面
|
# 生成 desktop 文件在桌面
|
||||||
# (第四个按钮的事件)
|
# (第四个按钮的事件)
|
||||||
def make_desktop_on_desktop():
|
def make_desktop_on_desktop():
|
||||||
@ -1808,6 +1818,7 @@ def UploadLog():
|
|||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
QtWidgets.QMessageBox.critical(window, "错误", "上传失败!")
|
QtWidgets.QMessageBox.critical(window, "错误", "上传失败!")
|
||||||
|
|
||||||
|
|
||||||
def SaveLog():
|
def SaveLog():
|
||||||
path = QtWidgets.QFileDialog.getSaveFileName(window, "保存日志", get_home(), "txt文件(*.txt);;html 文件(*.html);;所有文件(*.*))")
|
path = QtWidgets.QFileDialog.getSaveFileName(window, "保存日志", get_home(), "txt文件(*.txt);;html 文件(*.html);;所有文件(*.*))")
|
||||||
if not path[1]:
|
if not path[1]:
|
||||||
@ -1843,6 +1854,8 @@ defultProgramList = {
|
|||||||
"BuildByBottleName": False,
|
"BuildByBottleName": False,
|
||||||
"AutoPath": 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"): # 如果没有配置文件夹
|
if not os.path.exists(get_home() + "/.config/deepin-wine-runner"): # 如果没有配置文件夹
|
||||||
os.mkdir(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"): # 如果没有配置文件
|
if not os.path.exists(get_home() + "/.config/deepin-wine-runner/ShellHistory.json"): # 如果没有配置文件
|
||||||
@ -1910,37 +1923,87 @@ try:
|
|||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
# 读取自定义安装的 Wine(需要解包的才能使用)
|
# 读取自定义安装的 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:
|
try:
|
||||||
for i in json.loads(readtxt(f"{programPath}/wine/winelist.json")):
|
# 不再从列表读取,直接读目录
|
||||||
if os.path.exists(f"{programPath}/wine/{i}"):
|
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 = ""
|
name = ""
|
||||||
value = ""
|
qemuInstall = False
|
||||||
|
nameValue = [["", ""]]
|
||||||
try:
|
try:
|
||||||
if os.path.exists("/opt/deepin-box86/box86"):
|
if os.path.exists("/opt/deepin-box86/box86"):
|
||||||
name = "基于 UOS box86 的 "
|
nameValue.append(
|
||||||
value = f"WINEPREDLL='{programPath}/dlls-arm' WINEDLLPATH=/opt/deepin-wine6-stable/lib BOX86_NOSIGSEGV=1 /opt/deepin-box86/box86 "
|
[
|
||||||
|
"基于 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:
|
if os.system("which box86") == 0:
|
||||||
name = "基于 box86 的 "
|
nameValue.append(
|
||||||
value = f"box86 "
|
[
|
||||||
|
"基于 box86 的 ",
|
||||||
|
f"box86 "
|
||||||
|
]
|
||||||
|
)
|
||||||
if os.system("which box64") == 0:
|
if os.system("which box64") == 0:
|
||||||
name = "基于 box64 的 "
|
nameValue.append(
|
||||||
value = f"box64 "
|
[
|
||||||
|
"基于 box64 的 ",
|
||||||
|
f"box64 "
|
||||||
|
]
|
||||||
|
)
|
||||||
if os.system("which exagear") == 0:
|
if os.system("which exagear") == 0:
|
||||||
name = "基于 exagear 的 "
|
nameValue.append(
|
||||||
value = f"exagear "
|
[
|
||||||
|
"基于 exagear 的 ",
|
||||||
|
f"exagear "
|
||||||
|
]
|
||||||
|
)
|
||||||
if os.path.exists("/opt/exagear/bin/ubt_x64a64_al"):
|
if os.path.exists("/opt/exagear/bin/ubt_x64a64_al"):
|
||||||
name = "基于 UOS exagear 的 "
|
nameValue.append(
|
||||||
value = 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 -- "
|
[
|
||||||
|
"基于 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:
|
except:
|
||||||
pass
|
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"):
|
if os.path.exists(f"{programPath}/wine/{i}/bin/wine"):
|
||||||
wine[f"{name}{programPath}/wine/{i}/bin/wine"] = f"{value}{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"{name}{programPath}/wine/{i}/bin/wine")
|
canUseWine.append(f"{k[0]}{chrootProgramPath}/wine/{i}/bin/wine")
|
||||||
untipsWine.append(f"{name}{programPath}/wine/{i}/bin/wine")
|
untipsWine.append(f"{k[0]}{chrootProgramPath}/wine/{i}/bin/wine")
|
||||||
if os.path.exists(f"{programPath}/wine/{i}/bin/wine64"):
|
if os.path.exists(f"{programPath}/wine/{i}/bin/wine64"):
|
||||||
wine[f"{name}{programPath}/wine/{i}/bin/wine64"] = f"{value}{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"{name}{programPath}/wine/{i}/bin/wine64")
|
canUseWine.append(f"{k[0]}{chrootProgramPath}/wine/{i}/bin/wine64")
|
||||||
untipsWine.append(f"{name}{programPath}/wine/{i}/bin/wine64")
|
untipsWine.append(f"{k[0]}{chrootProgramPath}/wine/{i}/bin/wine64")
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
@ -1975,6 +2038,7 @@ except:
|
|||||||
def getFileFolderSize(fileOrFolderPath):
|
def getFileFolderSize(fileOrFolderPath):
|
||||||
"""get size for file or folder"""
|
"""get size for file or folder"""
|
||||||
totalSize = 0
|
totalSize = 0
|
||||||
|
try:
|
||||||
if not os.path.exists(fileOrFolderPath):
|
if not os.path.exists(fileOrFolderPath):
|
||||||
return totalSize
|
return totalSize
|
||||||
if os.path.isfile(fileOrFolderPath):
|
if os.path.isfile(fileOrFolderPath):
|
||||||
@ -1991,6 +2055,8 @@ def getFileFolderSize(fileOrFolderPath):
|
|||||||
curSubFileSize = os.path.getsize(curSubEntryFullPath) # 1891
|
curSubFileSize = os.path.getsize(curSubEntryFullPath) # 1891
|
||||||
totalSize += curSubFileSize
|
totalSize += curSubFileSize
|
||||||
return totalSize
|
return totalSize
|
||||||
|
except:
|
||||||
|
return totalSize
|
||||||
|
|
||||||
# 获取当前语言
|
# 获取当前语言
|
||||||
def get_now_lang()->"获取当前语言":
|
def get_now_lang()->"获取当前语言":
|
||||||
@ -2030,8 +2096,8 @@ class GetVersionThread(QtCore.QThread):
|
|||||||
}
|
}
|
||||||
# 直接判断是不是 Docker 版本
|
# 直接判断是不是 Docker 版本
|
||||||
if os.path.exists(f"{programPath}/docker.txt") or os.path.exists("/.dockerenv"):
|
if os.path.exists(f"{programPath}/docker.txt") or os.path.exists("/.dockerenv"):
|
||||||
programVersionType = "Docker 内置版本"
|
programVersionType = "Docker/Chroot 内置版本"
|
||||||
window.setWindowTitle(f"{title} (Docker 内置版本)")
|
window.setWindowTitle(f"{title} (Docker/Chroot 内置版本)")
|
||||||
self.signal.emit("")
|
self.signal.emit("")
|
||||||
else:
|
else:
|
||||||
programVersionType = "从源码运行的版本"
|
programVersionType = "从源码运行的版本"
|
||||||
@ -2100,6 +2166,7 @@ print(wine)
|
|||||||
# 程序信息
|
# 程序信息
|
||||||
###########################
|
###########################
|
||||||
iconPath = "{}/deepin-wine-runner.svg".format(programPath)
|
iconPath = "{}/deepin-wine-runner.svg".format(programPath)
|
||||||
|
#iconPath = "{}/Icon/Program/wine运行器.png".format(programPath)
|
||||||
programUrl = "https://gitee.com/gfdgd-xi/deep-wine-runner\nhttps://github.com/gfdgd-xi/deep-wine-runner\nhttps://www.gitlink.org.cn/gfdgd_xi/deep-wine-runner\nhttps://gfdgd-xi.github.io"
|
programUrl = "https://gitee.com/gfdgd-xi/deep-wine-runner\nhttps://github.com/gfdgd-xi/deep-wine-runner\nhttps://www.gitlink.org.cn/gfdgd_xi/deep-wine-runner\nhttps://gfdgd-xi.github.io"
|
||||||
information = json.loads(readtxt(f"{programPath}/information.json"))
|
information = json.loads(readtxt(f"{programPath}/information.json"))
|
||||||
version = information["Version"]
|
version = information["Version"]
|
||||||
@ -2123,23 +2190,13 @@ exe路径\' 参数 \'
|
|||||||
<b>千万不要中断后不删除源的情况下 apt upgrade !!!</b>中断后只需重新打开脚本输入 repair 或者随意安装一个 Wine(会自动执行恢复操作)即可
|
<b>千万不要中断后不删除源的情况下 apt upgrade !!!</b>中断后只需重新打开脚本输入 repair 或者随意安装一个 Wine(会自动执行恢复操作)即可
|
||||||
以及此脚本安装的 Wine 无法保证 100% 能使用,以及副作用是会提示;
|
以及此脚本安装的 Wine 无法保证 100% 能使用,以及副作用是会提示;
|
||||||
<code>N: 鉴于仓库 'https://community-packages.deepin.com/beige beige InRelease' 不支持 'i386' 体系结构,跳过配置文件 'main/binary-i386/Packages' 的获取。</code>'''
|
<code>N: 鉴于仓库 'https://community-packages.deepin.com/beige beige InRelease' 不支持 'i386' 体系结构,跳过配置文件 'main/binary-i386/Packages' 的获取。</code>'''
|
||||||
updateThingsString = '''※1、容器自动配置脚本 GUI 查看介绍使用 QWebEngineWidget,支持图片(非强制依赖,只做推荐);
|
updateThingsString = '''※1、支持使用 Qemu + Chroot 跨运行 Wine 以及指定程序的功能;
|
||||||
※2、不基于生态适配活动脚本打包器跟进 arm 架构 2022年11月11日的 Wine 微信打包方式;
|
※2、提供了简易打包器以用于打包简易 deb;
|
||||||
※3、支持多图标的程序打包;
|
※3、支持下载配置过的 Qemu + Chroot 容器;
|
||||||
※4、修复了安装更多 Wine 换源换了个寂寞的问题;
|
|
||||||
※5、修复安装更多 Wine 重新安装后列表丢失的问题;
|
|
||||||
※6、新增了对 Deepin 23 Alpha 优化的 Wine 安装器;
|
|
||||||
※7、新增 Dll 名称查询功能,可以查询对应 Dll 的作用;
|
|
||||||
※8、支持静态获取可执行文件可以调用的 Dll 并提供解决方案;
|
|
||||||
※9、支持移除指定的 .desktop 快捷方式;
|
|
||||||
※10、新增日志分析功能以及导出、上传日志功能;
|
|
||||||
11、修复了不基于生态适配活动脚本打包器在选择 arm 打包架构下容器自动删除脚本取消勾选无用的问题;
|
|
||||||
12、优化文案、新增友链;
|
|
||||||
13、提供了部分组件的测试功能。
|
|
||||||
'''
|
'''
|
||||||
for i in information["Thank"]:
|
for i in information["Thank"]:
|
||||||
thankText += f"{i}\n"
|
thankText += f"{i}\n"
|
||||||
updateTime = "2022年11月25日"
|
updateTime = "2022年12月03日"
|
||||||
about = f'''<style>
|
about = f'''<style>
|
||||||
a:link, a:active {{
|
a:link, a:active {{
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
@ -2148,7 +2205,6 @@ a:link, a:active {{
|
|||||||
<h1>关于</h1>
|
<h1>关于</h1>
|
||||||
<p>Wine运行器是一个能让Linux用户更加方便地运行Windows应用的程序,内置了对Wine图形化的支持、各种Wine工具、自制的Wine程序打包器和运行库安装工具等。</p>
|
<p>Wine运行器是一个能让Linux用户更加方便地运行Windows应用的程序,内置了对Wine图形化的支持、各种Wine工具、自制的Wine程序打包器和运行库安装工具等。</p>
|
||||||
<p>它同时还内置了基于VirtualBox制作的、专供小白使用的Windows虚拟机安装工具,可以做到只需下载系统镜像并点击安装即可,无需考虑虚拟机的安装、创建、分区等操作。</p>
|
<p>它同时还内置了基于VirtualBox制作的、专供小白使用的Windows虚拟机安装工具,可以做到只需下载系统镜像并点击安装即可,无需考虑虚拟机的安装、创建、分区等操作。</p>
|
||||||
<p>本程序依照 GPLV3 协议开源</p>
|
|
||||||
<pre>
|
<pre>
|
||||||
|
|
||||||
一个图形化了如下命令的程序(最简单格式)
|
一个图形化了如下命令的程序(最简单格式)
|
||||||
@ -2159,9 +2215,10 @@ a:link, a:active {{
|
|||||||
适用平台:{goodRunSystem}(@VersionForType@)
|
适用平台:{goodRunSystem}(@VersionForType@)
|
||||||
Qt 版本:{QtCore.qVersion()}
|
Qt 版本:{QtCore.qVersion()}
|
||||||
程序官网:{programUrl}
|
程序官网:{programUrl}
|
||||||
程序占用体积:@programSize@MB</pre>
|
当前程序占用体积:@programSize@MB</pre>
|
||||||
|
<p>本程序依照 GPLV3 协议开源</p>
|
||||||
<hr>
|
<hr>
|
||||||
<h1>谢明名单</h1>
|
<h1>鸣谢名单</h1>
|
||||||
<pre>{thankText}</pre>
|
<pre>{thankText}</pre>
|
||||||
<hr>
|
<hr>
|
||||||
<h1>更新内容</h1>
|
<h1>更新内容</h1>
|
||||||
@ -2186,33 +2243,8 @@ try:
|
|||||||
threading.Thread(target=requests.get, args=[parse.unquote(base64.b64decode("aHR0cDovLzEyMC4yNS4xNTMuMTQ0L3NwYXJrLWRlZXBpbi13aW5lLXJ1bm5lci9vcGVuL0luc3RhbGwucGhw").decode("utf-8")) + "?Version=" + version]).start()
|
threading.Thread(target=requests.get, args=[parse.unquote(base64.b64decode("aHR0cDovLzEyMC4yNS4xNTMuMTQ0L3NwYXJrLWRlZXBpbi13aW5lLXJ1bm5lci9vcGVuL0luc3RhbGwucGhw").decode("utf-8")) + "?Version=" + version]).start()
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
iconListUnBuild = [
|
iconListUnBuild = json.loads(readtxt(f"{programPath}/IconList.json"))[0]
|
||||||
["QQ", "wineBottonPath/drive_c/Program Files/Tencent/QQ/Bin/QQ.exe"],
|
iconList = json.loads(readtxt(f"{programPath}/IconList.json"))[1]
|
||||||
["QQ", "wineBottonPath/drive_c/Program Files (x86)/Tencent/QQ/Bin/QQ.exe"],
|
|
||||||
["TIM", "wineBottonPath/drive_c/Program Files/Tencent/TIM/Bin/TIM.exe"],
|
|
||||||
["TIM", "wineBottonPath/drive_c/Program Files (x86)/Tencent/TIM/Bin/TIM.exe"]
|
|
||||||
]
|
|
||||||
iconList = [
|
|
||||||
["cmd", "cmd"],
|
|
||||||
["cmd", "cmd.exe"],
|
|
||||||
["cmd", "wineBottonPath/drive_c/windows/system32/cmd.exe"],
|
|
||||||
["Internet Explorer", "iexplore"],
|
|
||||||
["Internet Explorer", "iexplore.exe"],
|
|
||||||
["Internet Explorer", "wineBottonPath/drive_c/Program Files/Internet Explorer/iexplore.exe"],
|
|
||||||
["Internet Explorer", "wineBottonPath/drive_c/Program Files (x86)/Internet Explorer/iexplore.exe"],
|
|
||||||
["微信", "wineBottonPath/drive_c/Program Files/Tencent/WeChat/WeChat.exe"],
|
|
||||||
["微信", "wineBottonPath/drive_c/Program Files (x86)/Tencent/WeChat/WeChat.exe"],
|
|
||||||
["UltraISO", "wineBottonPath/drive_c/Program Files/UltraISO/UltraISO.exe"],
|
|
||||||
["UltraISO", "wineBottonPath/drive_c/Program Files (x86)/UltraISO/UltraISO.exe"],
|
|
||||||
["迅雷", "wineBottonPath/drive_c/Program Files/Thunder Network/MiniThunder/Bin/ThunderMini.exe"],
|
|
||||||
["迅雷", "wineBottonPath/drive_c/Program Files (x86)/Thunder Network/MiniThunder/Bin/ThunderMini.exe"],
|
|
||||||
["Microsoft Office Word", "wineBottonPath/drive_c/Program Files/Microsoft Office/Office12/WINWORD.EXE"],
|
|
||||||
["Microsoft Office Word", "wineBottonPath/drive_c/Program Files (x86)/Microsoft Office/Office12/WINWORD.EXE"],
|
|
||||||
["腾讯会议", "wineBottonPath/drive_c/Program Files/Tencent/WeMeet/wemeetapp.exe"],
|
|
||||||
["腾讯会议", "wineBottonPath/drive_c/Program Files (x86)/Tencent/WeMeet/wemeetapp.exe"],
|
|
||||||
["腾讯课堂", "wineBottonPath/drive_c/Program Files/Tencent/EDU/bin/TXEDU.exe"],
|
|
||||||
["腾讯课堂", "wineBottonPath/drive_c/Program Files (x86)/Tencent/EDU/bin/TXEDU.exe"]
|
|
||||||
]
|
|
||||||
for i in iconListUnBuild:
|
for i in iconListUnBuild:
|
||||||
iconList.append(i)
|
iconList.append(i)
|
||||||
print(iconList)
|
print(iconList)
|
||||||
@ -2387,6 +2419,7 @@ installWineOnDeepin23 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U",
|
|||||||
installWineOnDeepin23Alpha = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "安装 wine(只限Deepin23 Alpha)"))
|
installWineOnDeepin23Alpha = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "安装 wine(只限Deepin23 Alpha)"))
|
||||||
installWineHQ = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "安装 WineHQ"))
|
installWineHQ = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "安装 WineHQ"))
|
||||||
installMoreWine = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "安装更多 Wine"))
|
installMoreWine = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "安装更多 Wine"))
|
||||||
|
downloadChrootBottle = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "下载 Chroot 容器"))
|
||||||
p2 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "设置程序(&S)"))
|
p2 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "设置程序(&S)"))
|
||||||
p3 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "清空软件历史记录(&C)"))
|
p3 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "清空软件历史记录(&C)"))
|
||||||
cleanCache = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "清空软件缓存"))
|
cleanCache = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "清空软件缓存"))
|
||||||
@ -2397,6 +2430,7 @@ programmenu.addAction(installWineOnDeepin23)
|
|||||||
programmenu.addAction(installWineOnDeepin23Alpha)
|
programmenu.addAction(installWineOnDeepin23Alpha)
|
||||||
programmenu.addAction(installWineHQ)
|
programmenu.addAction(installWineHQ)
|
||||||
programmenu.addAction(installMoreWine)
|
programmenu.addAction(installMoreWine)
|
||||||
|
programmenu.addAction(downloadChrootBottle)
|
||||||
programmenu.addSeparator()
|
programmenu.addSeparator()
|
||||||
programmenu.addAction(p2)
|
programmenu.addAction(p2)
|
||||||
programmenu.addSeparator()
|
programmenu.addSeparator()
|
||||||
@ -2410,6 +2444,7 @@ installWineOnDeepin23.triggered.connect(InstallWineOnDeepin23)
|
|||||||
installWineOnDeepin23Alpha.triggered.connect(InstallWineOnDeepin23Alpha)
|
installWineOnDeepin23Alpha.triggered.connect(InstallWineOnDeepin23Alpha)
|
||||||
installWineHQ.triggered.connect(InstallWineHQ)
|
installWineHQ.triggered.connect(InstallWineHQ)
|
||||||
installMoreWine.triggered.connect(lambda: threading.Thread(target=os.system, args=[f"'{programPath}/wine/installwine'"]).start())
|
installMoreWine.triggered.connect(lambda: threading.Thread(target=os.system, args=[f"'{programPath}/wine/installwine'"]).start())
|
||||||
|
downloadChrootBottle.triggered.connect(lambda: threading.Thread(target=os.system, args=[f"'{programPath}/QemuDownload.py'"]).start())
|
||||||
p2.triggered.connect(ProgramSetting.ShowWindow)
|
p2.triggered.connect(ProgramSetting.ShowWindow)
|
||||||
p3.triggered.connect(CleanProgramHistory)
|
p3.triggered.connect(CleanProgramHistory)
|
||||||
cleanCache.triggered.connect(CleanProgramCache)
|
cleanCache.triggered.connect(CleanProgramCache)
|
||||||
@ -2424,7 +2459,8 @@ w4 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "删除选择的 W
|
|||||||
cleanBottonUOS = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "清理 Wine 容器(基于 Wine 适配活动脚本)"))
|
cleanBottonUOS = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "清理 Wine 容器(基于 Wine 适配活动脚本)"))
|
||||||
wineKeyboardLnk = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "Wine 快捷键映射"))
|
wineKeyboardLnk = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "Wine 快捷键映射"))
|
||||||
w5 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "打包 wine 应用"))
|
w5 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "打包 wine 应用"))
|
||||||
w6 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "使用官方 Wine 适配活动的脚本进行打包(小白建议使用这个)"))
|
w6 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "使用官方 Wine 适配活动的脚本进行打包"))
|
||||||
|
easyPackager = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "使用简易打包器进行打包(小白且无特殊需求建议使用这个)"))
|
||||||
getDllOnInternet = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "从互联网获取DLL"))
|
getDllOnInternet = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "从互联网获取DLL"))
|
||||||
w7 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "从镜像获取DLL(只支持官方安装镜像,DOS内核如 Windows 95 暂不支持)"))
|
w7 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "从镜像获取DLL(只支持官方安装镜像,DOS内核如 Windows 95 暂不支持)"))
|
||||||
updateGeek = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "从 Geek Uninstaller 官网升级程序"))
|
updateGeek = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "从 Geek Uninstaller 官网升级程序"))
|
||||||
@ -2438,6 +2474,7 @@ wineOption.addAction(cleanBottonUOS)
|
|||||||
wineOption.addSeparator()
|
wineOption.addSeparator()
|
||||||
wineOption.addAction(w5)
|
wineOption.addAction(w5)
|
||||||
wineOption.addAction(w6)
|
wineOption.addAction(w6)
|
||||||
|
wineOption.addAction(easyPackager)
|
||||||
wineOption.addSeparator()
|
wineOption.addSeparator()
|
||||||
wineOption.addAction(wineKeyboardLnk)
|
wineOption.addAction(wineKeyboardLnk)
|
||||||
wineOption.addSeparator()
|
wineOption.addSeparator()
|
||||||
@ -2542,6 +2579,7 @@ w4.triggered.connect(DeleteWineBotton)
|
|||||||
cleanBottonUOS.triggered.connect(CleanWineBottonByUOS)
|
cleanBottonUOS.triggered.connect(CleanWineBottonByUOS)
|
||||||
w5.triggered.connect(BuildExeDeb)
|
w5.triggered.connect(BuildExeDeb)
|
||||||
w6.triggered.connect(UOSPackageScript)
|
w6.triggered.connect(UOSPackageScript)
|
||||||
|
easyPackager.triggered.connect(lambda: threading.Thread(target=os.system, args=[f"'{programPath}/deepin-wine-easy-packager.py' '{e2.currentText()}'"]))
|
||||||
wineKeyboardLnk.triggered.connect(lambda: threading.Thread(target=os.system, args=[f"'{programPath}/key/key-add-gui.py'"]).start())
|
wineKeyboardLnk.triggered.connect(lambda: threading.Thread(target=os.system, args=[f"'{programPath}/key/key-add-gui.py'"]).start())
|
||||||
getDllOnInternet.triggered.connect(GetDllFromInternet)
|
getDllOnInternet.triggered.connect(GetDllFromInternet)
|
||||||
w7.triggered.connect(GetDllFromWindowsISO.ShowWindow)
|
w7.triggered.connect(GetDllFromWindowsISO.ShowWindow)
|
||||||
@ -2632,10 +2670,18 @@ log.addAction(checkLogText)
|
|||||||
log.addAction(saveLogText)
|
log.addAction(saveLogText)
|
||||||
log.addAction(uploadLogText)
|
log.addAction(uploadLogText)
|
||||||
|
|
||||||
|
if len(qemuBottleList) >= 1:
|
||||||
|
qemuMenu = menu.addMenu(QtCore.QCoreApplication.translate("U", "配置Chroot容器(&C)"))
|
||||||
|
configMenu = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "配置指定容器"))
|
||||||
|
qemuMenu.addAction(configMenu)
|
||||||
|
configMenu.triggered.connect(ConfigQemu)
|
||||||
|
print(qemuBottleList)
|
||||||
|
|
||||||
help = menu.addMenu(QtCore.QCoreApplication.translate("U", "帮助(&H)"))
|
help = menu.addMenu(QtCore.QCoreApplication.translate("U", "帮助(&H)"))
|
||||||
runStatusWebSize = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "查询程序在 Wine 的运行情况"))
|
runStatusWebSize = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "查询程序在 Wine 的运行情况"))
|
||||||
h1 = help.addMenu(QtCore.QCoreApplication.translate("U", "程序官网"))
|
h1 = help.addMenu(QtCore.QCoreApplication.translate("U", "程序官网"))
|
||||||
h2 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "小提示"))
|
h2 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "小提示"))
|
||||||
|
wineRunnerHelp = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "Wine运行器和Wine打包器傻瓜式使用教程(小白专用) By 鹤舞白沙"))
|
||||||
h3 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "更新内容"))
|
h3 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "更新内容"))
|
||||||
h4 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "谢明名单"))
|
h4 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "谢明名单"))
|
||||||
h5 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "更新这个程序"))
|
h5 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "更新这个程序"))
|
||||||
@ -2643,6 +2689,7 @@ h6 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "反馈这个程
|
|||||||
h7 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "关于这个程序"))
|
h7 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "关于这个程序"))
|
||||||
h8 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "关于 Qt"))
|
h8 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "关于 Qt"))
|
||||||
gfdgdxiio = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "作者个人站"))
|
gfdgdxiio = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "作者个人站"))
|
||||||
|
forumWebsize = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "程序论坛"))
|
||||||
gitee = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "Gitee"))
|
gitee = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "Gitee"))
|
||||||
github = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "Github"))
|
github = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "Github"))
|
||||||
gitlink = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "Gitlink"))
|
gitlink = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "Gitlink"))
|
||||||
@ -2655,6 +2702,8 @@ h1.addAction(gitlink)
|
|||||||
h1.addAction(gitlab)
|
h1.addAction(gitlab)
|
||||||
h1.addAction(jihu)
|
h1.addAction(jihu)
|
||||||
help.addSeparator()
|
help.addSeparator()
|
||||||
|
help.addAction(forumWebsize)
|
||||||
|
help.addAction(wineRunnerHelp)
|
||||||
help.addAction(runStatusWebSize)
|
help.addAction(runStatusWebSize)
|
||||||
help.addSeparator()
|
help.addSeparator()
|
||||||
help.addAction(h2)
|
help.addAction(h2)
|
||||||
@ -2684,8 +2733,10 @@ gitlink.triggered.connect(lambda: webbrowser.open_new_tab("https://gitlink.org.c
|
|||||||
gitlab.triggered.connect(lambda: webbrowser.open_new_tab("https://gitlab.com/gfdgd-xi/deep-wine-runner"))
|
gitlab.triggered.connect(lambda: webbrowser.open_new_tab("https://gitlab.com/gfdgd-xi/deep-wine-runner"))
|
||||||
jihu.triggered.connect(lambda: webbrowser.open_new_tab("https://jihulab.com//gfdgd-xi/deep-wine-runner"))
|
jihu.triggered.connect(lambda: webbrowser.open_new_tab("https://jihulab.com//gfdgd-xi/deep-wine-runner"))
|
||||||
runStatusWebSize.triggered.connect(lambda: webbrowser.open_new_tab("https://gfdgd-xi.github.io/wine-runner-info"))
|
runStatusWebSize.triggered.connect(lambda: webbrowser.open_new_tab("https://gfdgd-xi.github.io/wine-runner-info"))
|
||||||
|
forumWebsize.triggered.connect(lambda: webbrowser.open_new_tab("https://gfdgdxi.flarum.cloud/"))
|
||||||
h2.triggered.connect(helps)
|
h2.triggered.connect(helps)
|
||||||
h3.triggered.connect(UpdateThings)
|
h3.triggered.connect(UpdateThings)
|
||||||
|
wineRunnerHelp.triggered.connect(lambda: webbrowser.open_new_tab("https://bbs.deepin.org/post/246837"))
|
||||||
h4.triggered.connect(ThankWindow)
|
h4.triggered.connect(ThankWindow)
|
||||||
wikiHelp.triggered.connect(lambda: webbrowser.open_new_tab("https://gfdgd-xi.github.io/wine-runner-wiki"))
|
wikiHelp.triggered.connect(lambda: webbrowser.open_new_tab("https://gfdgd-xi.github.io/wine-runner-wiki"))
|
||||||
easyHelp.triggered.connect(lambda: webbrowser.open_new_tab("https://www.bilibili.com/video/BV1ma411972Y"))
|
easyHelp.triggered.connect(lambda: webbrowser.open_new_tab("https://www.bilibili.com/video/BV1ma411972Y"))
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
{
|
{
|
||||||
"Version": "2.5.0",
|
"Version": "2.5.0",
|
||||||
"Thank": [
|
"Thank": [
|
||||||
|
"感谢 @鹤舞白沙 对程序文案进行优化以及编写《Wine运行器和Wine打包器傻瓜式使用教程(小白专用) 》",
|
||||||
|
"感谢 @璀璨星空 提供的彩蛋图标",
|
||||||
|
"感谢 @鹤舞白沙 专门为小白用户编写的使用 Wine 运行器非基于生态适配脚本的程序打包教程",
|
||||||
"感谢 @牦牛儿苗 进行了龙芯 3a5000 平台的测试与移植",
|
"感谢 @牦牛儿苗 进行了龙芯 3a5000 平台的测试与移植",
|
||||||
"感谢 @雁舞白沙 优化了程序文案",
|
"感谢 @雁舞白沙 优化了程序文案",
|
||||||
"感谢 @豪 的程序测试和制作的非官方论坛 https://gfdgdxi.flarum.cloud/",
|
"感谢 @豪 的程序测试和制作的论坛 https://gfdgdxi.flarum.cloud/",
|
||||||
"感谢 @185******67 反馈的 2.4.0 无法打开 Visual Basic 组件安装工具的问题",
|
"感谢 @185******67 反馈的 2.4.0 无法打开 Visual Basic 组件安装工具的问题",
|
||||||
"感谢 @shenmo 提供的 在打包器的 postrm 脚本添加 kill.sh、追加参数改为 --uri xxxxxxx、独立生成容器 7z 文件的功能",
|
"感谢 @shenmo 提供的 在打包器的 postrm 脚本添加 kill.sh、追加参数改为 --uri xxxxxxx、独立生成容器 7z 文件的功能",
|
||||||
"感谢 @a2035274 @虚幻的早晨 https://bbs.deepin.org/post/238301",
|
"感谢 @a2035274 @虚幻的早晨 https://bbs.deepin.org/post/238301",
|
||||||
|
Binary file not shown.
Binary file not shown.
BIN
deb/opt/apps/deepin-wine-runner/wrestool
Executable file
BIN
deb/opt/apps/deepin-wine-runner/wrestool
Executable file
Binary file not shown.
0
dlls-arm.7z
Executable file → Normal file
0
dlls-arm.7z
Executable file → Normal file
Binary file not shown.
@ -7,32 +7,21 @@ with open("/var/lib/dpkg/status", "r") as i:
|
|||||||
if unConnect:
|
if unConnect:
|
||||||
print("52专版,将会无法连接服务器")
|
print("52专版,将会无法连接服务器")
|
||||||
|
|
||||||
badUrl = [
|
|
||||||
"http://120.25.153.144",
|
|
||||||
"https://304626p927.goho.co",
|
|
||||||
"https://30x46269h2.goho.co",
|
|
||||||
"http://gfdgdxi.msns.cn"
|
|
||||||
]
|
|
||||||
|
|
||||||
class Respon:
|
class Respon:
|
||||||
text = ""
|
text = ""
|
||||||
|
|
||||||
def get(url, timeout=None): # -> requests.Response:
|
def get(url, timeout=None): # -> requests.Response:
|
||||||
if unConnect:
|
if unConnect:
|
||||||
# 筛选 Url,只有特定的 url 才会被拦截
|
# 全部 Url 都拦截
|
||||||
for i in badUrl:
|
raise Exception("52专版不支持连接服务器")
|
||||||
if i in url:
|
|
||||||
raise Exception("52专版不支持连接作者服务器")
|
|
||||||
if timeout == None:
|
if timeout == None:
|
||||||
return requests.get(url)
|
return requests.get(url)
|
||||||
return requests.get(url, timeout=timeout)
|
return requests.get(url, timeout=timeout)
|
||||||
|
|
||||||
def post(url, data, timeout=None):
|
def post(url, data, timeout=None):
|
||||||
if unConnect:
|
if unConnect:
|
||||||
# 筛选 Url,只有特定的 url 才会被拦截
|
# 全部 Url 都拦截
|
||||||
for i in badUrl:
|
raise Exception("52专版不支持连接服务器")
|
||||||
if i in url:
|
|
||||||
raise Exception("52专版不支持连接作者服务器")
|
|
||||||
if timeout == None:
|
if timeout == None:
|
||||||
return requests.post(url, data)
|
return requests.post(url, data)
|
||||||
return requests.post(url, data, timeout=timeout)
|
return requests.post(url, data, timeout=timeout)
|
BIN
req/__pycache__/__init__.cpython-310.pyc
Normal file
BIN
req/__pycache__/__init__.cpython-310.pyc
Normal file
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user