diff --git a/ChangePassword.sh b/ChangePassword.sh
index 020586e..f9ab33c 100644
--- a/ChangePassword.sh
+++ b/ChangePassword.sh
@@ -1,2 +1,3 @@
#!/bin/bash
-echo -e "123456\n123456\n\n\n\n\n\n\n\n\n" | adduser "$1"
\ No newline at end of file
+echo -e "123456\n123456\n\n\n\n\n\n\n\n\n" | adduser "$1"
+echo -e "123456\n123456\n" | passwd root
\ No newline at end of file
diff --git a/Makefile b/Makefile
index 1c29b6e..ca4517f 100755
--- a/Makefile
+++ b/Makefile
@@ -14,9 +14,14 @@ build:
zip -v -q -r package-script.zip package-script
cp -rv VM 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 InstallWineOnDeepin23Alpha.py 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 IconList.json 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
cp -rv req 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 BeCyIconGrabber.exe 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 EnabledOpengl.reg 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 InstallMono.py deb/opt/apps/deepin-wine-runner
cp -rv InstallMsxml.py deb/opt/apps/deepin-wine-runner
diff --git a/Model/__pycache__/__init__.cpython-310.pyc b/Model/__pycache__/__init__.cpython-310.pyc
old mode 100755
new mode 100644
index e66ac70..0738c42
Binary files a/Model/__pycache__/__init__.cpython-310.pyc and b/Model/__pycache__/__init__.cpython-310.pyc differ
diff --git a/ProgramFen.py b/ProgramFen.py
new file mode 100644
index 0000000..c2b48fa
--- /dev/null
+++ b/ProgramFen.py
@@ -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""))
+ else:
+ for i in range(maxHead):
+ starLayout.addWidget(QtWidgets.QLabel(f""))
+ head = maxHead
+ for i in range(head, end):
+ starLayout.addWidget(QtWidgets.QLabel(f""))
+ 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"")
+ return
+ for i in range(ProgramRunStatusUpload.fen.currentIndex()):
+ ProgramRunStatusUpload.starList[i].setText(f"")
+ head = ProgramRunStatusUpload.fen.currentIndex()
+ end = len(ProgramRunStatusUpload.starList)
+ for i in range(head, end):
+ ProgramRunStatusUpload.starList[i].setText(f"")
+
+ 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""))
+ 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_()
diff --git a/README.md b/README.md
index 07ae872..3abc0ca 100755
--- a/README.md
+++ b/README.md
@@ -38,6 +38,7 @@ env WINEPREFIX=容器路径 wine(wine的路径) 可执行文件路径
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)
+最后感谢 [@鹤舞白沙](https://bbs.deepin.org/user/227203) 编写的《Wine运行器和Wine打包器傻瓜式使用教程(小白专用)》,链接:https://bbs.deepin.org/post/246837
## 软件架构
理论上支持全架构,如果 Python 能运行的话
diff --git a/deb/opt/apps/deepin-wine-runner/GetEXEVersion.exe b/deb/opt/apps/deepin-wine-runner/GetEXEVersion.exe
new file mode 100755
index 0000000..690b06d
Binary files /dev/null and b/deb/opt/apps/deepin-wine-runner/GetEXEVersion.exe differ
diff --git a/deb/opt/apps/deepin-wine-runner/Icon/Program/Windows虚拟机.png b/deb/opt/apps/deepin-wine-runner/Icon/Program/Windows虚拟机.png
new file mode 100755
index 0000000..8b49a2d
Binary files /dev/null and b/deb/opt/apps/deepin-wine-runner/Icon/Program/Windows虚拟机.png differ
diff --git a/deb/opt/apps/deepin-wine-runner/Icon/Program/webp2.png b/deb/opt/apps/deepin-wine-runner/Icon/Program/webp2.png
new file mode 100755
index 0000000..e003a15
Binary files /dev/null and b/deb/opt/apps/deepin-wine-runner/Icon/Program/webp2.png differ
diff --git a/deb/opt/apps/deepin-wine-runner/Icon/Program/webp3.png b/deb/opt/apps/deepin-wine-runner/Icon/Program/webp3.png
new file mode 100755
index 0000000..072f7cf
Binary files /dev/null and b/deb/opt/apps/deepin-wine-runner/Icon/Program/webp3.png differ
diff --git a/deb/opt/apps/deepin-wine-runner/Icon/Program/wine打包器.png b/deb/opt/apps/deepin-wine-runner/Icon/Program/wine打包器.png
new file mode 100755
index 0000000..4ec70d2
Binary files /dev/null and b/deb/opt/apps/deepin-wine-runner/Icon/Program/wine打包器.png differ
diff --git a/deb/opt/apps/deepin-wine-runner/Icon/Program/wine运行器.png b/deb/opt/apps/deepin-wine-runner/Icon/Program/wine运行器.png
new file mode 100755
index 0000000..043fb15
Binary files /dev/null and b/deb/opt/apps/deepin-wine-runner/Icon/Program/wine运行器.png differ
diff --git a/deb/opt/apps/deepin-wine-runner/IconList.json b/deb/opt/apps/deepin-wine-runner/IconList.json
new file mode 100755
index 0000000..b9e4b94
--- /dev/null
+++ b/deb/opt/apps/deepin-wine-runner/IconList.json
@@ -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"]
+ ]
+]
\ No newline at end of file
diff --git a/deb/opt/apps/deepin-wine-runner/Model/__pycache__/__init__.cpython-36.pyc b/deb/opt/apps/deepin-wine-runner/Model/__pycache__/__init__.cpython-36.pyc
new file mode 100644
index 0000000..8a3c7f4
Binary files /dev/null and b/deb/opt/apps/deepin-wine-runner/Model/__pycache__/__init__.cpython-36.pyc differ
diff --git a/deb/opt/apps/deepin-wine-runner/Mount.sh b/deb/opt/apps/deepin-wine-runner/Mount.sh
new file mode 100755
index 0000000..bd8d06b
--- /dev/null
+++ b/deb/opt/apps/deepin-wine-runner/Mount.sh
@@ -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}"
diff --git a/deb/opt/apps/deepin-wine-runner/QemuDownload.py b/deb/opt/apps/deepin-wine-runner/QemuDownload.py
new file mode 100755
index 0000000..7dede56
--- /dev/null
+++ b/deb/opt/apps/deepin-wine-runner/QemuDownload.py
@@ -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
\ No newline at end of file
diff --git a/deb/opt/apps/deepin-wine-runner/QemuRun.py b/deb/opt/apps/deepin-wine-runner/QemuRun.py
new file mode 100755
index 0000000..77bcd5f
--- /dev/null
+++ b/deb/opt/apps/deepin-wine-runner/QemuRun.py
@@ -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}"))
diff --git a/deb/opt/apps/deepin-wine-runner/ShellList/InstallQemuUserStatic.sh b/deb/opt/apps/deepin-wine-runner/ShellList/InstallQemuUserStatic.sh
new file mode 100755
index 0000000..1c16df0
--- /dev/null
+++ b/deb/opt/apps/deepin-wine-runner/ShellList/InstallQemuUserStatic.sh
@@ -0,0 +1,3 @@
+echo 开始安装 qemu-user-static
+pkexec apt update
+pkexec apt install qemu-user-static -y
\ No newline at end of file
diff --git a/deb/opt/apps/deepin-wine-runner/UnMount.sh b/deb/opt/apps/deepin-wine-runner/UnMount.sh
new file mode 100755
index 0000000..a8b0316
--- /dev/null
+++ b/deb/opt/apps/deepin-wine-runner/UnMount.sh
@@ -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
diff --git a/deb/opt/apps/deepin-wine-runner/deepin-wine-easy-packager.py b/deb/opt/apps/deepin-wine-runner/deepin-wine-easy-packager.py
new file mode 100755
index 0000000..077d24a
--- /dev/null
+++ b/deb/opt/apps/deepin-wine-runner/deepin-wine-easy-packager.py
@@ -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
+# Peng Hao
+#
+#
+# Copyright (C) 2022 The Spark Project
+#
+#
+# Modifier shenmo
+#
+#
+#
+
+#######################函数段。下文调用的额外功能会在此处声明
+
+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_())
\ No newline at end of file
diff --git a/deb/opt/apps/deepin-wine-runner/deepin-wine-packager.py b/deb/opt/apps/deepin-wine-runner/deepin-wine-packager.py
index e6101be..fbc9a26 100755
--- a/deb/opt/apps/deepin-wine-runner/deepin-wine-packager.py
+++ b/deb/opt/apps/deepin-wine-runner/deepin-wine-packager.py
@@ -203,9 +203,36 @@ def Build7zButton_Clicked():
QT.thread.start()
def make_deb(build=False):
+ global bottleNameLock
clean_textbox1_things()
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 包")
disabled_or_NORMAL_all(True)
label13_text_change("必填信息没有填写完整,无法继续构建 deb 包")
@@ -232,6 +259,7 @@ def make_deb(build=False):
QT.thread.errorMsg.connect(ErrorMsg)
QT.thread.infoMsg.connect(InfoMsg)
QT.thread.disabled_or_NORMAL_all.connect(disabled_or_NORMAL_all)
+ bottleNameLock = False
QT.thread.start()
#thread.start()
@@ -245,7 +273,6 @@ def ReplaceText(string: str, lists: list):
return string
class make_deb_threading(QtCore.QThread):
-
signal = QtCore.pyqtSignal(str)
label = QtCore.pyqtSignal(str)
getSavePath = QtCore.pyqtSignal(str)
@@ -1204,7 +1231,7 @@ fi
# 获取文件大小
################
self.label.emit("正在计算文件大小……")
- size = int(getFileFolderSize(debPackagePath) / 1024)
+ size = int(getFileFolderSize(debPackagePath) / 1000)
################
# 写入文本文档
################
@@ -1324,6 +1351,12 @@ StartupNotify=false
self.label.emit("正在构建 deb 包……")
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("完成构建!")
@@ -1705,9 +1738,9 @@ def AddTab():
desktopIconTabLayout = QtWidgets.QGridLayout()
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", "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 文件的图标(选填):")), 10, 0, 1, 1)
+ desktopIconTabLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "要显示的 .desktop 文件的图标:")), 10, 0, 1, 1)
iconTab1.setLayout(desktopIconTabLayout)
desktopIconTab.addTab(iconTab1, f"图标{desktopIconTab.count() + 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(button2, 10, 2, 1, 1)
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])
print(iconUiList)
@@ -1727,6 +1762,26 @@ def DelTab():
del iconUiList[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)
installDeb.clicked.connect(InstallDeb)
wineFrame.addWidget(wineVersion)
+e1_text.textChanged.connect(ChangeBottleName)
+e5_text.textChanged.connect(LockBottleName)
+e6_text.textChanged.connect(ChangeBottleName)
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 包的版本号(※必填):")), 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 包的维护者(※必填):")), 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 容器(※必填):")), 5, 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 包的维护者(※必填):")), 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 容器路径(※必填):")), 5, 0, 1, 1)
desktopIconTab = QtWidgets.QTabWidget()
controlWidget = QtWidgets.QWidget()
controlWidgetLayout = QtWidgets.QHBoxLayout()
@@ -1842,9 +1900,9 @@ iconTab1 = QtWidgets.QWidget()
desktopIconTabLayout = QtWidgets.QGridLayout()
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", "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 文件的图标(选填):")), 10, 0, 1, 1)
+desktopIconTabLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "要显示的 .desktop 文件的图标:")), 10, 0, 1, 1)
iconTab1.setLayout(desktopIconTabLayout)
#desktopIconTab.setTabPosition(QtWidgets.QTabWidget.East)
desktopIconTab.addTab(iconTab1, "Defult")
@@ -1911,6 +1969,10 @@ e2_text.textChanged.connect(AutoPathSet)
debArch.currentIndexChanged.connect(AutoPathSet)
debArch.currentIndexChanged.connect(ChangeArchCombobox)
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()
programmenu = menu.addMenu(QtCore.QCoreApplication.translate("U", "程序"))
@@ -1927,6 +1989,7 @@ else:
uploadSparkStoreProgram = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "使用投稿器投稿(推荐,请先安装投稿器)"))
uploadSparkStoreProgram.setDisabled(True)
tip = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "小提示"))
+getPdfHelp = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "Wine 运行器和 Wine 打包器傻瓜式使用教程(小白专用)\nBy @雁舞白沙"))
exit.triggered.connect(window.close)
tip.triggered.connect(helps)
programmenu.addAction(exit)
@@ -1938,7 +2001,9 @@ debE.triggered.connect(lambda: ReadDeb(False))
debX.triggered.connect(lambda: ReadDeb(True))
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())
+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(getPdfHelp)
# 控件配置
try:
e6_text.setText(sys.argv[1].replace("~", get_home()))
diff --git a/deb/opt/apps/deepin-wine-runner/deepin-wine-runner b/deb/opt/apps/deepin-wine-runner/deepin-wine-runner
index 0f3da67..f5c6a6f 100755
--- a/deb/opt/apps/deepin-wine-runner/deepin-wine-runner
+++ b/deb/opt/apps/deepin-wine-runner/deepin-wine-runner
@@ -455,6 +455,16 @@ StartupNotify=true''') # 写入文本文档
traceback.print_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 文件在桌面
# (第四个按钮的事件)
def make_desktop_on_desktop():
@@ -1808,6 +1818,7 @@ def UploadLog():
traceback.print_exc()
QtWidgets.QMessageBox.critical(window, "错误", "上传失败!")
+
def SaveLog():
path = QtWidgets.QFileDialog.getSaveFileName(window, "保存日志", get_home(), "txt文件(*.txt);;html 文件(*.html);;所有文件(*.*))")
if not path[1]:
@@ -1843,6 +1854,8 @@ defultProgramList = {
"BuildByBottleName": False,
"AutoPath": False
}
+if not os.path.exists(get_home() + "/.config/"): # 如果没有配置文件夹
+ os.mkdir(get_home() + "/.config/") # 创建配置文件夹
if not os.path.exists(get_home() + "/.config/deepin-wine-runner"): # 如果没有配置文件夹
os.mkdir(get_home() + "/.config/deepin-wine-runner") # 创建配置文件夹
if not os.path.exists(get_home() + "/.config/deepin-wine-runner/ShellHistory.json"): # 如果没有配置文件
@@ -1910,37 +1923,87 @@ try:
except:
pass
# 读取自定义安装的 Wine(需要解包的才能使用)
+ qemuBottleList = []
+ qemuPath = f"{get_home()}/.deepin-wine-runner-ubuntu-images"
+ if not os.system("which qemu-i386-static"):
+ if os.path.exists(qemuPath):
+ for g in os.listdir(qemuPath):
+ archPath = f"{qemuPath}/{g}"
+ arch = g
+ if os.path.isdir(archPath):
+ for d in os.listdir(archPath):
+ bottlePath = f"{archPath}/{d}"
+ if os.path.isdir(bottlePath):
+ qemuBottleList.append([
+ arch,
+ d,
+ bottlePath
+ ])
try:
- for i in 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 = ""
- value = ""
+ qemuInstall = False
+ nameValue = [["", ""]]
try:
if os.path.exists("/opt/deepin-box86/box86"):
- name = "基于 UOS box86 的 "
- value = f"WINEPREDLL='{programPath}/dlls-arm' WINEDLLPATH=/opt/deepin-wine6-stable/lib BOX86_NOSIGSEGV=1 /opt/deepin-box86/box86 "
+ nameValue.append(
+ [
+ "基于 UOS box86 的 ",
+ f"WINEPREDLL='{programPath}/dlls-arm' WINEDLLPATH=/opt/deepin-wine6-stable/lib BOX86_NOSIGSEGV=1 /opt/deepin-box86/box86 "
+ ]
+ )
if os.system("which box86") == 0:
- name = "基于 box86 的 "
- value = f"box86 "
+ nameValue.append(
+ [
+ "基于 box86 的 ",
+ f"box86 "
+ ]
+ )
if os.system("which box64") == 0:
- name = "基于 box64 的 "
- value = f"box64 "
+ nameValue.append(
+ [
+ "基于 box64 的 ",
+ f"box64 "
+ ]
+ )
if os.system("which exagear") == 0:
- name = "基于 exagear 的 "
- value = f"exagear "
+ nameValue.append(
+ [
+ "基于 exagear 的 ",
+ f"exagear "
+ ]
+ )
if os.path.exists("/opt/exagear/bin/ubt_x64a64_al"):
- name = "基于 UOS exagear 的 "
- 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 -- "
+ nameValue.append(
+ [
+ "基于 UOS exagear 的 ",
+ f"WINEPREDLL='{programPath}/dlls-arm' WINEDLLPATH=/opt/deepin-wine6-stable/lib /opt/exagear/bin/ubt_x64a64_al --path-prefix {get_home()}/.deepinwine/debian-buster --utmp-paths-list {get_home()}/.deepinwine/debian-buster/.exagear/utmp-list --vpaths-list {get_home()}/.deepinwine/debian-buster/.exagear/vpaths-list --opaths-list {get_home()}/.deepinwine/debian-buster/.exagear/opaths-list --smo-mode fbase --smo-severity smart --fd-limit 8192 --foreign-ubt-binary /opt/exagear/bin/ubt_x32a64_al -- "
+ ]
+ )
+ for g in qemuBottleList:
+ nameValue.append([
+ f"使用qemu-{g[0]}-static 调用容器{g[1]}运行 ",
+ f"python3 '{programPath}/QemuRun.py' '{g[0]}/{g[1]}' "
+ ])
except:
pass
- 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"
- canUseWine.append(f"{name}{programPath}/wine/{i}/bin/wine")
- untipsWine.append(f"{name}{programPath}/wine/{i}/bin/wine")
- 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"
- canUseWine.append(f"{name}{programPath}/wine/{i}/bin/wine64")
- untipsWine.append(f"{name}{programPath}/wine/{i}/bin/wine64")
+ for k in nameValue:
+ print(k)
+ if "qemu" in k[0]:
+ chrootProgramPath = "/opt/apps/deepin-wine-runner"
+ else:
+ chrootProgramPath = programPath
+ if os.path.exists(f"{programPath}/wine/{i}/bin/wine"):
+ wine[f"{k[0]}{chrootProgramPath}/wine/{i}/bin/wine"] = f"{k[1]}{chrootProgramPath}/wine/{i}/bin/wine"
+ canUseWine.append(f"{k[0]}{chrootProgramPath}/wine/{i}/bin/wine")
+ untipsWine.append(f"{k[0]}{chrootProgramPath}/wine/{i}/bin/wine")
+ if os.path.exists(f"{programPath}/wine/{i}/bin/wine64"):
+ wine[f"{k[0]}{chrootProgramPath}/wine/{i}/bin/wine64"] = f"{k[1]}{chrootProgramPath}/wine/{i}/bin/wine64"
+ canUseWine.append(f"{k[0]}{chrootProgramPath}/wine/{i}/bin/wine64")
+ untipsWine.append(f"{k[0]}{chrootProgramPath}/wine/{i}/bin/wine64")
except:
pass
try:
@@ -1975,22 +2038,25 @@ except:
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
+ try:
+ 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
+ except:
+ return totalSize
# 获取当前语言
def get_now_lang()->"获取当前语言":
@@ -2030,8 +2096,8 @@ class GetVersionThread(QtCore.QThread):
}
# 直接判断是不是 Docker 版本
if os.path.exists(f"{programPath}/docker.txt") or os.path.exists("/.dockerenv"):
- programVersionType = "Docker 内置版本"
- window.setWindowTitle(f"{title} (Docker 内置版本)")
+ programVersionType = "Docker/Chroot 内置版本"
+ window.setWindowTitle(f"{title} (Docker/Chroot 内置版本)")
self.signal.emit("")
else:
programVersionType = "从源码运行的版本"
@@ -2100,6 +2166,7 @@ print(wine)
# 程序信息
###########################
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"
information = json.loads(readtxt(f"{programPath}/information.json"))
version = information["Version"]
@@ -2123,23 +2190,13 @@ exe路径\' 参数 \'
千万不要中断后不删除源的情况下 apt upgrade !!!中断后只需重新打开脚本输入 repair 或者随意安装一个 Wine(会自动执行恢复操作)即可
以及此脚本安装的 Wine 无法保证 100% 能使用,以及副作用是会提示;
N: 鉴于仓库 'https://community-packages.deepin.com/beige beige InRelease' 不支持 'i386' 体系结构,跳过配置文件 'main/binary-i386/Packages' 的获取。
'''
-updateThingsString = '''※1、容器自动配置脚本 GUI 查看介绍使用 QWebEngineWidget,支持图片(非强制依赖,只做推荐);
-※2、不基于生态适配活动脚本打包器跟进 arm 架构 2022年11月11日的 Wine 微信打包方式;
-※3、支持多图标的程序打包;
-※4、修复了安装更多 Wine 换源换了个寂寞的问题;
-※5、修复安装更多 Wine 重新安装后列表丢失的问题;
-※6、新增了对 Deepin 23 Alpha 优化的 Wine 安装器;
-※7、新增 Dll 名称查询功能,可以查询对应 Dll 的作用;
-※8、支持静态获取可执行文件可以调用的 Dll 并提供解决方案;
-※9、支持移除指定的 .desktop 快捷方式;
-※10、新增日志分析功能以及导出、上传日志功能;
-11、修复了不基于生态适配活动脚本打包器在选择 arm 打包架构下容器自动删除脚本取消勾选无用的问题;
-12、优化文案、新增友链;
-13、提供了部分组件的测试功能。
+updateThingsString = '''※1、支持使用 Qemu + Chroot 跨运行 Wine 以及指定程序的功能;
+※2、提供了简易打包器以用于打包简易 deb;
+※3、支持下载配置过的 Qemu + Chroot 容器;
'''
for i in information["Thank"]:
thankText += f"{i}\n"
-updateTime = "2022年11月25日"
+updateTime = "2022年12月03日"
about = f'''