Compare commits

..

41 Commits

Author SHA1 Message Date
0f10e5aace done 2022-12-10 21:11:29 +08:00
683a1a876e 新增图标 2022-12-10 12:46:27 +08:00
9fb280271b 修复MountWithouHome.sh的问题 2022-12-09 22:45:51 +08:00
12d8fb69e8 new 2022-12-09 17:37:10 +08:00
1cbb6d59be 新增程序翻译 2022-12-09 13:04:54 +08:00
2170aa7959 更新翻译 2022-12-09 12:54:19 +08:00
a7cf18bd28 新增打包器“Shift+F1提示” 2022-12-09 12:49:47 +08:00
38544a72f0 will 2022-12-09 10:37:50 +08:00
efa2c65886 优化菜单分类 2022-12-09 10:28:29 +08:00
1e1f451d6c 支持在隔离的 Chroot 容器内运行 Wine 2022-12-08 22:55:40 +08:00
ddbf0089b4 新增程序图标 2022-12-08 22:37:49 +08:00
368bea581e 添加图标 2022-12-08 21:58:06 +08:00
Allen
cf60f70ba5 删除文件 Icon/Function/.keep 2022-12-08 03:46:38 +00:00
Allen
a1fe72e4b9 update wine-function-png
新增功能图标

Signed-off-by: Allen <2849413304@qq.com>
2022-12-08 03:45:15 +00:00
Allen
da347935b7 新建 Function 2022-12-08 03:43:18 +00:00
163923de8d 新增vkd3d安装功能 2022-12-07 16:08:41 +08:00
e90708e03d 更新dxvk版本 2022-12-07 14:15:31 +08:00
ca939881e3 解压容器 2022-12-07 13:41:42 +08:00
fc8989db9f 程序公告 2022-12-07 13:18:49 +08:00
b60f2cd0eb 下载量初步 2022-12-07 10:21:50 +08:00
27eb980190 新增程序评分功能 2022-12-06 21:24:50 +08:00
8a7010529d 修复简易打包器无法打开问题 2022-12-06 17:31:18 +08:00
640c9f77a0 更新鸣谢列表 2022-12-06 12:44:53 +08:00
ed39b338c9 更新翻译 2022-12-06 09:38:01 +08:00
51635cf2c0 更新翻译 2022-12-05 22:36:19 +08:00
b2e15d12ac 更新翻译 2022-12-05 22:21:33 +08:00
dc998a4fa0 修改权限 2022-12-04 22:29:18 +08:00
66963e6f26 优化移除容器 2022-12-04 22:28:56 +08:00
c8ccc1dff5 修改makefile 2022-12-04 19:29:09 +08:00
08dbe1cb80 优化文案和简易打包器 2022-12-04 16:13:08 +08:00
01a3307626 优化文案 2022-12-03 22:14:23 +08:00
f6698e2f39 Qemu优化 2022-12-03 21:47:05 +08:00
9c0e2d11b3 《京剧猫》真好看,再看亿集再写代码 2022-12-03 19:34:34 +08:00
bcebe543cc 支持取消挂载容器 2022-12-02 22:26:10 +08:00
9fdc3a998c 主文件支持调用qemu chroot 2022-12-02 22:13:42 +08:00
fb0ff07ad6 Qemu Run And Chroot Unmount 2022-12-02 19:16:08 +08:00
a5352c6942 Qemu Chroot 镜像下载 2022-12-01 20:16:21 +08:00
e724d19663 新图标+Qemu镜像下载工具 2022-11-30 22:15:35 +08:00
e78fb2b4a4 初步制作qemu实现的跨架构运行wine的功能结构 2022-11-30 14:37:37 +08:00
d330c83691 更新依赖和简易打包器 2022-11-29 22:27:15 +08:00
de0a9b13f1 更新README 2022-11-29 08:15:11 +08:00
102 changed files with 4258 additions and 1142 deletions

3
ChangePassword.sh Executable file
View File

@@ -0,0 +1,3 @@
#!/bin/bash
echo -e "123456\n123456\n\n\n\n\n\n\n\n\n" | adduser "$1"
echo -e "123456\n123456\n" | passwd root

5
Download.py Normal file
View File

@@ -0,0 +1,5 @@
#!/usr/bin/env python3
import sys
import base64
import requests
print(requests.get(base64.b64decode("aHR0cDovLzEyMC4yNS4xNTMuMTQ0L3NwYXJrLWRlZXBpbi13aW5lLXJ1bm5lci9JbnN0YWxsLnBocD9WZXJzaW9uPQ==").decode("utf-8") + sys.argv[1]).text)

BIN
Icon/Function/CHROOT.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
Icon/Function/more-wine.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

BIN
Icon/Function/wine.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

BIN
Icon/Function/wine23A.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

BIN
Icon/Function/wine23P.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

BIN
Icon/Program/Windows虚拟机.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

BIN
Icon/Program/webp2.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

BIN
Icon/Program/webp3.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

BIN
Icon/Program/wine打包器.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

BIN
Icon/Program/wine运行器.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

0
IconList.json Normal file → Executable file
View File

161
Makefile
View File

@@ -3,82 +3,93 @@ build:
#cd VM-source && make
#cd wine && make
cp -rv helperset deb/opt/apps/deepin-wine-runner/
cp -rv VM-source/VirtualMachine VM
cp -rv VM-source/deepin-wine-runner.svg VM
cp -rv VM-source/api VM
cp -rv VM-source/Windows7X64Auto.iso VM
cp -rv VM-source/Windows7X86Auto.iso VM
cp -rv VM-source/run.py VM
cp -rv wine/ deb/opt/apps/deepin-wine-runner/
cp -rv Test/ deb/opt/apps/deepin-wine-runner/
cp -rv VM-source/VirtualMachine VM
cp -rv VM-source/deepin-wine-runner.svg VM
cp -rv VM-source/api VM
cp -rv VM-source/Windows7X64Auto.iso VM
cp -rv VM-source/Windows7X86Auto.iso VM
cp -rv VM-source/run.py VM
cp -rv wine/ deb/opt/apps/deepin-wine-runner/
cp -rv Test/ deb/opt/apps/deepin-wine-runner/
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 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 deepin-wine-easy-packager.py deb/opt/apps/deepin-wine-runner
cp -rv IconList.json deb/opt/apps/deepin-wine-runner
cp -rv VM deb/opt/apps/deepin-wine-runner
cp -rv Download.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 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 vkd3d-proton.7z 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
cp -rv MountWithoutHome.sh deb/opt/apps/deepin-wine-runner
echo "[]" > 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 BuildDesktop.py 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
cp -rv deepin-wine-packager-with-script.py deb/opt/apps/deepin-wine-runner
cp -rv deepin-wine-packager.py deb/opt/apps/deepin-wine-runner
cp -rv deepin-wine-runner-update-bug deb/opt/apps/deepin-wine-runner
cp -rv deepin-wine-runner.svg deb/opt/apps/deepin-wine-runner
cp -rv deepin-wine-venturi-setter.py deb/opt/apps/deepin-wine-runner
cp -rv InstallVisualBasicRuntime.py 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 geek.exe 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
cp -rv InstallNetFramework.py deb/opt/apps/deepin-wine-runner
cp -rv InstallOther.py deb/opt/apps/deepin-wine-runner
cp -rv InstallVisualCPlusPlus.py deb/opt/apps/deepin-wine-runner
cp -rv launch.sh deb/opt/apps/deepin-wine-runner
cp -rv LICENSE deb/opt/apps/deepin-wine-runner
cp -rv mainwindow.py deb/opt/apps/deepin-wine-runner/deepin-wine-runner
cp -rv package-script.zip deb/opt/apps/deepin-wine-runner
cp -rv Run.bat deb/opt/apps/deepin-wine-runner
cp -rv RunVM.sh deb/opt/apps/deepin-wine-runner
cp -rv "wine install" deb/opt/apps/deepin-wine-runner
cp -rv 窗体透明度设置工具.exe deb/opt/apps/deepin-wine-runner
cp -rv UpdateGeek.sh deb/opt/apps/deepin-wine-runner
cp -rv AppStore.py deb/opt/apps/deepin-wine-runner
cp -rv InstallWineOnDeepin23.py deb/opt/apps/deepin-wine-runner
cp -rv dxvk.7z deb/opt/apps/deepin-wine-runner
cp -rv InstallFont.py deb/opt/apps/deepin-wine-runner
cp -rv CheckDLL deb/opt/apps/deepin-wine-runner
#cp -rv exagear.7z deb/opt/apps/deepin-wine-runner
cp -rv dlls-arm.7z deb/opt/apps/deepin-wine-runner
cp -rv deepin.list deb/opt/apps/deepin-wine-runner
cp -rv sparkstore.list deb/opt/apps/deepin-wine-runner
cp -rv arm-package.7z deb/opt/apps/deepin-wine-runner
#cp -rv exa.7z deb/opt/apps/deepin-wine-runner
cp -rv clean-unuse-program.py deb/opt/apps/deepin-wine-runner
cp -rv InstallNewWineHQ.sh deb/opt/apps/deepin-wine-runner
cp -rv cleanbottle.sh deb/opt/apps/deepin-wine-runner
cp -rv StartVM.sh deb/opt/apps/deepin-wine-runner
#cp -rv deepin-wine-runner-create-botton.py deb/opt/apps/deepin-wine-runner
cp -rv Icon deb/opt/apps/deepin-wine-runner
cp -rv ConfigLanguareRunner-help.json deb/opt/apps/deepin-wine-runner
cp -rv gtkGetFileNameDlg deb/opt/apps/deepin-wine-runner
cp -rv LANG/*.qm deb/opt/apps/deepin-wine-runner/LANG
cp -rv InstallDll.py deb/opt/apps/deepin-wine-runner/LANG
cp -rv ConfigLanguareRunner.py deb/opt/apps/deepin-wine-runner
cp -rv AutoConfig.py deb/opt/apps/deepin-wine-runner
cp -rv UI deb/opt/apps/deepin-wine-runner/
cp -rv InstallDll.py deb/opt/apps/deepin-wine-runner
cp -rv Model deb/opt/apps/deepin-wine-runner
cp -rv API deb/opt/apps/deepin-wine-runner
cp -rv key 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 ChangePassword.sh deb/opt/apps/deepin-wine-runner
cp -rv trans 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
cp -rv deepin-wine-packager-with-script.py deb/opt/apps/deepin-wine-runner
cp -rv deepin-wine-packager.py deb/opt/apps/deepin-wine-runner
cp -rv deepin-wine-runner-update-bug deb/opt/apps/deepin-wine-runner
cp -rv deepin-wine-runner.svg deb/opt/apps/deepin-wine-runner
cp -rv deepin-wine-venturi-setter.py deb/opt/apps/deepin-wine-runner
cp -rv InstallVisualBasicRuntime.py 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 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
cp -rv InstallNetFramework.py deb/opt/apps/deepin-wine-runner
cp -rv InstallOther.py deb/opt/apps/deepin-wine-runner
cp -rv InstallVisualCPlusPlus.py deb/opt/apps/deepin-wine-runner
cp -rv launch.sh deb/opt/apps/deepin-wine-runner
cp -rv LICENSE deb/opt/apps/deepin-wine-runner
cp -rv mainwindow.py deb/opt/apps/deepin-wine-runner/deepin-wine-runner
cp -rv package-script.zip deb/opt/apps/deepin-wine-runner
cp -rv Run.bat deb/opt/apps/deepin-wine-runner
cp -rv RunVM.sh deb/opt/apps/deepin-wine-runner
cp -rv "wine install" deb/opt/apps/deepin-wine-runner
cp -rv 窗体透明度设置工具.exe deb/opt/apps/deepin-wine-runner
cp -rv UpdateGeek.sh deb/opt/apps/deepin-wine-runner
cp -rv AppStore.py deb/opt/apps/deepin-wine-runner
cp -rv InstallWineOnDeepin23.py deb/opt/apps/deepin-wine-runner
cp -rv dxvk.7z deb/opt/apps/deepin-wine-runner
cp -rv InstallFont.py deb/opt/apps/deepin-wine-runner
cp -rv CheckDLL deb/opt/apps/deepin-wine-runner
#cp -rv exagear.7z deb/opt/apps/deepin-wine-runner
cp -rv dlls-arm.7z deb/opt/apps/deepin-wine-runner
cp -rv deepin.list deb/opt/apps/deepin-wine-runner
cp -rv sparkstore.list deb/opt/apps/deepin-wine-runner
cp -rv arm-package.7z deb/opt/apps/deepin-wine-runner
#cp -rv exa.7z deb/opt/apps/deepin-wine-runner
cp -rv clean-unuse-program.py deb/opt/apps/deepin-wine-runner
cp -rv InstallNewWineHQ.sh deb/opt/apps/deepin-wine-runner
cp -rv cleanbottle.sh deb/opt/apps/deepin-wine-runner
cp -rv StartVM.sh deb/opt/apps/deepin-wine-runner
#cp -rv deepin-wine-runner-create-botton.py deb/opt/apps/deepin-wine-runner
cp -rv Icon deb/opt/apps/deepin-wine-runner
cp -rv ConfigLanguareRunner-help.json deb/opt/apps/deepin-wine-runner
cp -rv gtkGetFileNameDlg deb/opt/apps/deepin-wine-runner
cp -rv LANG/*.qm deb/opt/apps/deepin-wine-runner/LANG
cp -rv InstallDll.py deb/opt/apps/deepin-wine-runner/LANG
cp -rv ConfigLanguareRunner.py deb/opt/apps/deepin-wine-runner
cp -rv AutoConfig.py deb/opt/apps/deepin-wine-runner
cp -rv UI deb/opt/apps/deepin-wine-runner/
cp -rv InstallDll.py deb/opt/apps/deepin-wine-runner
cp -rv Model deb/opt/apps/deepin-wine-runner
cp -rv API deb/opt/apps/deepin-wine-runner
cp -rv key deb/opt/apps/deepin-wine-runner
dpkg -b deb spark-deepin-wine-runner.deb
@@ -91,11 +102,5 @@ install:
remove:
sudo apt purge spark-deepin-wine-runner
depend:
sudo apt update
sudo apt install python3 python3-pil python3-pil.imagetk\
python3-pyquery deepin-terminal aria2 curl unrar unzip\
python3-requests fakeroot bash python3-pyqt5
run:
python3 mainwindow.py

BIN
Model/__pycache__/__init__.cpython-310.pyc Executable file → Normal file

Binary file not shown.

Binary file not shown.

44
Mount.sh Executable file
View File

@@ -0,0 +1,44 @@
#!/bin/bash
if [ ` whoami ` != "root" ]; then
echo "Only root can run me"
exit 1
fi
if [ ! -d "$1" ]; then
echo "路径不存在!"
exit 1
fi
echo $0
echo $1
echo $2
echo $3
# 挂载必备目录
cd "$1"
# 拷贝 Qemu Static
cp -r /usr/bin/qemu-*-static ./usr/bin
# 挂载目录
mount --bind /dev ./dev
#mount --bind /dev/pts ./dev/pts
mount -t proc /proc ./proc
mount --bind /etc/resolv.conf ./etc/resolv.conf
mount -t sysfs /sys ./sys
#mount --bind /dev/shm ./dev/shm
chmod 777 -R root
xhost +
# 挂载 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}

29
MountWithoutHome.sh Executable file
View File

@@ -0,0 +1,29 @@
#!/bin/bash
if [ ` whoami ` != "root" ]; then
echo "Only root can run me"
exit 1
fi
if [ ! -d "$1" ]; then
echo "路径不存在!"
exit 1
fi
echo $0
echo $1
echo $2
echo $3
# 挂载必备目录
cd "$1"
# 拷贝 Qemu Static
cp -r /usr/bin/qemu-*-static ./usr/bin
# 挂载目录
mount --bind /dev ./dev
#mount --bind /dev/pts ./dev/pts
mount -t proc /proc ./proc
mount --bind /etc/resolv.conf ./etc/resolv.conf
mount -t sysfs /sys ./sys
#mount --bind /dev/shm ./dev/shm
chmod 777 -R root
xhost +
# 如果参数 3 存在
chroot . ${@:3}

122
ProgramFen.py Executable file
View 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(ProgramRunStatusShow.msgWindow)
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, 1]:
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(5)
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(ProgramRunStatusUpload.msgWindow, 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(ProgramRunStatusUpload.msgWindow, 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_()

438
QemuDownload.py Executable file
View File

@@ -0,0 +1,438 @@
#!/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 trans 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)
if not get_now_lang() == "zh_CN.UTF-8":
transla = Trans("en_US", f"{programPath}/trans/deepin-wine-runner-qemu-download.json")
else:
transla = Trans("zh_CN")
_translate = transla.transe
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")
self.verticalLayout_2.addWidget(QtWidgets.QLabel(_translate("U", """使用前须知:
1、Qemu 跨架构效率较低,如果有条件建议优先使用 box86、exagear 等效率较高的转换层;
2、使用此方案需要使用到 Root 权限(需开启管理员模式)并安装 qemu-user-static
3、chroot 时候可能会出现问题导致程序闪退或异常,出现该问题重启电脑即可;
4、在此环境使用 Wine 时,只能读取到您用户目录或本程序文件夹下的文件,其它路径无法读取;
5、移除容器时请保证在这次打开电脑时没有调用过需要删除容器如果有调用过建议重启电脑后再移除
6、暂时属于测试功能""")))
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 os.path.exists("/tmp/deepin-wine-runner-qemu-lock"):
if QtWidgets.QMessageBox.question(window, "提示", "检测到您的电脑已经运行了 Qemu/Chroot 容器,建议您重启电脑后再删除该容器,否则容易造成数据损失!\n是否取消操作?") == QtWidgets.QMessageBox.Yes:
return
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_()

44
QemuRun.py Executable file
View File

@@ -0,0 +1,44 @@
#!/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[3:]:
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}' ")
os.system("touch /tmp/deepin-wine-runner-qemu-lock")
# 判断是否挂载
if not os.path.ismount(f"{homePath}/.deepin-wine-runner-ubuntu-images/{sys.argv[1]}/dev"):
print("文件暂未挂载,开始挂载")
if int(sys.argv[2]):
sys.exit(os.system(f"pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY bash '{programPath}/MountWithoutHome.sh' '{homePath}/.deepin-wine-runner-ubuntu-images/{sys.argv[1]}' '{userName}' {commandList}"))
else:
sys.exit(os.system(f"pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY bash '{programPath}/Mount.sh' '{homePath}/.deepin-wine-runner-ubuntu-images/{sys.argv[1]}' '{userName}' {commandList}"))
sys.exit(os.system(f"pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY chroot '--userspec={userName}:{userName}' '{homePath}/.deepin-wine-runner-ubuntu-images/{sys.argv[1]}/' env 'HOME=/home/{userName}' {commandList}"))

View File

@@ -1,5 +1,5 @@
<p width=100px align="center"><img src="https://storage.deepin.org/thread/202208031419283599_deepin-wine-runner.png"></p>
<h1 align="center">Wine 运行器 2.5.0</h1>
<h1 align="center">Wine 运行器 3.0.0</h1>
<hr>
## 介绍
@@ -11,7 +11,7 @@ env WINEPREFIX=容器路径 winewine的路径 可执行文件路径
```
让你可以简易方便的使用 wine
是使用 Python3 的 PyQt5 构建的
测试平台deepin 20.7.1UOS 家庭版 21.3.1Ubuntu 22.04Ubuntu 20.04UOS 专业版 1050openkylin
测试平台deepin 20.8UOS 家庭版 21.3.1Ubuntu 22.04Ubuntu 20.04UOS 专业版 1050openkylin
![截图_选择区域_20221002221112.png](https://storage.deepin.org/thread/202210022215217037_截图_选择区域_20221002221112.png)
而打包器可以方便的把您的 wine 容器打包成 deb 包供他人使用,程序创建的 deb 构建临时文件夹目录树如下:
```bash
@@ -37,17 +37,16 @@ env WINEPREFIX=容器路径 winewine的路径 可执行文件路径
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
## 软件架构
i386、amd64 和 arm64deepin-wine、deepin-wine5、wine、wine64、deepin-wine5-stable、deepin-wine6-stable、spark-wine7-devel、ukylin-wine 运行在哪就运行在哪
理论上支持全架构,如果 Python 能运行的话
非 X86 架构会利用到 `box86``exagear`等技术
非 X86 架构会利用到 `box86``exagear``qemu` 等技术
## 分支介绍
### main 分支
主分支,稳定分支
### Alpha 分支
开发版分支,一般不稳定,有许多 bug
## 版本区分
### 无特殊标识
@@ -103,6 +102,29 @@ desktop文件中StartupWMClass字段。用于让桌面组件将窗口类名与de
![image.png](https://storage.deepin.org/thread/202207190822204627_image.png)
## 更新日志
### 3.0.02022年12月10日
**※1、支持使用 Qemu + Chroot 跨运行 Wine 以及指定程序的功能;**
**※2、提供了简易打包器以用于打包简易 deb**
**※3、支持下载配置过的 Qemu + Chroot 容器;**
**※4、支持在隔离的 Chroot 容器内运行 Wine**
**※5、支持解压指定 deb 的内打包好的容器;**
**※6、优化 Wine 列表显示;**
**※7、新增程序论坛和教程入口**
**※8、程序公告功能**
**※9、新增程序评分功能**
**※10、新增解包 deb 内 Wine 容器功能;**
**※11、新增 Vkd3d Proton 安装功能,更新 dxvk 版本至 2.0.0**
**※12、新增程序菜单栏部分栏目图标**
**※13、打包器支持按下 Shift + F1 查看指定选项提示;**
14、优化非基于生态适配脚本的打包器内容自动填充功能
15、优化程序文案
16、新增日志翻译功能
17、程序进一步完善英语翻译机翻
18、优化程序更新策略
19、优化日志分析功能
20、优化程序 UI。
![image.png](https://storage.deepin.org/thread/202212102108356218_image.png)
### 2.5.0.12022年11月25日
**※1、修复已知问题**

View File

@@ -8,10 +8,10 @@
# 基于 Python3 的 tkinter 构建
###########################################################################################
cd `dirname $0`
which VBoxManage1
which VBoxManage
if test $? == 0 ; then
VM/VirtualMachine
exit
fi
zenity --info --no-wrap --text="未安装 VirtualBox请自行安装 VirtualBox 并重新运行"
#./launch.sh deepin-terminal -C "pkexec apt install virtualbox-6.1 -y && zenity --info --text=\"安装完毕,关闭此对话框和安装终端重新运行程序即可\" --no-wrap" --keep-open
#./launch.sh deepin-terminal -C "pkexec apt install virtualbox-6.1 -y && zenity --info --text=\"安装完毕,关闭此对话框和安装终端重新运行程序即可\" --no-wrap" --keep-open

View File

@@ -0,0 +1,3 @@
echo 开始安装 qemu-user-static
pkexec apt update
pkexec apt install qemu-user-static -y

BIN
UI/__pycache__/KeyAddGui.cpython-37.pyc Executable file → Normal file

Binary file not shown.

37
UnMount.sh Executable file
View File

@@ -0,0 +1,37 @@
#!/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
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

0
arm-package.7z Normal file → Executable file
View File

View File

@@ -1,29 +1,36 @@
Package: spark-deepin-wine-runner
Version: 2.6.0~alpha1
Version: 3.0.0
Maintainer: gfdgd xi <3025613752@qq.com>, 为什么您不喜欢熊出没和阿布呢
Homepage: https://gitee.com/gfdgd-xi/deep-wine-runner, https://github.com/gfdgd-xi/deep-wine-runner, https://gitlink.org.cn/gfdgd_xi/deep-wine-runner
Architecture: all
Priority: optional
Depends: python3, python3-pil, python3-pil.imagetk, python3-pyquery, aria2, curl, unrar, unzip, python3-requests, fakeroot, bash, python3-pyqt5, python3-psutil, deepin-terminal | mate-terminal | gnome-terminal | xfce4-terminal, python3-dbus, python3-pip
Recommends: winbind, wimtools
Depends: python3, python3-pil, python3-pil.imagetk, python3-pyquery, aria2, curl, unrar, unzip, python3-requests, fakeroot, bash, python3-pyqt5, python3-psutil, deepin-terminal | mate-terminal | gnome-terminal | xfce4-terminal, python3-dbus, python3-pip, p7zip-full, sudo
Recommends: winbind, wimtools, python3-pyqt5.qtwebengine
Section: utils
Conflicts: spark.deepin-venturi-setter, spark-deepin-wine5-application-packer
Replaces: spark.deepin-venturi-setter, spark-deepin-wine5-application-packer
Installed-Size: 21844
Conflicts: spark.deepin-venturi-setter, spark-deepin-wine5-application-packer, spark-deepin-wine-runner-52
Replaces: spark.deepin-venturi-setter, spark-deepin-wine5-application-packer, spark-deepin-wine-runner-52
Installed-Size: 25856
Description: gfdgd xi、为什么您不喜欢熊出没和阿布呢 制作的 wine 运行器
2.5.0 更新内容:
※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、提供了部分组件的测试功能。
更新时间2022年11月25日
3.0.0 更新内容:
※1、支持使用 Qemu + Chroot 跨运行 Wine 以及指定程序的功能
※2、提供了简易打包器以用于打包简易 deb
※3、支持下载配置过的 Qemu + Chroot 容器
※4、支持在隔离的 Chroot 容器内运行 Wine
※5、支持解压指定 deb 的内打包好的容器
※6、优化 Wine 列表显示
※7、新增程序论坛和教程入口
※8、程序公告功能
※9、新增程序评分功能
※10、新增解包 deb 内 Wine 容器功能;
11、新增 Vkd3d Proton 安装功能,更新 dxvk 版本至 2.0.0
12、新增程序菜单栏部分栏目图标
13、打包器支持按下 Shift + F1 查看指定选项提示;
14、优化非基于生态适配脚本的打包器内容自动填充功能
15、优化程序文案
16、新增日志翻译功能
17、程序进一步完善英语翻译机翻
18、优化程序更新策略
19、优化日志分析功能
20、优化程序 UI。
更新时间2022年12月09日
作者gfdgd xi、为什么您不喜欢熊出没和阿布呢

View File

@@ -2,7 +2,7 @@
# 使用系统默认的 sh 运行
#################################################################################################################
# 作者gfdgd xi、为什么您不喜欢熊出没和阿布呢
# 版本2.3.0
# 版本2.6.0
# 更新时间2022年10月02日
# 感谢:感谢 wine、deepin-wine 以及星火团队,提供了 wine、deepin-wine、spark-wine-devel 给大家使用,让我能做这个程序
# 基于 sh
@@ -10,6 +10,7 @@
# 非强制性的必应组件,所以成功不成功都行
echo 安装组件
python3 -m pip install --upgrade pynput --trusted-host https://repo.huaweicloud.com -i https://repo.huaweicloud.com/repository/pypi/simple > /dev/null 2>&1 | true
python3 -m pip install --upgrade xpinyin --trusted-host https://repo.huaweicloud.com -i https://repo.huaweicloud.com/repository/pypi/simple > /dev/null 2>&1 | true
echo 执行完成
echo 移除旧组件
if [ -d /opt/apps/deepin-wine-runner/arm-package ]; then
@@ -48,9 +49,13 @@ if [ `arch` != "x86_64" ]; then
rm -rf /opt/apps/deepin-wine-runner/InstallNewWineHQ.sh
fi
# 到时候切换 gpg 源会方便很多
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys FD6EEA1F20CD4B27 > /dev/null 2>&1 | true
if [ -d /usr/share/deepin-installer ]; then
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys FD6EEA1F20CD4B27 > /dev/null 2>&1 | true
# 用于修复 2022.11.25 Better DDE 导致的 Deepin Community Live CD Install 版问题
sh -c 'echo "deb [trusted=yes] https://proposed-packages.deepin.com/dde-apricot unstable main contrib non-free" > /etc/apt/sources.list.d/deepin-unstable.list'
fi
apt update > /dev/null 2>&1 | true
# 设置目录权限,让用户可读可写,方便后续删除组件
chmod 777 -R /opt/apps/deepin-wine-runner
# 向服务器返回安装数加1不显示内容且忽略错误
curl https://304626p927.goho.co/spark-deepin-wine-runner/Install.php?Version=2.5.0 -s > /dev/null 2>&1 | true
python3 /opt/apps/deepin-wine-runner/Download.py 3.0.0 > /dev/null 2>&1 | true

View File

@@ -0,0 +1,3 @@
#!/bin/bash
echo -e "123456\n123456\n\n\n\n\n\n\n\n\n" | adduser "$1"
echo -e "123456\n123456\n" | passwd root

View File

@@ -0,0 +1,5 @@
#!/usr/bin/env python3
import sys
import base64
import requests
print(requests.get(base64.b64decode("aHR0cDovLzEyMC4yNS4xNTMuMTQ0L3NwYXJrLWRlZXBpbi13aW5lLXJ1bm5lci9JbnN0YWxsLnBocD9WZXJzaW9uPQ==").decode("utf-8") + sys.argv[1]).text)

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

View 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"]
]
]

View File

@@ -0,0 +1,44 @@
#!/bin/bash
if [ ` whoami ` != "root" ]; then
echo "Only root can run me"
exit 1
fi
if [ ! -d "$1" ]; then
echo "路径不存在!"
exit 1
fi
echo $0
echo $1
echo $2
echo $3
# 挂载必备目录
cd "$1"
# 拷贝 Qemu Static
cp -r /usr/bin/qemu-*-static ./usr/bin
# 挂载目录
mount --bind /dev ./dev
#mount --bind /dev/pts ./dev/pts
mount -t proc /proc ./proc
mount --bind /etc/resolv.conf ./etc/resolv.conf
mount -t sysfs /sys ./sys
#mount --bind /dev/shm ./dev/shm
chmod 777 -R root
xhost +
# 挂载 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}

View File

@@ -0,0 +1,29 @@
#!/bin/bash
if [ ` whoami ` != "root" ]; then
echo "Only root can run me"
exit 1
fi
if [ ! -d "$1" ]; then
echo "路径不存在!"
exit 1
fi
echo $0
echo $1
echo $2
echo $3
# 挂载必备目录
cd "$1"
# 拷贝 Qemu Static
cp -r /usr/bin/qemu-*-static ./usr/bin
# 挂载目录
mount --bind /dev ./dev
#mount --bind /dev/pts ./dev/pts
mount -t proc /proc ./proc
mount --bind /etc/resolv.conf ./etc/resolv.conf
mount -t sysfs /sys ./sys
#mount --bind /dev/shm ./dev/shm
chmod 777 -R root
xhost +
# 如果参数 3 存在
chroot . ${@:3}

View 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(ProgramRunStatusShow.msgWindow)
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, 1]:
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(5)
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(ProgramRunStatusUpload.msgWindow, 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(ProgramRunStatusUpload.msgWindow, 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_()

View File

@@ -0,0 +1,438 @@
#!/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 trans 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)
if not get_now_lang() == "zh_CN.UTF-8":
transla = Trans("en_US", f"{programPath}/trans/deepin-wine-runner-qemu-download.json")
else:
transla = Trans("zh_CN")
_translate = transla.transe
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")
self.verticalLayout_2.addWidget(QtWidgets.QLabel(_translate("U", """使用前须知:
1、Qemu 跨架构效率较低,如果有条件建议优先使用 box86、exagear 等效率较高的转换层;
2、使用此方案需要使用到 Root 权限(需开启管理员模式)并安装 qemu-user-static
3、chroot 时候可能会出现问题导致程序闪退或异常,出现该问题重启电脑即可;
4、在此环境使用 Wine 时,只能读取到您用户目录或本程序文件夹下的文件,其它路径无法读取;
5、移除容器时请保证在这次打开电脑时没有调用过需要删除容器如果有调用过建议重启电脑后再移除
6、暂时属于测试功能""")))
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 os.path.exists("/tmp/deepin-wine-runner-qemu-lock"):
if QtWidgets.QMessageBox.question(window, "提示", "检测到您的电脑已经运行了 Qemu/Chroot 容器,建议您重启电脑后再删除该容器,否则容易造成数据损失!\n是否取消操作?") == QtWidgets.QMessageBox.Yes:
return
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_()

View File

@@ -0,0 +1,44 @@
#!/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[3:]:
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}' ")
os.system("touch /tmp/deepin-wine-runner-qemu-lock")
# 判断是否挂载
if not os.path.ismount(f"{homePath}/.deepin-wine-runner-ubuntu-images/{sys.argv[1]}/dev"):
print("文件暂未挂载,开始挂载")
if int(sys.argv[2]):
sys.exit(os.system(f"pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY bash '{programPath}/MountWithoutHome.sh' '{homePath}/.deepin-wine-runner-ubuntu-images/{sys.argv[1]}' '{userName}' {commandList}"))
else:
sys.exit(os.system(f"pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY bash '{programPath}/Mount.sh' '{homePath}/.deepin-wine-runner-ubuntu-images/{sys.argv[1]}' '{userName}' {commandList}"))
sys.exit(os.system(f"pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY chroot '--userspec={userName}:{userName}' '{homePath}/.deepin-wine-runner-ubuntu-images/{sys.argv[1]}/' env 'HOME=/home/{userName}' {commandList}"))

View File

@@ -8,10 +8,10 @@
# 基于 Python3 的 tkinter 构建
###########################################################################################
cd `dirname $0`
which VBoxManage1
which VBoxManage
if test $? == 0 ; then
VM/VirtualMachine
exit
fi
zenity --info --no-wrap --text="未安装 VirtualBox请自行安装 VirtualBox 并重新运行"
#./launch.sh deepin-terminal -C "pkexec apt install virtualbox-6.1 -y && zenity --info --text=\"安装完毕,关闭此对话框和安装终端重新运行程序即可\" --no-wrap" --keep-open
#./launch.sh deepin-terminal -C "pkexec apt install virtualbox-6.1 -y && zenity --info --text=\"安装完毕,关闭此对话框和安装终端重新运行程序即可\" --no-wrap" --keep-open

View File

@@ -0,0 +1,3 @@
echo 开始安装 qemu-user-static
pkexec apt update
pkexec apt install qemu-user-static -y

View File

@@ -0,0 +1,37 @@
#!/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
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

View File

@@ -0,0 +1,648 @@
#!/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)
def ReadMe():
QtWidgets.QMessageBox.information(window, "提示", """1、目前只支持打包 X86 架构的 deb 包,暂未支持 arm
2、需要区分要打包的程序是绿色软件还是单文件安装包两个对应的打包方式不相同
3、打包绿色软件时为尽可能减小程序体积请将绿化后的程序或程序文件夹单独拷贝到干净的目录后再浏览选择主程序打包
4、打包详情
①调用 WineDeepin Wine6 Stable
②调用 HelperSpark Wine Helper
③有卸载自动移除容器脚本""")
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'")
# 安装包
self.info.emit("请在运行完安装程序后按下打包器主界面的“安装程序执行完成按钮”以进行下一步操作")
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 = "com." + xpinyin.Pinyin().get_pinyin(os.path.splitext(os.path.basename(rightLnk[0]))[0].replace(" ", "")).lower().replace("--", "-").replace(" ", "").replace("_", "-").replace("-", ".") + ".spark"
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("安装程序执行完成")
helpButton = QtWidgets.QPushButton("帮助")
browserExeButton.clicked.connect(BrowserExe)
buildButton.clicked.connect(RunBuildThread)
installCmpleteButton.clicked.connect(PressCompleteDownload)
helpButton.clicked.connect(ReadMe)
installCmpleteButton.setDisabled(True)
controlLayout.addWidget(buildButton)
controlLayout.addWidget(installCmpleteButton)
controlLayout.addWidget(helpButton)
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_())

View File

@@ -23,23 +23,24 @@ from PIL import Image
import PyQt5.QtGui as QtGui
import PyQt5.QtCore as QtCore
import PyQt5.QtWidgets as QtWidgets
from trans import *
#################
# 程序所需事件
#################
def button1_cl():
path = QtWidgets.QFileDialog.getExistingDirectory(widget, QtCore.QCoreApplication.translate("U", "选择 wine 容器"), f"{get_home()}/.deepinwine")
path = QtWidgets.QFileDialog.getExistingDirectory(widget, transla.transe("U", "选择 wine 容器"), f"{get_home()}/.deepinwine")
if path != "":
e6_text.setText(path)
def button2_cl(number):
path = QtWidgets.QFileDialog.getOpenFileName(widget, QtCore.QCoreApplication.translate("U", "选择图标文件"), get_home(), "PNG图标(*.png);;SVG图标(*.svg);;全部文件(*.*)")[0]
path = QtWidgets.QFileDialog.getOpenFileName(widget, transla.transe("U", "选择图标文件"), get_home(), "PNG图标(*.png);;SVG图标(*.svg);;全部文件(*.*)")[0]
if path != "":
mapLink[number].setText(path)
def button4_cl():
path = QtWidgets.QFileDialog.getSaveFileName(widget, QtCore.QCoreApplication.translate("U", "保存 deb 包"), get_home(), "deb 文件(*.deb);;所有文件(*.*)", "{}_{}_i386.deb".format(e1_text.text(), e2_text.text()))[0]
path = QtWidgets.QFileDialog.getSaveFileName(widget, transla.transe("U", "保存 deb 包"), get_home(), "deb 文件(*.deb);;所有文件(*.*)", "{}_{}_i386.deb".format(e1_text.text(), e2_text.text()))[0]
if path != "":
e12_text.setText(path)
@@ -203,14 +204,41 @@ 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 包")
return
if QtWidgets.QMessageBox.question(widget, QtCore.QCoreApplication.translate("U", "提示"), QtCore.QCoreApplication.translate("U", "打包将会改动现在选择的容器,是否继续?")) == QtWidgets.QMessageBox.No:
if QtWidgets.QMessageBox.question(widget, transla.transe("U", "提示"), transla.transe("U", "打包将会改动现在选择的容器,是否继续?")) == QtWidgets.QMessageBox.No:
disabled_or_NORMAL_all(True)
return
# 警告信息
@@ -232,6 +260,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 +274,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 +1232,7 @@ fi
# 获取文件大小
################
self.label.emit("正在计算文件大小……")
size = int(getFileFolderSize(debPackagePath) / 1024)
size = int(getFileFolderSize(debPackagePath) / 1000)
################
# 写入文本文档
################
@@ -1324,6 +1352,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("完成构建!")
@@ -1689,7 +1723,7 @@ mapLink = []
def AddTab():
global mapLink
button2 = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "浏览……"))
button2 = QtWidgets.QPushButton(transla.transe("U", "浏览……"))
e7_text = QtWidgets.QLineEdit()
e8_text = QtWidgets.QLineEdit()
e9_text = QtWidgets.QLineEdit()
@@ -1703,11 +1737,11 @@ def AddTab():
mapLink.append(e9_text)
#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", "要显示的 .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", "要显示的 .desktop 文件的名称(※必填):")), 9, 0, 1, 1)
desktopIconTabLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "要显示的 .desktop 文件的图标(选填)")), 10, 0, 1, 1)
desktopIconTabLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "wine 容器里需要运行的可执行文件路径(※必填):")), 6, 0, 1, 1)
desktopIconTabLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "要显示的 .desktop 文件的分类(※必填):")), 7, 0, 1, 1)
desktopIconTabLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "wine 容器里需要运行的可执行文件的参数:")), 8, 0, 1, 1)
desktopIconTabLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "要显示的 .desktop 文件的名称(※必填):")), 9, 0, 1, 1)
desktopIconTabLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "要显示的 .desktop 文件的图标:")), 10, 0, 1, 1)
iconTab1.setLayout(desktopIconTabLayout)
desktopIconTab.addTab(iconTab1, f"图标{desktopIconTab.count() + 1}")
desktopIconTabLayout.addWidget(e7_text, 6, 1, 1, 1)
@@ -1716,7 +1750,24 @@ def AddTab():
desktopIconTabLayout.addWidget(e8_text, 9, 1, 1, 1)
desktopIconTabLayout.addWidget(e9_text, 10, 1, 1, 1)
desktopIconTabLayout.addWidget(button2, 10, 2, 1, 1)
e8_text.setWhatsThis(transla.transe("U", """填写该软件的中文或英文名称。"""))
e9_text.setWhatsThis(transla.transe("U", """图标只支持PNG格式和SVG格式其他格式无法显示。"""))
e15_text.setWhatsThis(transla.transe("U", "程序参数,如%u,一般不需要"))
e7_text.setWhatsThis(transla.transe("U", """可执行文件的运行路径格式是“C:/XXX/XXX.exe”不包含引号"""))
option1_text.setWhatsThis(transla.transe("U", """点击右侧的下拉箭头,选择该软件所属的软件分类即可,常见软件分类名称释义:
Network=网络应用;
Chat=即时通讯或社交沟通;
Video=视频播放;
Graphics=图形图像;
Office=办公学习;
Translation=阅读翻译;
Development=软件开发;
Utility=工具软件或其他应用。
不明白英文的可以百度查询一下软件分类名称的意思。
注意:此时选择的软件分类名称决定了该软件打包后再安装时会安装在启动器中的哪个软件分类目录中。"""))
e7_text.textChanged.connect(ChangeTapTitle)
e7_text.setPlaceholderText("例如 c:/Program Files/Tencent/QQ/Bin/QQ.exe")
e9_text.setPlaceholderText(transla.transe("U", "支持 png 和 svg 格式,不支持 ico 格式"))
iconUiList.append([e7_text, option1_text, e15_text, e8_text, e9_text])
print(iconUiList)
@@ -1727,6 +1778,30 @@ 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
# 获取当前语言
def get_now_lang()->"获取当前语言":
return os.getenv('LANG')
bottleNameLock = False
###############
# 程序信息
###############
@@ -1758,18 +1833,27 @@ iconUiList = []
iconPath = "{}/deepin-wine-runner.svg".format(programPath)
information = json.loads(readtxt(f"{programPath}/information.json"))
version = information["Version"]
tips = """提示:
# 语言载入
if not get_now_lang() == "zh_CN.UTF-8":
#trans = QtCore.QTranslator()
#trans.load(f"{programPath}/LANG/deepin-wine-runner-en_US.qm")
#app.installTranslator(trans)
transla = Trans("en_US", f"{programPath}/trans/deepin-wine-packager.json")
else:
transla = Trans("zh_CN")
tips = transla.transe("U", """提示:
1、deb 打包软件包名要求:
软件包名只能含有小写字母(a-z)、数字(0-9)、加号(+)和减号(-)、以及点号(.),软件包名最短长度两个字符;它必须以字母开头
2、如果要填写路径有“浏览……”按钮的是要填本计算机对应文件的路径否则就是填写安装到其他计算机使用的路径
3、输入 wine 的容器路径时最后面请不要输入“/”
4、输入可执行文件的运行路径时是以“C:/XXX/XXX.exe”的格式进行输入默认是以 C 为开头,不用“\”做命令的分隔,而是用“/”
5、.desktop 的图标只支持 PNG 格式和 SVG 格式,其他格式无法显示图标
6、路径建议不要带空格容易出问题"""
6、路径建议不要带空格容易出问题""")
###############
# 窗口创建
###############
app = QtWidgets.QApplication(sys.argv)
window = QtWidgets.QMainWindow()
widget = QtWidgets.QWidget()
@@ -1792,25 +1876,25 @@ e12_text = QtWidgets.QLineEdit()
e15_text = QtWidgets.QLineEdit()
label13_text = QtWidgets.QLabel("<p align='center'>当前 deb 打包情况:暂未打包</p>")
option1_text = QtWidgets.QComboBox()
button1 = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "浏览……"))
button2 = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "浏览……"))
button4 = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "浏览……"))
button1 = QtWidgets.QPushButton(transla.transe("U", "浏览……"))
button2 = QtWidgets.QPushButton(transla.transe("U", "浏览……"))
button4 = QtWidgets.QPushButton(transla.transe("U", "浏览……"))
debControlFrame = QtWidgets.QHBoxLayout()
button5 = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "打包……"))
installDeb = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "安装打包完成的 deb……"))
buildDebDir = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "根据填写内容打包模板"))
build7z = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "打包容器 7z 包"))
button5 = QtWidgets.QPushButton(transla.transe("U", "打包……"))
installDeb = QtWidgets.QPushButton(transla.transe("U", "安装打包完成的 deb……"))
buildDebDir = QtWidgets.QPushButton(transla.transe("U", "根据填写内容打包模板"))
build7z = QtWidgets.QPushButton(transla.transe("U", "打包容器 7z 包"))
debControlFrame.addWidget(button5)
debControlFrame.addWidget(installDeb)
rmBash = QtWidgets.QCheckBox(QtCore.QCoreApplication.translate("U", "设置卸载该 deb 后自动删除该容器"))
cleanBottonByUOS = QtWidgets.QCheckBox(QtCore.QCoreApplication.translate("U", "使用统信 Wine 生态适配活动容器清理脚本"))
rmBash = QtWidgets.QCheckBox(transla.transe("U", "设置卸载该 deb 后自动删除该容器"))
cleanBottonByUOS = QtWidgets.QCheckBox(transla.transe("U", "使用统信 Wine 生态适配活动容器清理脚本"))
debArch = QtWidgets.QComboBox()
debArch.addItems(["i386", "arm64(box86+exagear)"])
textbox1 = QtWidgets.QTextBrowser()
option1_text.addItems(["Network", "Chat", "Audio", "Video", "Graphics", "Office", "Translation", "Development", "Utility"])
option1_text.setCurrentText("Network")
wineFrame = QtWidgets.QHBoxLayout()
chooseWineHelperValue = QtWidgets.QCheckBox(QtCore.QCoreApplication.translate("U", "使用星火wine helper\n如不勾选默认为deepin-wine-helper"))
chooseWineHelperValue = QtWidgets.QCheckBox(transla.transe("U", "使用星火wine helper\n如不勾选默认为deepin-wine-helper"))
button1.clicked.connect(button1_cl)
button2.clicked.connect(lambda: button2_cl(0))
mapLink.append(e9_text)
@@ -1820,19 +1904,23 @@ 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(transla.transe("U", "要打包的 deb 包的包名(※必填):")), 0, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "deb 包的版本号(※必填):")), 1, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "deb 包的说明(※必填):")), 2, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "deb 包的维护者(※必填):")), 3, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "解压的 wine 容器的名称(※必填):")), 4, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "打包的 wine 容器路径(※必填):")), 5, 0, 1, 1)
desktopIconTab = QtWidgets.QTabWidget()
controlWidget = QtWidgets.QWidget()
controlWidgetLayout = QtWidgets.QHBoxLayout()
desktopIconTabAdd = QtWidgets.QPushButton("+")
desktopIconTabDel = QtWidgets.QPushButton("-")
desktopIconTabAdd.setWhatsThis("添加新图标")
desktopIconTabDel.setWhatsThis("移除选中图标")
controlWidgetLayout.addWidget(desktopIconTabAdd)
controlWidgetLayout.addWidget(desktopIconTabDel)
controlWidget.setLayout(controlWidgetLayout)
@@ -1840,18 +1928,18 @@ desktopIconTabAdd.clicked.connect(AddTab)
desktopIconTabDel.clicked.connect(DelTab)
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", "要显示的 .desktop 文件的名称(※必填):")), 9, 0, 1, 1)
desktopIconTabLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "要显示的 .desktop 文件的图标(选填)")), 10, 0, 1, 1)
desktopIconTabLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "wine 容器里需要运行的可执行文件路径(※必填):")), 6, 0, 1, 1)
desktopIconTabLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "要显示的 .desktop 文件的分类(※必填):")), 7, 0, 1, 1)
desktopIconTabLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "wine 容器里需要运行的可执行文件的参数:")), 8, 0, 1, 1)
desktopIconTabLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "要显示的 .desktop 文件的名称(※必填):")), 9, 0, 1, 1)
desktopIconTabLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "要显示的 .desktop 文件的图标:")), 10, 0, 1, 1)
iconTab1.setLayout(desktopIconTabLayout)
#desktopIconTab.setTabPosition(QtWidgets.QTabWidget.East)
desktopIconTab.addTab(iconTab1, "Defult")
desktopIconTab.setCornerWidget(controlWidget)
widgetLayout.addWidget(desktopIconTab, 8, 0, 6, 3)
widgetLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "选择打包的 wine 版本(※必选):")), 6, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "打包 deb 的保存路径(※必填):")), 7, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "选择打包的 wine 版本(※必选):")), 6, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "打包 deb 的保存路径(※必填):")), 7, 0, 1, 1)
widgetLayout.addWidget(e1_text, 0, 1, 1, 1)
widgetLayout.addWidget(e2_text, 1, 1, 1, 1)
widgetLayout.addWidget(e3_text, 2, 1, 1, 1)
@@ -1874,30 +1962,30 @@ widgetLayout.addLayout(debControlFrame, 16, 1, 1, 1)
widgetLayout.addWidget(label13_text, 17, 0, 1, 3)
widgetLayout.addWidget(textbox1, 18, 0, 1, 3)
# 高级功能
moreSetting = QtWidgets.QGroupBox(QtCore.QCoreApplication.translate("U", "高级设置"))
moreSetting = QtWidgets.QGroupBox(transla.transe("U", "高级设置"))
debDepends = QtWidgets.QLineEdit()
debRecommend = QtWidgets.QLineEdit()
debDepends.setPlaceholderText(QtCore.QCoreApplication.translate("U", "deb 包的依赖(如无特殊需求默认即可)"))
debDepends.setPlaceholderText(transla.transe("U", "deb 包的依赖(如无特殊需求默认即可)"))
debDepends.setText("deepin-wine6-stable, deepin-wine-helper (>= 5.1.30-1), fonts-wqy-microhei, fonts-wqy-zenhei")
debRecommend.setPlaceholderText(QtCore.QCoreApplication.translate("U", "deb 包的推荐依赖(非强制,一般默认即可)"))
debRecommend.setPlaceholderText(transla.transe("U", "deb 包的推荐依赖(非强制,一般默认即可)"))
moreSettingLayout = QtWidgets.QVBoxLayout()
localWineVersion = QtWidgets.QComboBox()
useInstallWineArch = QtWidgets.QComboBox()
useInstallWineArch.addItems(["wine", "wine64"])
moreSettingLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "Wine 位数(只限本地需要打包集成的Wine)\n提示32位的Wine不能使用64位容器")))
moreSettingLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "Wine 位数(只限本地需要打包集成的Wine)\n提示32位的Wine不能使用64位容器")))
#moreSettingLayout.addWidget(localWineVersion)
moreSettingLayout.addWidget(useInstallWineArch)
moreSettingLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "deb 包选项:")))
moreSettingLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "deb 包选项:")))
moreSettingLayout.addWidget(rmBash)
moreSettingLayout.addWidget(cleanBottonByUOS)
moreSettingLayout.addWidget(chooseWineHelperValue)
moreSettingLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "deb 的依赖(强制,如无特殊需求默认即可)")))
moreSettingLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "deb 的依赖(强制,如无特殊需求默认即可)")))
moreSettingLayout.addWidget(debDepends)
moreSettingLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "deb 的推荐依赖(非强制,一般默认即可)")))
moreSettingLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "deb 的推荐依赖(非强制,一般默认即可)")))
moreSettingLayout.addWidget(debRecommend)
moreSettingLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "要显示的 .desktop 文件的 MimeType")))
moreSettingLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "要显示的 .desktop 文件的 MimeType")))
moreSettingLayout.addWidget(e10_text)
moreSettingLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "打包 deb 架构:")))
moreSettingLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "打包 deb 架构:")))
moreSettingLayout.addWidget(debArch)
moreSetting.setLayout(moreSettingLayout)
widgetLayout.addWidget(moreSetting, 0, 3, 16, 2)
@@ -1911,22 +1999,27 @@ 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(transla.transe("U", "支持 png 和 svg 格式,不支持 ico 格式"))
# 菜单栏
menu = window.menuBar()
programmenu = menu.addMenu(QtCore.QCoreApplication.translate("U", "程序"))
debMenu = menu.addMenu(QtCore.QCoreApplication.translate("U", "deb 包"))
uploadSparkStore = menu.addMenu(QtCore.QCoreApplication.translate("U", "投稿到星火应用商店"))
help = menu.addMenu(QtCore.QCoreApplication.translate("U", "帮助"))
exit = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "退出程序"))
debE = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "只读取 Control 信息"))
debX = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "读取所有(需解包,时间较久)"))
uploadSparkStoreWebsize = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "从网页端投稿"))
programmenu = menu.addMenu(transla.transe("U", "程序"))
debMenu = menu.addMenu(transla.transe("U", "deb 包"))
uploadSparkStore = menu.addMenu(transla.transe("U", "投稿到星火应用商店"))
help = menu.addMenu(transla.transe("U", "帮助"))
exit = QtWidgets.QAction(transla.transe("U", "退出程序"))
debE = QtWidgets.QAction(transla.transe("U", "只读取 Control 信息"))
debX = QtWidgets.QAction(transla.transe("U", "读取所有(需解包,时间较久)"))
uploadSparkStoreWebsize = QtWidgets.QAction(transla.transe("U", "从网页端投稿"))
if os.path.exists("/opt/spark-store-submitter/bin/spark-store-submitter"):
uploadSparkStoreProgram = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "使用投稿器投稿(推荐)"))
uploadSparkStoreProgram = QtWidgets.QAction(transla.transe("U", "使用投稿器投稿(推荐)"))
else:
uploadSparkStoreProgram = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "使用投稿器投稿(推荐,请先安装投稿器)"))
uploadSparkStoreProgram = QtWidgets.QAction(transla.transe("U", "使用投稿器投稿(推荐,请先安装投稿器)"))
uploadSparkStoreProgram.setDisabled(True)
tip = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "小提示"))
tip = QtWidgets.QAction(transla.transe("U", "小提示"))
getPdfHelp = QtWidgets.QAction(transla.transe("U", "Wine运行器和Wine打包器傻瓜式使用教程小白专用\nBy @雁舞白沙"))
exit.triggered.connect(window.close)
tip.triggered.connect(helps)
programmenu.addAction(exit)
@@ -1938,7 +2031,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://bbs.deepin.org/post/246837"))
help.addAction(tip)
help.addAction(getPdfHelp)
# 控件配置
try:
e6_text.setText(sys.argv[1].replace("~", get_home()))
@@ -1955,6 +2050,44 @@ window.setCentralWidget(widget)
window.setWindowTitle(f"wine 应用打包器 {version}")
window.setWindowIcon(QtGui.QIcon(iconPath))
window.resize(int(window.frameSize().width() * 2.1), int(window.frameSize().height()))
e1_text.setWhatsThis("""com.XXX.deepin
XXX指windows软件的英文名称可以自定义名称但最好是用软件解压安装后自动生成的英文名称dingtalk。包名只能含有小写字母a-z、数字0-9、加号+)和减号(-)、以及点号(.),软件包名最短长度为两个字符,且包名必须以字母开头。""")
# 创建控件
e2_text.setWhatsThis(transla.transe("U", """6.5.50随便填写或填写该软件的windows版本的版本号6.5.50只是示例)。"""))
e3_text.setWhatsThis(transla.transe("U", """随便填写或使用该软件的windows版本的软件简介。"""))
e4_text.setWhatsThis(transla.transe("U", """填写自己的网名,若是自用软件,不上架至应用商店,不进行后续维护,可随便填写。"""))
e5_text.setWhatsThis(f"<p>解压容器到其它机器的容器名称,一般自动带出</p><p><img src='{programPath}/Icon/Screen/202211121646232464_image.png'></p>")
e6_text.setWhatsThis(transla.transe("U", f"要打包的容器所在路径,也可以选择已经好打包的 7z 文件,一般自动带出"))
e7_text.setWhatsThis("""可执行文件的运行路径格式是“C:/XXX/XXX.exe”不包含引号""")
debArch.setWhatsThis(transla.transe("U", "选择生成 deb 包所对应的架构"))
rmBash.setWhatsThis(transla.transe("U", "清理容器无用内容,一般建议勾选,最新版本默认勾选,如果有特殊需求(如容器内有 mono、gecko 等)建议取消勾选"))
debDepends.setWhatsThis(transla.transe("U", "生成 deb 包所需的依赖,一般情况下默认即可"))
debRecommend.setWhatsThis(transla.transe("U", "生成 deb 包的推荐依赖,一般情况下为空即可"))
cleanBottonByUOS.setWhatsThis(transla.transe("U", "清理容器无用内容,一般建议勾选,最新版本默认勾选,如果有特殊需求(如容器内有 mono、gecko 等)建议取消勾选"))
chooseWineHelperValue.setWhatsThis(transla.transe("U", "使用星火 dwine helper 替换 Deepin Wine Helper投稿星火应用商店的话建议勾选最新版本默认勾选如果打包 arm 包将不会提供选择)"))
option1_text.setWhatsThis("""点击右侧的下拉箭头,选择该软件所属的软件分类即可,常见软件分类名称释义:
Network=网络应用;
Chat=即时通讯或社交沟通;
Video=视频播放;
Graphics=图形图像;
Office=办公学习;
Translation=阅读翻译;
Development=软件开发;
Utility=工具软件或其他应用。
不明白英文的可以百度查询一下软件分类名称的意思。
注意:此时选择的软件分类名称决定了该软件打包后再安装时会安装在启动器中的哪个软件分类目录中。""")
e8_text.setWhatsThis(transla.transe("U", """填写该软件的中文或英文名称。"""))
e9_text.setWhatsThis(transla.transe("U", """图标只支持PNG格式和SVG格式其他格式无法显示。"""))
e10_text.setWhatsThis(transla.transe("U", "快捷方式的 MimeType 项,一般为空即可"))
option1_text.setWhatsThis(transla.transe("U", "打包的 Wine 版本,根据实际情况选择(如果打包 arm 包将不会提供选择)"))
e12_text.setWhatsThis(transla.transe("U", "打包出的 deb 生成的位置,一般自动生成"))
e15_text.setWhatsThis(transla.transe("U", "程序参数,如%u,一般不需要"))
build7z.setWhatsThis(transla.transe("U", "只打包容器生成 7z 包,不做其它操作"))
buildDebDir.setWhatsThis(transla.transe("U", "构建 deb 包目录,但不打包成 deb"))
textbox1.setWhatsThis(transla.transe("U", "查看打包过程中命令返回内容"))
button5.setWhatsThis(transla.transe("U", "点击该按钮打包生成 deb"))
installDeb.setWhatsThis(transla.transe("U", "调用默认的 deb 安装工具安装生成的 deb"))
#window.setWindowFlag(QtGui.Qt)
window.show()
sys.exit(app.exec_())
# Flag解包只读control和解包全部读取

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,16 @@
{
"Version": "2.5.0",
"Version": "3.0.0",
"Thank": [
"感谢 @豪 提供程序图标",
"感谢 @鹤舞白沙 对程序文案进行优化以及编写《Wine运行器和Wine打包器傻瓜式使用教程小白专用 》",
"感谢 @璀璨星空 提供的彩蛋图标",
"感谢 @Bail 反馈的更新策略问题",
"感谢 @白水 反馈的安装 exagear 后无法识别和调用 box86 的问题",
"感谢 @汐光. 提供的翻译接口",
"感谢 @鹤舞白沙 专门为小白用户编写的使用 Wine 运行器非基于生态适配脚本的程序打包教程",
"感谢 @牦牛儿苗 进行了龙芯 3a5000 平台的测试与移植",
"感谢 @雁舞白沙 优化了程序文案",
"感谢 @豪 的程序测试和制作的非官方论坛 https://gfdgdxi.flarum.cloud/",
"感谢 @豪 的程序测试和制作的论坛 https://gfdgdxi.flarum.cloud/",
"感谢 @185******67 反馈的 2.4.0 无法打开 Visual Basic 组件安装工具的问题",
"感谢 @shenmo 提供的 在打包器的 postrm 脚本添加 kill.sh、追加参数改为 --uri xxxxxxx、独立生成容器 7z 文件的功能",
"感谢 @a2035274 @虚幻的早晨 https://bbs.deepin.org/post/238301",

View File

@@ -7,32 +7,21 @@ with open("/var/lib/dpkg/status", "r") as i:
if unConnect:
print("52专版将会无法连接服务器")
badUrl = [
"http://120.25.153.144",
"https://304626p927.goho.co",
"https://30x46269h2.goho.co",
"http://gfdgdxi.msns.cn"
]
class Respon:
text = ""
def get(url, timeout=None): # -> requests.Response:
if unConnect:
# 筛选 Url,只有特定的 url 才会被拦截
for i in badUrl:
if i in url:
raise Exception("52专版不支持连接作者服务器")
# 全部 Url拦截
raise Exception("52专版不支持连接服务器")
if timeout == None:
return requests.get(url)
return requests.get(url, timeout=timeout)
def post(url, data, timeout=None):
if unConnect:
# 筛选 Url,只有特定的 url 才会被拦截
for i in badUrl:
if i in url:
raise Exception("52专版不支持连接作者服务器")
# 全部 Url拦截
raise Exception("52专版不支持连接服务器")
if timeout == None:
return requests.post(url, data)
return requests.post(url, data, timeout=timeout)

View File

@@ -0,0 +1,53 @@
#!/usr/bin/env python3
import os
import json
import requests
import traceback
class Trans():
isTrans = False
unCloudTrans = True
word = {}
fileName = ""
def __init__(self, lang="zh_CN", fileName=f"trans.json") -> None:
self.fileName = fileName
self.isTrans = (lang != "zh_CN")
if self.isTrans:
try:
if not os.path.exists(fileName):
with open(fileName, "w") as file:
file.write("{}")
with open(fileName, "r") as file:
self.word = json.loads(file.read())
except:
traceback.print_exc()
self.isTrans = False
def transe(self, temp, text) -> str:
if not self.isTrans:
return text
try:
return self.word[text].replace("", "(").replace("", ")")
except:
if self.unCloudTrans:
return text
# 机翻
data = { 'doctype': 'json', 'type': 'auto','i': text}
jsonReturn = requests.post("http://fanyi.youdao.com/translate", data=data).json()["translateResult"]
transText = ""
for i in jsonReturn:
print(i[0])
transText += f'{i[0]["tgt"]}\n'
if "\n" in text:
transText = transText.replace("\n\n", "\n")[:-1]
else:
transText = transText[:-1]
self.word[text] = transText.replace("", "(").replace("", ")")
try:
with open(self.fileName, "w") as file:
file.write(json.dumps(self.word, ensure_ascii=False))
except:
traceback.print_exc()
print(f"{text}=>{transText}")
return transText

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
{"更换源": "Change the source", "Gitlink 源(推荐)": "Gitlink source (recommended)", "备用源(只支持 IPv6 用户)": "The alternate source (only support IPv6 users)", "本地测试源127.0.0.1": "Local test source (127.0.0.1)", "使用前须知:\n1、Qemu 跨架构效率较低,如果有条件建议优先使用 box86、exagear 等效率较高的转换层;\n2、使用此方案需要使用到 Root 权限(需开启管理员模式)并安装 qemu-user-static\n3、chroot 时候可能会出现问题导致程序闪退或异常,出现该问题重启电脑即可;\n4、在此环境使用 Wine 时,只能读取到您用户目录或本程序文件夹下的文件,其它路径无法读取;\n5、移除容器时请保证在这次打开电脑时没有调用过需要删除容器如果有调用过建议重启电脑后再移除\n6、暂时属于测试功能": "Instructions before use:\n1, Qemu across architecture efficiency is low, if there is condition is preferred to use box86, exagear high efficiency transformation layer;\n2, use this program to need to use the Root administrator mode (open) and install qemu - user - static;\n3, when chroot flash back problems may cause the program or abnormal, the problems to restart the computer;\n4, in this environment using Wine, can only read your user directory or folder of the program files, other path cannot read;\n5, remove the container please make sure that no calls while in the open a computer need to delete the container, if there is a call after advice to restart the computer to remove;\n6, a temporary belong to test functionality;"}

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1 @@
/opt/apps/deepin-wine-runner/deepin-wine-easy-packager.py

View File

@@ -0,0 +1,12 @@
[Desktop Entry]
Type=Application
X-Categories=System;Wine;
Exec=/usr/bin/deepin-wine-packager-easy-builder %F
Icon=/opt/apps/deepin-wine-runner/deepin-wine-runner.svg
Name=Wine Package Builder
Name[zh]=Wine 简易打包器
Terminal=false
StartupNotify=true
NoDisplay=true
Keywords=exe;scr;
MimeType=application/x-ms-dos-executable;application/x-msi;application/x-ms-shortcut;

78
deepin-wine-easy-packager.py Normal file → Executable file
View File

@@ -1,3 +1,4 @@
#!/usr/bin/env python3
import os
import sys
import json
@@ -344,6 +345,15 @@ def UnUseUpperCharPath(path: str):
raise OSError("文件路径不存在")
return "/" + "/".join(pathList)
def ReadMe():
QtWidgets.QMessageBox.information(window, "提示", """1、目前只支持打包 X86 架构的 deb 包,暂未支持 arm
2、需要区分要打包的程序是绿色软件还是单文件安装包两个对应的打包方式不相同
3、打包绿色软件时为尽可能减小程序体积请将绿化后的程序或程序文件夹单独拷贝到干净的目录后再浏览选择主程序打包
4、打包详情
①调用 WineDeepin Wine6 Stable
②调用 HelperSpark Wine Helper
③有卸载自动移除容器脚本""")
class RunThread(QtCore.QThread):
showLogText = QtCore.pyqtSignal(str)
@@ -399,17 +409,21 @@ class RunThread(QtCore.QThread):
############# 后面将全部调用 deepin wine6 stable 进行操作
exeName = os.path.basename(exePath.text())
# 暂定
debPackageName = "spark-" + xpinyin.Pinyin().get_pinyin(os.path.splitext(exeName)[0].replace(" ", "")).lower().replace("--", "-").replace(" ", "")
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()
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/'")
############## 运行 EXE
if self.QuestionMsg("请问此可执行文件是安装包还是绿色软件?是安装包请按 Yes绿色软件按 No"):
# 清空无益处的 lnk 文件
@@ -420,6 +434,7 @@ class RunThread(QtCore.QThread):
# 禁止生成 .desktop 文件
self.RunCommand(f"WINEPREFIX='{bottlePath}' deepin-wine6-stable 'reg' 'add' 'HKEY_CURRENT_USER\Software\Wine\DllOverrides' /v winemenubuilder.exe '/f'")
# 安装包
self.info.emit("请在运行完安装程序后按下打包器主界面的“安装程序执行完成按钮”以进行下一步操作")
global pressCompleteDownload
pressCompleteDownload = False
installCmpleteButton.setEnabled(True)
@@ -434,13 +449,16 @@ class RunThread(QtCore.QThread):
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()
if "卸载" in lnkPath or "uninstall" in lnkPath or "update" in lnkPath or "网页" in lnkPath or "websize" in lnkPath:
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:
@@ -452,16 +470,21 @@ class RunThread(QtCore.QThread):
if len(k[1]) < miniLenge:
rightLnk = k
miniLenge = len(rightLnk[1])
debPackageName = "com." + xpinyin.Pinyin().get_pinyin(os.path.splitext(os.path.basename(rightLnk[0]))[0].replace(" ", "")).lower().replace("--", "-").replace(" ", "").replace("_", "-").replace("-", ".") + ".spark"
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(exePathInBottle)
debPackageVersion = self.GetEXEVersion(exePathInSystem)
cpNow = False
for i in iconList:
path = i.replace("wineBottonPath", bottlePath).lower()
path = i[1].replace("wineBottonPath", bottlePath).lower()
if path == exePathInSystem.lower():
self.RunCommand(f"cp -rv '{UnUseUpperCharPath(path)}' '{debBuildPath}/{programIconPath}'")
self.RunCommand(f"cp -rv '{programPath}/Icon/{i[0]}.svg' '{debBuildPath}/{programIconPath}'")
exeName = i[0]
cpNow = True
break
if not cpNow:
@@ -475,12 +498,17 @@ class RunThread(QtCore.QThread):
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"'{programPath}/wrestool' '{exePathInBottle}' -x -t 14 > '{debBuildPath}/{programIconPath}'")
debPackageVersion = self.GetEXEVersion(exePathInBottle)
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'")
debDescription = f"{exeName} By Deepin Wine 6 Stable And Build By Wine Runner"
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)
@@ -501,7 +529,7 @@ class RunThread(QtCore.QThread):
########### 打包容器
self.RunCommand(f"7z a '{bottlePackagePath}' '{bottlePath}/'*")
########### 生成文件内容
buildProgramSize = getFileFolderSize(debBuildPath)
buildProgramSize = getFileFolderSize(debBuildPath) / 1000
replaceMap = [
["@@@Package@@@", debPackageName],
["@@@Version@@@", debPackageVersion],
@@ -535,11 +563,11 @@ class RunThread(QtCore.QThread):
self.info.emit("打包完成!")
self.disbledAll.emit(False)
########### 移除临时文件
#self.RunCommand(f"rm -rfv '{debBuildPath}' > /dev/null")
#self.RunCommand(f"rm -rfv '{bottlePath}' > /dev/null")
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")
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()}")
@@ -556,6 +584,7 @@ def RunBuildThread():
buildThread.question.connect(QuestionMessage)
buildThread.disbledAll.connect(DisbledAndEnabledAll)
buildThread.cleanPressState.connect(CleanPressCompleteDownloadState)
logText.clear()
buildThread.start()
pressCompleteDownload = False
@@ -593,12 +622,15 @@ if __name__ == "__main__":
controlLayout = QtWidgets.QHBoxLayout()
buildButton = QtWidgets.QPushButton("现在打包……")
installCmpleteButton = QtWidgets.QPushButton("安装程序执行完成")
helpButton = QtWidgets.QPushButton("帮助")
browserExeButton.clicked.connect(BrowserExe)
buildButton.clicked.connect(RunBuildThread)
installCmpleteButton.clicked.connect(PressCompleteDownload)
helpButton.clicked.connect(ReadMe)
installCmpleteButton.setDisabled(True)
controlLayout.addWidget(buildButton)
controlLayout.addWidget(installCmpleteButton)
controlLayout.addWidget(helpButton)
layout.addWidget(QtWidgets.QLabel("选择 EXE"), 0, 0)
layout.addWidget(exePath, 0, 1)
layout.addWidget(browserExeButton, 0, 2)
@@ -607,10 +639,10 @@ if __name__ == "__main__":
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_())
# ./wrestool ../Desktop/deep-wine-runner/geek.exe -x -t 14 > a.png
# Flag
# 1、不想打包了强制终止功能
# 2、版本号自动识别
# 3、包名自动识别
sys.exit(app.exec_())

View File

@@ -23,23 +23,24 @@ from PIL import Image
import PyQt5.QtGui as QtGui
import PyQt5.QtCore as QtCore
import PyQt5.QtWidgets as QtWidgets
from trans import *
#################
# 程序所需事件
#################
def button1_cl():
path = QtWidgets.QFileDialog.getExistingDirectory(widget, QtCore.QCoreApplication.translate("U", "选择 wine 容器"), f"{get_home()}/.deepinwine")
path = QtWidgets.QFileDialog.getExistingDirectory(widget, transla.transe("U", "选择 wine 容器"), f"{get_home()}/.deepinwine")
if path != "":
e6_text.setText(path)
def button2_cl(number):
path = QtWidgets.QFileDialog.getOpenFileName(widget, QtCore.QCoreApplication.translate("U", "选择图标文件"), get_home(), "PNG图标(*.png);;SVG图标(*.svg);;全部文件(*.*)")[0]
path = QtWidgets.QFileDialog.getOpenFileName(widget, transla.transe("U", "选择图标文件"), get_home(), "PNG图标(*.png);;SVG图标(*.svg);;全部文件(*.*)")[0]
if path != "":
mapLink[number].setText(path)
def button4_cl():
path = QtWidgets.QFileDialog.getSaveFileName(widget, QtCore.QCoreApplication.translate("U", "保存 deb 包"), get_home(), "deb 文件(*.deb);;所有文件(*.*)", "{}_{}_i386.deb".format(e1_text.text(), e2_text.text()))[0]
path = QtWidgets.QFileDialog.getSaveFileName(widget, transla.transe("U", "保存 deb 包"), get_home(), "deb 文件(*.deb);;所有文件(*.*)", "{}_{}_i386.deb".format(e1_text.text(), e2_text.text()))[0]
if path != "":
e12_text.setText(path)
@@ -237,7 +238,7 @@ def make_deb(build=False):
disabled_or_NORMAL_all(True)
label13_text_change("必填信息没有填写完整,无法继续构建 deb 包")
return
if QtWidgets.QMessageBox.question(widget, QtCore.QCoreApplication.translate("U", "提示"), QtCore.QCoreApplication.translate("U", "打包将会改动现在选择的容器,是否继续?")) == QtWidgets.QMessageBox.No:
if QtWidgets.QMessageBox.question(widget, transla.transe("U", "提示"), transla.transe("U", "打包将会改动现在选择的容器,是否继续?")) == QtWidgets.QMessageBox.No:
disabled_or_NORMAL_all(True)
return
# 警告信息
@@ -1231,7 +1232,7 @@ fi
# 获取文件大小
################
self.label.emit("正在计算文件大小……")
size = int(getFileFolderSize(debPackagePath) / 1024)
size = int(getFileFolderSize(debPackagePath) / 1000)
################
# 写入文本文档
################
@@ -1722,7 +1723,7 @@ mapLink = []
def AddTab():
global mapLink
button2 = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "浏览……"))
button2 = QtWidgets.QPushButton(transla.transe("U", "浏览……"))
e7_text = QtWidgets.QLineEdit()
e8_text = QtWidgets.QLineEdit()
e9_text = QtWidgets.QLineEdit()
@@ -1736,11 +1737,11 @@ def AddTab():
mapLink.append(e9_text)
#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", "要显示的 .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", "要显示的 .desktop 文件的名称(※必填):")), 9, 0, 1, 1)
desktopIconTabLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "要显示的 .desktop 文件的图标:")), 10, 0, 1, 1)
desktopIconTabLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "wine 容器里需要运行的可执行文件路径(※必填):")), 6, 0, 1, 1)
desktopIconTabLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "要显示的 .desktop 文件的分类(※必填):")), 7, 0, 1, 1)
desktopIconTabLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "wine 容器里需要运行的可执行文件的参数:")), 8, 0, 1, 1)
desktopIconTabLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "要显示的 .desktop 文件的名称(※必填):")), 9, 0, 1, 1)
desktopIconTabLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "要显示的 .desktop 文件的图标:")), 10, 0, 1, 1)
iconTab1.setLayout(desktopIconTabLayout)
desktopIconTab.addTab(iconTab1, f"图标{desktopIconTab.count() + 1}")
desktopIconTabLayout.addWidget(e7_text, 6, 1, 1, 1)
@@ -1749,9 +1750,24 @@ def AddTab():
desktopIconTabLayout.addWidget(e8_text, 9, 1, 1, 1)
desktopIconTabLayout.addWidget(e9_text, 10, 1, 1, 1)
desktopIconTabLayout.addWidget(button2, 10, 2, 1, 1)
e8_text.setWhatsThis(transla.transe("U", """填写该软件的中文或英文名称。"""))
e9_text.setWhatsThis(transla.transe("U", """图标只支持PNG格式和SVG格式其他格式无法显示。"""))
e15_text.setWhatsThis(transla.transe("U", "程序参数,如%u,一般不需要"))
e7_text.setWhatsThis(transla.transe("U", """可执行文件的运行路径格式是“C:/XXX/XXX.exe”不包含引号"""))
option1_text.setWhatsThis(transla.transe("U", """点击右侧的下拉箭头,选择该软件所属的软件分类即可,常见软件分类名称释义:
Network=网络应用;
Chat=即时通讯或社交沟通;
Video=视频播放;
Graphics=图形图像;
Office=办公学习;
Translation=阅读翻译;
Development=软件开发;
Utility=工具软件或其他应用。
不明白英文的可以百度查询一下软件分类名称的意思。
注意:此时选择的软件分类名称决定了该软件打包后再安装时会安装在启动器中的哪个软件分类目录中。"""))
e7_text.textChanged.connect(ChangeTapTitle)
e7_text.setPlaceholderText("例如 c:/Program Files/Tencent/QQ/Bin/QQ.exe")
e9_text.setPlaceholderText("支持 png 和 svg 格式,不支持 ico 格式")
e9_text.setPlaceholderText(transla.transe("U", "支持 png 和 svg 格式,不支持 ico 格式"))
iconUiList.append([e7_text, option1_text, e15_text, e8_text, e9_text])
print(iconUiList)
@@ -1780,7 +1796,11 @@ def LockBottleName():
if bottleNameChangeLock:
return
bottleNameLock = True
# 获取当前语言
def get_now_lang()->"获取当前语言":
return os.getenv('LANG')
bottleNameLock = False
###############
# 程序信息
@@ -1813,18 +1833,27 @@ iconUiList = []
iconPath = "{}/deepin-wine-runner.svg".format(programPath)
information = json.loads(readtxt(f"{programPath}/information.json"))
version = information["Version"]
tips = """提示:
# 语言载入
if not get_now_lang() == "zh_CN.UTF-8":
#trans = QtCore.QTranslator()
#trans.load(f"{programPath}/LANG/deepin-wine-runner-en_US.qm")
#app.installTranslator(trans)
transla = Trans("en_US", f"{programPath}/trans/deepin-wine-packager.json")
else:
transla = Trans("zh_CN")
tips = transla.transe("U", """提示:
1、deb 打包软件包名要求:
软件包名只能含有小写字母(a-z)、数字(0-9)、加号(+)和减号(-)、以及点号(.),软件包名最短长度两个字符;它必须以字母开头
2、如果要填写路径有“浏览……”按钮的是要填本计算机对应文件的路径否则就是填写安装到其他计算机使用的路径
3、输入 wine 的容器路径时最后面请不要输入“/”
4、输入可执行文件的运行路径时是以“C:/XXX/XXX.exe”的格式进行输入默认是以 C 为开头,不用“\”做命令的分隔,而是用“/”
5、.desktop 的图标只支持 PNG 格式和 SVG 格式,其他格式无法显示图标
6、路径建议不要带空格容易出问题"""
6、路径建议不要带空格容易出问题""")
###############
# 窗口创建
###############
app = QtWidgets.QApplication(sys.argv)
window = QtWidgets.QMainWindow()
widget = QtWidgets.QWidget()
@@ -1847,25 +1876,25 @@ e12_text = QtWidgets.QLineEdit()
e15_text = QtWidgets.QLineEdit()
label13_text = QtWidgets.QLabel("<p align='center'>当前 deb 打包情况:暂未打包</p>")
option1_text = QtWidgets.QComboBox()
button1 = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "浏览……"))
button2 = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "浏览……"))
button4 = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "浏览……"))
button1 = QtWidgets.QPushButton(transla.transe("U", "浏览……"))
button2 = QtWidgets.QPushButton(transla.transe("U", "浏览……"))
button4 = QtWidgets.QPushButton(transla.transe("U", "浏览……"))
debControlFrame = QtWidgets.QHBoxLayout()
button5 = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "打包……"))
installDeb = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "安装打包完成的 deb……"))
buildDebDir = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "根据填写内容打包模板"))
build7z = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "打包容器 7z 包"))
button5 = QtWidgets.QPushButton(transla.transe("U", "打包……"))
installDeb = QtWidgets.QPushButton(transla.transe("U", "安装打包完成的 deb……"))
buildDebDir = QtWidgets.QPushButton(transla.transe("U", "根据填写内容打包模板"))
build7z = QtWidgets.QPushButton(transla.transe("U", "打包容器 7z 包"))
debControlFrame.addWidget(button5)
debControlFrame.addWidget(installDeb)
rmBash = QtWidgets.QCheckBox(QtCore.QCoreApplication.translate("U", "设置卸载该 deb 后自动删除该容器"))
cleanBottonByUOS = QtWidgets.QCheckBox(QtCore.QCoreApplication.translate("U", "使用统信 Wine 生态适配活动容器清理脚本"))
rmBash = QtWidgets.QCheckBox(transla.transe("U", "设置卸载该 deb 后自动删除该容器"))
cleanBottonByUOS = QtWidgets.QCheckBox(transla.transe("U", "使用统信 Wine 生态适配活动容器清理脚本"))
debArch = QtWidgets.QComboBox()
debArch.addItems(["i386", "arm64(box86+exagear)"])
textbox1 = QtWidgets.QTextBrowser()
option1_text.addItems(["Network", "Chat", "Audio", "Video", "Graphics", "Office", "Translation", "Development", "Utility"])
option1_text.setCurrentText("Network")
wineFrame = QtWidgets.QHBoxLayout()
chooseWineHelperValue = QtWidgets.QCheckBox(QtCore.QCoreApplication.translate("U", "使用星火wine helper\n如不勾选默认为deepin-wine-helper"))
chooseWineHelperValue = QtWidgets.QCheckBox(transla.transe("U", "使用星火wine helper\n如不勾选默认为deepin-wine-helper"))
button1.clicked.connect(button1_cl)
button2.clicked.connect(lambda: button2_cl(0))
mapLink.append(e9_text)
@@ -1879,18 +1908,19 @@ 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(transla.transe("U", "要打包的 deb 包的包名(※必填):")), 0, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "deb 包的版本号(※必填):")), 1, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "deb 包的说明(※必填):")), 2, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "deb 包的维护者(※必填):")), 3, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "要解压的 wine 容器的名称(※必填):")), 4, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "打包的 wine 容器路径(※必填):")), 5, 0, 1, 1)
desktopIconTab = QtWidgets.QTabWidget()
controlWidget = QtWidgets.QWidget()
controlWidgetLayout = QtWidgets.QHBoxLayout()
desktopIconTabAdd = QtWidgets.QPushButton("+")
desktopIconTabDel = QtWidgets.QPushButton("-")
desktopIconTabAdd.setWhatsThis("添加新图标")
desktopIconTabDel.setWhatsThis("移除选中图标")
controlWidgetLayout.addWidget(desktopIconTabAdd)
controlWidgetLayout.addWidget(desktopIconTabDel)
controlWidget.setLayout(controlWidgetLayout)
@@ -1898,18 +1928,18 @@ desktopIconTabAdd.clicked.connect(AddTab)
desktopIconTabDel.clicked.connect(DelTab)
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", "要显示的 .desktop 文件的名称(※必填):")), 9, 0, 1, 1)
desktopIconTabLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "要显示的 .desktop 文件的图标:")), 10, 0, 1, 1)
desktopIconTabLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "wine 容器里需要运行的可执行文件路径(※必填):")), 6, 0, 1, 1)
desktopIconTabLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "要显示的 .desktop 文件的分类(※必填):")), 7, 0, 1, 1)
desktopIconTabLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "wine 容器里需要运行的可执行文件的参数:")), 8, 0, 1, 1)
desktopIconTabLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "要显示的 .desktop 文件的名称(※必填):")), 9, 0, 1, 1)
desktopIconTabLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "要显示的 .desktop 文件的图标:")), 10, 0, 1, 1)
iconTab1.setLayout(desktopIconTabLayout)
#desktopIconTab.setTabPosition(QtWidgets.QTabWidget.East)
desktopIconTab.addTab(iconTab1, "Defult")
desktopIconTab.setCornerWidget(controlWidget)
widgetLayout.addWidget(desktopIconTab, 8, 0, 6, 3)
widgetLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "选择打包的 wine 版本(※必选):")), 6, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "打包 deb 的保存路径(※必填):")), 7, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "选择打包的 wine 版本(※必选):")), 6, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "打包 deb 的保存路径(※必填):")), 7, 0, 1, 1)
widgetLayout.addWidget(e1_text, 0, 1, 1, 1)
widgetLayout.addWidget(e2_text, 1, 1, 1, 1)
widgetLayout.addWidget(e3_text, 2, 1, 1, 1)
@@ -1932,30 +1962,30 @@ widgetLayout.addLayout(debControlFrame, 16, 1, 1, 1)
widgetLayout.addWidget(label13_text, 17, 0, 1, 3)
widgetLayout.addWidget(textbox1, 18, 0, 1, 3)
# 高级功能
moreSetting = QtWidgets.QGroupBox(QtCore.QCoreApplication.translate("U", "高级设置"))
moreSetting = QtWidgets.QGroupBox(transla.transe("U", "高级设置"))
debDepends = QtWidgets.QLineEdit()
debRecommend = QtWidgets.QLineEdit()
debDepends.setPlaceholderText(QtCore.QCoreApplication.translate("U", "deb 包的依赖(如无特殊需求默认即可)"))
debDepends.setPlaceholderText(transla.transe("U", "deb 包的依赖(如无特殊需求默认即可)"))
debDepends.setText("deepin-wine6-stable, deepin-wine-helper (>= 5.1.30-1), fonts-wqy-microhei, fonts-wqy-zenhei")
debRecommend.setPlaceholderText(QtCore.QCoreApplication.translate("U", "deb 包的推荐依赖(非强制,一般默认即可)"))
debRecommend.setPlaceholderText(transla.transe("U", "deb 包的推荐依赖(非强制,一般默认即可)"))
moreSettingLayout = QtWidgets.QVBoxLayout()
localWineVersion = QtWidgets.QComboBox()
useInstallWineArch = QtWidgets.QComboBox()
useInstallWineArch.addItems(["wine", "wine64"])
moreSettingLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "Wine 位数(只限本地需要打包集成的Wine)\n提示32位的Wine不能使用64位容器")))
moreSettingLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "Wine 位数(只限本地需要打包集成的Wine)\n提示32位的Wine不能使用64位容器")))
#moreSettingLayout.addWidget(localWineVersion)
moreSettingLayout.addWidget(useInstallWineArch)
moreSettingLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "deb 包选项:")))
moreSettingLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "deb 包选项:")))
moreSettingLayout.addWidget(rmBash)
moreSettingLayout.addWidget(cleanBottonByUOS)
moreSettingLayout.addWidget(chooseWineHelperValue)
moreSettingLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "deb 的依赖(强制,如无特殊需求默认即可)")))
moreSettingLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "deb 的依赖(强制,如无特殊需求默认即可)")))
moreSettingLayout.addWidget(debDepends)
moreSettingLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "deb 的推荐依赖(非强制,一般默认即可)")))
moreSettingLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "deb 的推荐依赖(非强制,一般默认即可)")))
moreSettingLayout.addWidget(debRecommend)
moreSettingLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "要显示的 .desktop 文件的 MimeType")))
moreSettingLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "要显示的 .desktop 文件的 MimeType")))
moreSettingLayout.addWidget(e10_text)
moreSettingLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "打包 deb 架构:")))
moreSettingLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "打包 deb 架构:")))
moreSettingLayout.addWidget(debArch)
moreSetting.setLayout(moreSettingLayout)
widgetLayout.addWidget(moreSetting, 0, 3, 16, 2)
@@ -1972,24 +2002,24 @@ 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 格式")
e9_text.setPlaceholderText(transla.transe("U", "支持 png 和 svg 格式,不支持 ico 格式"))
# 菜单栏
menu = window.menuBar()
programmenu = menu.addMenu(QtCore.QCoreApplication.translate("U", "程序"))
debMenu = menu.addMenu(QtCore.QCoreApplication.translate("U", "deb 包"))
uploadSparkStore = menu.addMenu(QtCore.QCoreApplication.translate("U", "投稿到星火应用商店"))
help = menu.addMenu(QtCore.QCoreApplication.translate("U", "帮助"))
exit = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "退出程序"))
debE = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "只读取 Control 信息"))
debX = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "读取所有(需解包,时间较久)"))
uploadSparkStoreWebsize = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "从网页端投稿"))
programmenu = menu.addMenu(transla.transe("U", "程序"))
debMenu = menu.addMenu(transla.transe("U", "deb 包"))
uploadSparkStore = menu.addMenu(transla.transe("U", "投稿到星火应用商店"))
help = menu.addMenu(transla.transe("U", "帮助"))
exit = QtWidgets.QAction(transla.transe("U", "退出程序"))
debE = QtWidgets.QAction(transla.transe("U", "只读取 Control 信息"))
debX = QtWidgets.QAction(transla.transe("U", "读取所有(需解包,时间较久)"))
uploadSparkStoreWebsize = QtWidgets.QAction(transla.transe("U", "从网页端投稿"))
if os.path.exists("/opt/spark-store-submitter/bin/spark-store-submitter"):
uploadSparkStoreProgram = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "使用投稿器投稿(推荐)"))
uploadSparkStoreProgram = QtWidgets.QAction(transla.transe("U", "使用投稿器投稿(推荐)"))
else:
uploadSparkStoreProgram = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "使用投稿器投稿(推荐,请先安装投稿器)"))
uploadSparkStoreProgram = QtWidgets.QAction(transla.transe("U", "使用投稿器投稿(推荐,请先安装投稿器)"))
uploadSparkStoreProgram.setDisabled(True)
tip = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "小提示"))
getPdfHelp = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "Wine 运行器和 Wine 打包器傻瓜式使用教程(小白专用)\nBy @雁舞白沙"))
tip = QtWidgets.QAction(transla.transe("U", "小提示"))
getPdfHelp = QtWidgets.QAction(transla.transe("U", "Wine运行器和Wine打包器傻瓜式使用教程小白专用\nBy @雁舞白沙"))
exit.triggered.connect(window.close)
tip.triggered.connect(helps)
programmenu.addAction(exit)
@@ -2001,7 +2031,7 @@ 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"))
getPdfHelp.triggered.connect(lambda: webbrowser.open_new_tab("https://bbs.deepin.org/post/246837"))
help.addAction(tip)
help.addAction(getPdfHelp)
# 控件配置
@@ -2020,6 +2050,44 @@ window.setCentralWidget(widget)
window.setWindowTitle(f"wine 应用打包器 {version}")
window.setWindowIcon(QtGui.QIcon(iconPath))
window.resize(int(window.frameSize().width() * 2.1), int(window.frameSize().height()))
e1_text.setWhatsThis("""com.XXX.deepin
XXX指windows软件的英文名称可以自定义名称但最好是用软件解压安装后自动生成的英文名称dingtalk。包名只能含有小写字母a-z、数字0-9、加号+)和减号(-)、以及点号(.),软件包名最短长度为两个字符,且包名必须以字母开头。""")
# 创建控件
e2_text.setWhatsThis(transla.transe("U", """6.5.50随便填写或填写该软件的windows版本的版本号6.5.50只是示例)。"""))
e3_text.setWhatsThis(transla.transe("U", """随便填写或使用该软件的windows版本的软件简介。"""))
e4_text.setWhatsThis(transla.transe("U", """填写自己的网名,若是自用软件,不上架至应用商店,不进行后续维护,可随便填写。"""))
e5_text.setWhatsThis(f"<p>解压容器到其它机器的容器名称,一般自动带出</p><p><img src='{programPath}/Icon/Screen/202211121646232464_image.png'></p>")
e6_text.setWhatsThis(transla.transe("U", f"要打包的容器所在路径,也可以选择已经好打包的 7z 文件,一般自动带出"))
e7_text.setWhatsThis("""可执行文件的运行路径格式是“C:/XXX/XXX.exe”不包含引号""")
debArch.setWhatsThis(transla.transe("U", "选择生成 deb 包所对应的架构"))
rmBash.setWhatsThis(transla.transe("U", "清理容器无用内容,一般建议勾选,最新版本默认勾选,如果有特殊需求(如容器内有 mono、gecko 等)建议取消勾选"))
debDepends.setWhatsThis(transla.transe("U", "生成 deb 包所需的依赖,一般情况下默认即可"))
debRecommend.setWhatsThis(transla.transe("U", "生成 deb 包的推荐依赖,一般情况下为空即可"))
cleanBottonByUOS.setWhatsThis(transla.transe("U", "清理容器无用内容,一般建议勾选,最新版本默认勾选,如果有特殊需求(如容器内有 mono、gecko 等)建议取消勾选"))
chooseWineHelperValue.setWhatsThis(transla.transe("U", "使用星火 dwine helper 替换 Deepin Wine Helper投稿星火应用商店的话建议勾选最新版本默认勾选如果打包 arm 包将不会提供选择)"))
option1_text.setWhatsThis("""点击右侧的下拉箭头,选择该软件所属的软件分类即可,常见软件分类名称释义:
Network=网络应用;
Chat=即时通讯或社交沟通;
Video=视频播放;
Graphics=图形图像;
Office=办公学习;
Translation=阅读翻译;
Development=软件开发;
Utility=工具软件或其他应用。
不明白英文的可以百度查询一下软件分类名称的意思。
注意:此时选择的软件分类名称决定了该软件打包后再安装时会安装在启动器中的哪个软件分类目录中。""")
e8_text.setWhatsThis(transla.transe("U", """填写该软件的中文或英文名称。"""))
e9_text.setWhatsThis(transla.transe("U", """图标只支持PNG格式和SVG格式其他格式无法显示。"""))
e10_text.setWhatsThis(transla.transe("U", "快捷方式的 MimeType 项,一般为空即可"))
option1_text.setWhatsThis(transla.transe("U", "打包的 Wine 版本,根据实际情况选择(如果打包 arm 包将不会提供选择)"))
e12_text.setWhatsThis(transla.transe("U", "打包出的 deb 生成的位置,一般自动生成"))
e15_text.setWhatsThis(transla.transe("U", "程序参数,如%u,一般不需要"))
build7z.setWhatsThis(transla.transe("U", "只打包容器生成 7z 包,不做其它操作"))
buildDebDir.setWhatsThis(transla.transe("U", "构建 deb 包目录,但不打包成 deb"))
textbox1.setWhatsThis(transla.transe("U", "查看打包过程中命令返回内容"))
button5.setWhatsThis(transla.transe("U", "点击该按钮打包生成 deb"))
installDeb.setWhatsThis(transla.transe("U", "调用默认的 deb 安装工具安装生成的 deb"))
#window.setWindowFlag(QtGui.Qt)
window.show()
sys.exit(app.exec_())
# Flag解包只读control和解包全部读取

7
demo/APICheck/main.cpp Normal file
View File

@@ -0,0 +1,7 @@
#include <iostream>
#include <Windows.h>
using namespace std;
int main(){
MessageBox(NULL, TEXT("a"), TEXT("A"), 32);
return 0;
}

BIN
demo/APICheck/main.exe Executable file

Binary file not shown.

0
dlls-arm.7z Normal file → Executable file
View File

BIN
dxvk.7z Executable file → Normal file

Binary file not shown.

0
geek.exe Normal file → Executable file
View File

View File

@@ -1,10 +1,16 @@
{
"Version": "2.5.0",
"Version": "3.0.0",
"Thank": [
"感谢 @雁舞白沙 专门为小白用户编写的使用 Wine 运行器非基于生态适配脚本的程序打包教程",
"感谢 @豪 提供程序图标",
"感谢 @鹤舞白沙 对程序文案进行优化以及编写《Wine运行器和Wine打包器傻瓜式使用教程小白专用 》",
"感谢 @璀璨星空 提供的彩蛋图标",
"感谢 @Bail 反馈的更新策略问题",
"感谢 @白水 反馈的安装 exagear 后无法识别和调用 box86 的问题",
"感谢 @汐光. 提供的翻译接口",
"感谢 @鹤舞白沙 专门为小白用户编写的使用 Wine 运行器非基于生态适配脚本的程序打包教程",
"感谢 @牦牛儿苗 进行了龙芯 3a5000 平台的测试与移植",
"感谢 @雁舞白沙 优化了程序文案",
"感谢 @豪 的程序测试和制作的非官方论坛 https://gfdgdxi.flarum.cloud/",
"感谢 @豪 的程序测试和制作的论坛 https://gfdgdxi.flarum.cloud/",
"感谢 @185******67 反馈的 2.4.0 无法打开 Visual Basic 组件安装工具的问题",
"感谢 @shenmo 提供的 在打包器的 postrm 脚本添加 kill.sh、追加参数改为 --uri xxxxxxx、独立生成容器 7z 文件的功能",
"感谢 @a2035274 @虚幻的早晨 https://bbs.deepin.org/post/238301",

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -1,3 +1,3 @@
{
"Version": "2.5.0"
"Version": "3.0.0"
}

View File

@@ -19,6 +19,7 @@ import subprocess
import PyQt5.QtGui as QtGui
import PyQt5.QtCore as QtCore
import PyQt5.QtWidgets as QtWidgets
from trans import *
###################
# 程序所需事件
@@ -147,6 +148,10 @@ def NameChange(packageOrBotton: int):
elif packageOrBotton == 1 and bottonName.text() != packageName.text():
lockB = True
# 获取当前语言
def get_now_lang()->"获取当前语言":
return os.getenv('LANG')
###########################
# 程序信息
###########################
@@ -154,7 +159,12 @@ programPath = os.path.split(os.path.realpath(__file__))[0] # 返回 string
information = json.loads(readtxt(f"{programPath}/information.json"))
version = information["Version"]
iconPath = "{}/deepin-wine-runner.svg".format(programPath)
tips = """第一个文本框是应用程序中文名
# 语言载入
if not get_now_lang() == "zh_CN.UTF-8":
transla = Trans("en_US", f"{programPath}/trans/packager.json")
else:
transla = Trans("zh_CN")
tips = transla.transe("U", """第一个文本框是应用程序中文名
第二个文本框是应用程序英文名
第三个文本框是最终生成的包的描述
第四个选择框是desktop文件中的分类
@@ -164,7 +174,7 @@ desktop文件中StartupWMClass字段。用于让桌面组件将窗口类名与de
第六个输入框是最终生成的包的包名,包名的命名规则以deepin开头加官网域名需要前后对调位置如还不能区分再加上应用名
最后一个是最终生成的包的版本号,版本号命名规则:应用版本号+deepin+数字
提示:包名和容器名相同,无法设置为不相同,如果需要设置为不相同,需要用另一个非基于生态适配脚本的打包器
"""
""")
###########################
# 窗口创建
@@ -186,22 +196,22 @@ packageName = QtWidgets.QLineEdit()
bottonName = QtWidgets.QLineEdit()
versionName = QtWidgets.QLineEdit()
controlFrame = QtWidgets.QHBoxLayout()
buildDeb = QtWidgets.QPushButton("打包")
debPath = QtWidgets.QPushButton("deb 包生成目录")
buildDeb = QtWidgets.QPushButton(transla.transe("U", "打包"))
debPath = QtWidgets.QPushButton(transla.transe("U", "deb 包生成目录"))
buildDeb.setSizePolicy(size)
debPath.setSizePolicy(size)
commandReturn = QtWidgets.QTextBrowser()
typeName.addItems(["Network", "Chat", "Audio", "Video", "Graphics", "Office", "Translation", "Development", "Utility", "System"])
controlFrame.addWidget(buildDeb)
controlFrame.addWidget(debPath)
widgetLayout.addWidget(QtWidgets.QLabel("程序中文名:"), 0, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel("程序英文名:"), 1, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel("包描述:"), 2, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel("程序分类:"), 3, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel("程序在 Wine 容器的位置:"), 4, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel("包名:"), 5, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel("容器名:"), 6, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel("版本号:"), 7, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "程序中文名:")), 0, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "程序英文名:")), 1, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "包描述:")), 2, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "程序分类:")), 3, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "程序在 Wine 容器的位置:")), 4, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "包名:")), 5, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "容器名:")), 6, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel(transla.transe("U", "版本号:")), 7, 0, 1, 1)
widgetLayout.addWidget(chineseName, 0, 1, 1, 1)
widgetLayout.addWidget(englishName, 1, 1, 1, 1)
widgetLayout.addWidget(debDescription, 2, 1, 1, 1)
@@ -221,27 +231,47 @@ window.setCentralWidget(widget)
window.resize(int(window.frameGeometry().width() * 1.5), int(window.frameGeometry().height()))
window.setWindowIcon(QtGui.QIcon(iconPath))
menu = window.menuBar()
programMenu = menu.addMenu("程序")
exit = QtWidgets.QAction("退出")
programMenu = menu.addMenu(transla.transe("U", "程序"))
exit = QtWidgets.QAction(transla.transe("U", "退出"))
exit.triggered.connect(window.close)
uploadSparkStore = menu.addMenu(QtCore.QCoreApplication.translate("U", "投稿到星火应用商店"))
uploadSparkStoreWebsize = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "从网页端投稿"))
uploadSparkStore = menu.addMenu(transla.transe("U", "投稿到星火应用商店"))
uploadSparkStoreWebsize = QtWidgets.QAction(transla.transe("U", "从网页端投稿"))
if os.path.exists("/opt/spark-store-submitter/bin/spark-store-submitter"):
uploadSparkStoreProgram = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "使用投稿器投稿(推荐)"))
uploadSparkStoreProgram = QtWidgets.QAction(transla.transe("U", "使用投稿器投稿(推荐)"))
else:
uploadSparkStoreProgram = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "使用投稿器投稿(推荐,请先安装投稿器)"))
uploadSparkStoreProgram = QtWidgets.QAction(transla.transe("U", "使用投稿器投稿(推荐,请先安装投稿器)"))
uploadSparkStoreProgram.setDisabled(True)
uploadSparkStore.addAction(uploadSparkStoreProgram)
uploadSparkStore.addAction(uploadSparkStoreWebsize)
uploadSparkStoreWebsize.triggered.connect(lambda: webbrowser.open_new_tab("https://upload.deepinos.org"))
uploadSparkStoreProgram.triggered.connect(lambda: threading.Thread(target=os.system, args=["/opt/spark-store-submitter/bin/spark-store-submitter"]).start())
helpMenu = menu.addMenu("帮助")
help = QtWidgets.QAction("帮助")
helpMenu = menu.addMenu(transla.transe("U", "帮助"))
help = QtWidgets.QAction(transla.transe("U", "帮助"))
help.triggered.connect(ShowHelp)
helpMenu.addAction(help)
programMenu.addAction(exit)
print(iconPath)
window.show()
chineseName.setWhatsThis(transla.transe("U", "应用程序中文名"))
englishName.setWhatsThis(transla.transe("U", "应用程序英文名"))
debDescription.setWhatsThis(transla.transe("U", "最终生成的包的描述"))
typeName.setWhatsThis(transla.transe("U", """点击右侧的下拉箭头,选择该软件所属的软件分类即可,常见软件分类名称释义:
Network=网络应用;
Chat=即时通讯或社交沟通;
Video=视频播放;
Graphics=图形图像;
Office=办公学习;
Translation=阅读翻译;
Development=软件开发;
Utility=工具软件或其他应用。
不明白英文的可以百度查询一下软件分类名称的意思。
注意:此时选择的软件分类名称决定了该软件打包后再安装时会安装在启动器中的哪个软件分类目录中。"""))
exePath.setWhatsThis("""程序在 Wine 容器的位置,以 c:\\XXX 的形式,盘符必须小写,用反斜杠,如果路径带用户名的话会自动替换为$USER
而 StartupWMClass 字段将会由程序自动生成,作用如下:
desktop文件中StartupWMClass字段。用于让桌面组件将窗口类名与desktop文件相对应。这个值为实际运行的主程序EXE的文件名wine/crossover在程序运行后会将文件名设置为窗口类名""")
packageName.setWhatsThis(transla.transe("U", "最终生成的包的包名,包名的命名规则以deepin开头加官网域名需要前后对调位置如还不能区分再加上应用名"))
bottonName.setWhatsThis(transla.transe("U", "容器名"))
versionName.setWhatsThis(transla.transe("U", "最终生成的包的版本号,版本号命名规则:应用版本号+deepin+数字"))
window.setWindowTitle(f"Wine 打包器 {version}——基于统信 Wine 生态活动打包脚本制作")
windowFrameInputValueList = [
chineseName,

View File

@@ -0,0 +1,53 @@
#!/usr/bin/env python3
import os
import json
import requests
import traceback
class Trans():
isTrans = False
unCloudTrans = True
word = {}
fileName = ""
def __init__(self, lang="zh_CN", fileName=f"trans.json") -> None:
self.fileName = fileName
self.isTrans = (lang != "zh_CN")
if self.isTrans:
try:
if not os.path.exists(fileName):
with open(fileName, "w") as file:
file.write("{}")
with open(fileName, "r") as file:
self.word = json.loads(file.read())
except:
traceback.print_exc()
self.isTrans = False
def transe(self, temp, text) -> str:
if not self.isTrans:
return text
try:
return self.word[text]
except:
if self.unCloudTrans:
return text
# 机翻
data = { 'doctype': 'json', 'type': 'auto','i': text}
jsonReturn = requests.post("http://fanyi.youdao.com/translate", data=data).json()["translateResult"]
transText = ""
for i in jsonReturn:
print(i[0])
transText += f'{i[0]["tgt"]}\n'
if "\n" in text:
transText = transText.replace("\n\n", "\n")[:-1]
else:
transText = transText[:-1]
self.word[text] = transText
try:
with open(self.fileName, "w") as file:
file.write(json.dumps(self.word, ensure_ascii=False))
except:
traceback.print_exc()
print(f"{text}=>{transText}")
return transText

View File

@@ -0,0 +1 @@
{"第一个文本框是应用程序中文名\n第二个文本框是应用程序英文名\n第三个文本框是最终生成的包的描述\n第四个选择框是desktop文件中的分类\n第五个输入框是程序在 Wine 容器的位置,以 c:\\XXX 的形式,盘符必须小写,用反斜杠,如果路径带用户名的话会自动替换为$USER\n而 StartupWMClass 字段将会由程序自动生成,作用如下:\ndesktop文件中StartupWMClass字段。用于让桌面组件将窗口类名与desktop文件相对应。这个值为实际运行的主程序EXE的文件名wine/crossover在程序运行后会将文件名设置为窗口类名\n第六个输入框是最终生成的包的包名,包名的命名规则以deepin开头加官网域名需要前后对调位置如还不能区分再加上应用名\n最后一个是最终生成的包的版本号版本号命名规则应用版本号+deepin+数字\n提示包名和容器名相同无法设置为不相同如果需要设置为不相同需要用另一个非基于生态适配脚本的打包器\n": "The first is the application Chinese name text box\nThe second text box is application English name\nThe third one is a text box that ultimately make the description of the package\nA fourth option box is a classification in the desktop file\nThe fifth input box is program in Wine vessel position, to the c: \\ XXX's form, the drive must be lowercase, with a backslash, if the path with the USER name will be automatically replaced with $USER\nWhile StartupWMClass fields will be automatically generated by the program, function is as follows:\nThe desktop file StartupWMClass fields.\nThe sixth input box is the package name of the resulting package, the package name begin with deepin naming rules, plus the website domain name (need change over) before and after, if can't distinguish between plus application name\nThe last one is the resulting package version number, version number naming rules: application version number + deepin + number\nTip: package name is the same as the container name, cannot be set to different, if you need to set up for different, need to use another based on the ecological adaptation of the script package", "投稿到星火应用商店": "Contribute to spark the app store", "从网页端投稿": "From the web", "使用投稿器投稿(推荐)": "Use contribute contributes (recommended)", "打包": "packaging", "deb 包生成目录": "Deb package generated directory", "程序中文名:": "Program name:", "程序英文名:": "English name:", "包描述:": "Package description:", "程序分类:": "Program classification:", "程序在 Wine 容器的位置:": "The location of the program in Wine container:", "包名:": "Package name:", "容器名:": "Vessel name:", "版本号:": "The version number:", "程序": "The program", "退出": "exit", "帮助": "help", "应用程序中文名": "The application name", "应用程序英文名": "The application name in English", "最终生成的包的描述": "The resulting package description", "点击右侧的下拉箭头,选择该软件所属的软件分类即可,常见软件分类名称释义:\nNetwork=网络应用;\nChat=即时通讯或社交沟通;\nVideo=视频播放;\nGraphics=图形图像;\nOffice=办公学习;\nTranslation=阅读翻译;\nDevelopment=软件开发;\nUtility=工具软件或其他应用。\n不明白英文的可以百度查询一下软件分类名称的意思。\n注意此时选择的软件分类名称决定了该软件打包后再安装时会安装在启动器中的哪个软件分类目录中。": "Click on the right side of the drop-down menu, select the software's classification, the classification of common software name definition:\nThe Network = web applications;\nChat = instant messaging or social communication;\nVideo = Video playback;\nGraphics = Graphics;\nOffice = Office learning;\nTranslation = read Translation;\nDevelopment = software Development;\nThe Utility = tool software or other applications.\nDon't understand English can baidu query the meaning of classification of software name.\nNote: the choice of software classification name determines the software package installs again after installation in the starter which classification of software directory.", "最终生成的包的包名,包名的命名规则以deepin开头加官网域名需要前后对调位置如还不能区分再加上应用名": "The package name of the resulting package, the package name begin with deepin naming rules, plus (need change over) before and after the website domain name, such as can not distinguish between plus application name", "容器名": "Container name", "最终生成的包的版本号,版本号命名规则:应用版本号+deepin+数字": "The resulting package version number, version number naming rules: application version number + deepin + number"}

View File

@@ -7,32 +7,21 @@ with open("/var/lib/dpkg/status", "r") as i:
if unConnect:
print("52专版将会无法连接服务器")
badUrl = [
"http://120.25.153.144",
"https://304626p927.goho.co",
"https://30x46269h2.goho.co",
"http://gfdgdxi.msns.cn"
]
class Respon:
text = ""
def get(url, timeout=None): # -> requests.Response:
if unConnect:
# 筛选 Url,只有特定的 url 才会被拦截
for i in badUrl:
if i in url:
raise Exception("52专版不支持连接作者服务器")
# 全部 Url拦截
raise Exception("52专版不支持连接服务器")
if timeout == None:
return requests.get(url)
return requests.get(url, timeout=timeout)
def post(url, data, timeout=None):
if unConnect:
# 筛选 Url,只有特定的 url 才会被拦截
for i in badUrl:
if i in url:
raise Exception("52专版不支持连接作者服务器")
# 全部 Url拦截
raise Exception("52专版不支持连接服务器")
if timeout == None:
return requests.post(url, data)
return requests.post(url, data, timeout=timeout)

Binary file not shown.

Binary file not shown.

53
trans/__init__.py Normal file
View File

@@ -0,0 +1,53 @@
#!/usr/bin/env python3
import os
import json
import requests
import traceback
class Trans():
isTrans = False
unCloudTrans = True
word = {}
fileName = ""
def __init__(self, lang="zh_CN", fileName=f"trans.json") -> None:
self.fileName = fileName
self.isTrans = (lang != "zh_CN")
if self.isTrans:
try:
if not os.path.exists(fileName):
with open(fileName, "w") as file:
file.write("{}")
with open(fileName, "r") as file:
self.word = json.loads(file.read())
except:
traceback.print_exc()
self.isTrans = False
def transe(self, temp, text) -> str:
if not self.isTrans:
return text
try:
return self.word[text].replace("", "(").replace("", ")")
except:
if self.unCloudTrans:
return text
# 机翻
data = { 'doctype': 'json', 'type': 'auto','i': text}
jsonReturn = requests.post("http://fanyi.youdao.com/translate", data=data).json()["translateResult"]
transText = ""
for i in jsonReturn:
print(i[0])
transText += f'{i[0]["tgt"]}\n'
if "\n" in text:
transText = transText.replace("\n\n", "\n")[:-1]
else:
transText = transText[:-1]
self.word[text] = transText.replace("", "(").replace("", ")")
try:
with open(self.fileName, "w") as file:
file.write(json.dumps(self.word, ensure_ascii=False))
except:
traceback.print_exc()
print(f"{text}=>{transText}")
return transText

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
{"更换源": "Change the source", "Gitlink 源(推荐)": "Gitlink source (recommended)", "备用源(只支持 IPv6 用户)": "The alternate source (only support IPv6 users)", "本地测试源127.0.0.1": "Local test source (127.0.0.1)", "使用前须知:\n1、Qemu 跨架构效率较低,如果有条件建议优先使用 box86、exagear 等效率较高的转换层;\n2、使用此方案需要使用到 Root 权限(需开启管理员模式)并安装 qemu-user-static\n3、chroot 时候可能会出现问题导致程序闪退或异常,出现该问题重启电脑即可;\n4、在此环境使用 Wine 时,只能读取到您用户目录或本程序文件夹下的文件,其它路径无法读取;\n5、移除容器时请保证在这次打开电脑时没有调用过需要删除容器如果有调用过建议重启电脑后再移除\n6、暂时属于测试功能": "Instructions before use:\n1, Qemu across architecture efficiency is low, if there is condition is preferred to use box86, exagear high efficiency transformation layer;\n2, use this program to need to use the Root administrator mode (open) and install qemu - user - static;\n3, when chroot flash back problems may cause the program or abnormal, the problems to restart the computer;\n4, in this environment using Wine, can only read your user directory or folder of the program files, other path cannot read;\n5, remove the container please make sure that no calls while in the open a computer need to delete the container, if there is a call after advice to restart the computer to remove;\n6, a temporary belong to test functionality;"}

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More