Compare commits

..
14 Commits
Author SHA1 Message Date
gfdgd-xi 9799b598c3 调整README 2024-01-28 19:13:02 +08:00
gfdgd-xi 2933fc90df 调整README 2024-01-28 19:12:02 +08:00
gfdgd-xi 4a4a75eacd 大致 2024-01-16 22:18:09 +08:00
gfdgd-xi 42516f874a 初步多线程 2024-01-02 22:40:51 +08:00
gfdgd-xi c4b977c31c 实现Wine识别检测功能 2024-01-01 22:36:04 +08:00
gfdgd-xi df6d4ef120 初步的兼容层检测 2024-01-01 17:53:39 +08:00
gfdgd-xi 8e9489b7f7 历史记录的初步读取 2024-01-01 17:33:09 +08:00
gfdgd-xi b6d435def7 实现了部分wine检测 2024-01-01 16:48:08 +08:00
gfdgd-xi 60c3920f1f 初步调好了UI 2024-01-01 15:46:55 +08:00
gfdgd-xi f9f163b973 UI熟悉多了 2024-01-01 15:25:51 +08:00
gfdgd-xi 1b30fd4a6c UI有点感觉了 2024-01-01 15:19:08 +08:00
gfdgd-xi 0b27387d08 Add README 2024-01-01 14:00:01 +08:00
gfdgd-xi 0bcc1dfc18 Add README 2024-01-01 13:56:02 +08:00
gfdgd-xi c4a0fcfa6e GPLV3 2024-01-01 13:51:52 +08:00
30 changed files with 1297 additions and 125 deletions
+73 -6
View File
@@ -1,6 +1,73 @@
*.user*
__pycache__
*.deb
VM-source/Makefile
*.rpm
*.pro.user
# This file is used to ignore files which are generated
# ----------------------------------------------------------------------------
*~
*.autosave
*.a
*.core
*.moc
*.o
*.obj
*.orig
*.rej
*.so
*.so.*
*_pch.h.cpp
*_resource.rc
*.qm
.#*
*.*#
core
!core/
tags
.DS_Store
.directory
*.debug
Makefile*
*.prl
*.app
moc_*.cpp
ui_*.h
qrc_*.cpp
Thumbs.db
*.res
*.rc
/.qmake.cache
/.qmake.stash
# qtcreator generated files
*.pro.user*
# xemacs temporary files
*.flc
# Vim temporary files
.*.swp
# Visual Studio generated files
*.ib_pdb_index
*.idb
*.ilk
*.pdb
*.sln
*.suo
*.vcproj
*vcproj.*.*.user
*.ncb
*.sdf
*.opensdf
*.vcxproj
*vcxproj.*
# MinGW generated files
*.Debug
*.Release
# Python byte code
*.pyc
# Binaries
# --------
*.dll
*.exe
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 270 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Executable
+31
View File
@@ -0,0 +1,31 @@
<p width=100px align="center"><img src="https://storage.deepin.org/thread/202208031419283599_deepin-wine-runner.png"></p>
<h1 align="center">Wine 运行器 C++ 版</h1>
<hr>
<a href='https://gitee.com/gfdgd-xi/deep-wine-runner/stargazers'><img src='https://gitee.com/gfdgd-xi/deep-wine-runner/badge/star.svg?theme=dark' alt='star'></img></a>
<a href='https://gitee.com/gfdgd-xi/deep-wine-runner/members'><img src='https://gitee.com/gfdgd-xi/deep-wine-runner/badge/fork.svg?theme=dark' alt='fork'></img></a>
## 介绍
Wine运行器是一个能让Linux用户更加方便地运行Windows应用的程序。原版的 Wine 只能使用命令操作,且安装过程较为繁琐,对小白不友好。于是该运行器为了解决该痛点,内置了对Wine图形化的支持、Wine 安装器、微型应用商店、各种Wine工具、自制的Wine程序打包器、运行库安装工具等。
它同时还内置了基于Qemu/VirtualBox制作的、专供小白使用的Windows虚拟机安装工具,可以做到只需下载系统镜像并点击安装即可,无需考虑虚拟机的安装、创建、分区等操作,也能在非 X86 架构安装 X86 架构的 Windows 操作系统(但是效率较低,可以运行些老系统)。
而且对于部分 Wine 应用适配者来说,提供了图形化的打包工具,以及提供了一些常用工具以及运行库的安装方式,以及能安装多种不同的 Wine 以测试效果,能极大提升适配效率。
且对于 Deepin23 用户做了特别优化,以便能在缺少 i386 运行库的情况下运行 Wine32。同时也为非 X86 架构用户提供了 Box86/64、Qemu User 的安装方式
该版本用于解决 Python 版 Wine 运行器依赖过于复杂的问题(简化版 Wine 运行器)
## 如何编译
```bash
git clone https://gitee.com/gfdgd-xi/deep-wine-runner-cpp --depth=1
cd deep-wine-runner-cpp
qmake .
make -j4
./deep-wine-runner-cpp
```
## 请作者吃点零食
如果你觉得 Wine 运行器对你有帮助,可以请作者吃点零食
(本来想说喝一杯咖啡的,但我不喝啊)
<img src="Icon/QR/Wechat.png" width="200" />
<img src="Icon/QR/Alipay.jpg" width="200" />
<img src="Icon/QR/QQ.png" width="200" >
# ©2020-Now gfdgd xi
+23
View File
@@ -0,0 +1,23 @@
<RCC>
<qresource prefix="/">
<file>information.json</file>
<file>LICENSE</file>
</qresource>
<qresource prefix="/Icon">
<file>deepin-wine-runner_512x512.png</file>
<file>deepin-wine-runner.svg</file>
<file>Icon/Program/AboutIcon0.png</file>
</qresource>
<qresource prefix="/Icon/QR">
<file>Icon/QR/Alipay.jpg</file>
<file>Icon/QR/QQ.png</file>
<file>Icon/QR/Wechat.png</file>
</qresource>
<qresource prefix="/Icon/Function">
<file>Icon/Function/CHROOT.png</file>
<file>Icon/Function/more-wine.png</file>
<file>Icon/Function/wine.png</file>
<file>Icon/Function/wine23A.png</file>
<file>Icon/Function/wine23P.png</file>
</qresource>
</RCC>
+79
View File
@@ -0,0 +1,79 @@
#include "about_this_program.h"
#include "ui_about_this_program.h"
#include <QDateTime>
about_this_program::about_this_program(QWidget *parent) :
QDialog(parent),
ui(new Ui::about_this_program)
{
ui->setupUi(this);
QString tips = tr("<h4>提示:</h4>\n"\
"1、使用终端运行该程序,可以看到 wine 以及程序本身的提示和报错;\n"\
"2、wine 32 位和 64 位的容器互不兼容;\n"\
"3、所有的 wine 和 winetricks 均需要自行安装(可以从 菜单栏=>程序 里面进行安装);\n"\
"4、本程序支持带参数运行 wine 程序(之前版本也可以),只需要按以下格式即可:\n"\
"exe路径\' 参数 \'\n"\
"即可(单引号需要输入);\n"\
"5、wine 容器如果没有指定,则会默认为 ~/.wine;\n"\
"6、如果可执行文件比较大的话,会出现点击“获取该程序运行情况”出现假死的情况,因为正在后台读取 SHA1,只需要等一下即可(读取速度依照您电脑处理速度、读写速度、可执行文件大小等有关);\n"\
"7、如果非 X86 的用户的 UOS 专业版用户想要使用的话,只需要在应用商店安装一个 Wine 版本微信即可在本程序选择正确的 Wine 运行程序;");
QString aboutProgram = tr("<p>Wine运行器是一个能让Linux用户更加方便地运行Windows应用的程序。原版的 Wine 只能使用命令操作,且安装过程较为繁琐,对小白不友好。于是该运行器为了解决该痛点,内置了对Wine图形化的支持、Wine 安装器、微型应用商店、各种Wine工具、自制的Wine程序打包器、运行库安装工具等。</p>\n"\
"<p>它同时还内置了基于Qemu/VirtualBox制作的、专供小白使用的Windows虚拟机安装工具,可以做到只需下载系统镜像并点击安装即可,无需考虑虚拟机的安装、创建、分区等操作,也能在非 X86 架构安装 X86 架构的 Windows 操作系统(但是效率较低,可以运行些老系统)。</p>\n"\
"<p>而且对于部分 Wine 应用适配者来说,提供了图形化的打包工具,以及提供了一些常用工具以及运行库的安装方式,以及能安装多种不同的 Wine 以测试效果,能极大提升适配效率。</p>\n"\
"<p>且对于 Deepin23 用户做了特别优化,以便能在缺少 i386 运行库的情况下运行 Wine32。同时也为非 X86 架构用户提供了 Box86/64、Qemu User 的安装方式</p>\n"\
"<pre>");
QString goodRunSystem = tr("常见 Linux 发行版");
QString updateThingsString = "";
QString updateTime = "2023年12月24日";
QString thankText = "";
QString version = "";
QString programUrl = "https://gitee.com/gfdgd-xi/deep-wine-runner\nhttps://github.com/gfdgd-xi/deep-wine-runner\nhttps://gfdgd-xi.github.io";
QString about = "<style>\n"\
"a:link, a:active {{\n"\
" text-decoration: none;\n"\
"}}\n"\
"</style>\n"\
"<h1>关于</h1>\n"\
"" + aboutProgram + "\n"\
"\n"\
"版本:" + version + "\n"\
"适用平台:" + goodRunSystem + "\n"\
"安装包构建时间:" + __DATE__ + " " + __TIME__ + "\n"\
"Qt 版本:" + qVersion() + "\n"\
"程序官网:" + programUrl + "\n"\
"<b>Wine 运行器 QQ 交流群:762985460</b>\n"\
"<b>Wine运行器 QQ 频道:https://pd.qq.com/s/edqkgeydx</b>\n"\
"当前程序占用体积:@programSize@MB</pre>\n"\
"<p>本程序依照 GPLV3 协议开源</p>\n"\
"<hr>\n"\
"<h1>鸣谢名单</h1>\n"\
"<pre>" + thankText + "</pre>\n"\
"<hr>\n"\
"<h1>更新内容</h1>\n"\
"<pre>" + updateThingsString + "\n"\
"<b>更新时间:" + updateTime + "</b></pre>\n"\
"<hr>\n"\
"<h1>提示</h1>\n"\
"<pre>" + tips + "\n"\
"</pre>\n"\
"<hr>\n"\
"<h1>友谊链接</h1>\n"\
"<pre>星火应用商店:<a href='https://spark-app.store/'>https://spark-app.store/</a>\n"\
"Deepin 官网:<a href='https://www.deepin.org'>https://www.deepin.org</a>\n"\
"Deepin 论坛:<a href='https://bbs.deepin.org'>https://bbs.deepin.org</a>\n"\
"gfdgd xi<a href='https://gfdgd-xi.github.io'>https://gfdgd-xi.github.io</a>\n"\
"<hr>\n"\
"<h1>©2020~" + QDateTime(QDateTime::currentDateTime()).toString("yyyy") + " By gfdgd xi</h1>";
}
about_this_program::~about_this_program()
{
delete ui;
}
void about_this_program::on_ok_clicked()
{
this->close();
}
+25
View File
@@ -0,0 +1,25 @@
#ifndef ABOUT_THIS_PROGRAM_H
#define ABOUT_THIS_PROGRAM_H
#include <QDialog>
namespace Ui {
class about_this_program;
}
class about_this_program : public QDialog
{
Q_OBJECT
public:
explicit about_this_program(QWidget *parent = nullptr);
~about_this_program();
private slots:
void on_ok_clicked();
private:
Ui::about_this_program *ui;
};
#endif // ABOUT_THIS_PROGRAM_H
+78
View File
@@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>about_this_program</class>
<widget class="QDialog" name="about_this_program">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>863</width>
<height>498</height>
</rect>
</property>
<property name="windowTitle">
<string>关于 Wine 运行器</string>
</property>
<property name="windowIcon">
<iconset resource="Resources.qrc">
<normaloff>:/Icon/deepin-wine-runner.svg</normaloff>:/Icon/deepin-wine-runner.svg</iconset>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="1">
<widget class="QTextBrowser" name="aboutInfo"/>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="ok">
<property name="text">
<string>确定</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="iconShow">
<property name="text">
<string>&lt;a&gt;&lt;img src=&quot;:/Icon/deepin-wine-runner.svg&quot; width=256 &gt;&lt;/a&gt;</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<resources>
<include location="Resources.qrc"/>
</resources>
<connections/>
</ui>
+38
View File
@@ -0,0 +1,38 @@
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++17
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
about_this_program.cpp \
main.cpp \
mainwindow.cpp \
qr.cpp
HEADERS += \
about_this_program.h \
mainwindow.h \
qr.h
FORMS += \
about_this_program.ui \
mainwindow.ui \
qr.ui
TRANSLATIONS += \
deep-wine-runner-cpp_zh_CN.ts
CONFIG += lrelease
CONFIG += embed_translations
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
RESOURCES += \
Resources.qrc
+3
View File
@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="zh_CN"></TS>
File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 11 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

+1
View File
File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

-119
View File
@@ -1,119 +0,0 @@
#!/usr/bin/env python3
import os
import sys
import time
import subprocess
import threading
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
def check_window():
# 使用 wmctrl 命令列出所有窗口,并使用 grep 过滤出特定的 WMCLASS
windows = subprocess.getoutput(f'wmctrl -lx | grep "{target_wmclass}"')
# 如果窗口存在,则关闭提示
if windows.replace("\n", "").replace(" ", "") != "":
# 提取窗口ID
window_id = windows.replace(" ", " ").split(" ")[0]
print(f"Window with WMCLASS '{target_wmclass}' found")
return 1
else:
print(f"Window with WMCLASS '{target_wmclass}' not found.")
def check_wmclass():
if timeout:
time.sleep(timeout)
window.close()
return
# 循环检测窗口是否存在的函数
# 每隔一段时间检测一次窗口是否存在
showtimeout = 60 # 为防止因为应用无法打开而无法正常关闭窗口,于是设置 time out
while True:
if check_window():
break
# 等待一段时间后再次检测
time.sleep(1)
AppInfoShowerRefresh()
showtimeout -= 1
if showtimeout <= 0:
break
window.close()
timeout = 0
if os.getenv("WAYLAND_DISPLAY"):
timeout = 3
if os.system("which wmctrl"):
print("No wmctrl installed. Do not check wmclass")
timeout = 3
target_wmclass = os.getenv("WINE_WMCLASS")
def GetRecommendWindowSize(window: QMainWindow):
# 计算屏幕分辨率
screen = QGuiApplication.primaryScreen()
width = screen.geometry().width()
height = screen.geometry().height()
# 如果为竖状屏幕
if width < height:
temp = height
height = width
width = temp
return [int(width / 4), window.geometry().height()]
def SetWindowSize(window: QMainWindow):
# 计算比例
size = GetRecommendWindowSize(window)
window.resize(size[0], size[1])
def MoveCenter(window: QMainWindow):
# 计算屏幕分辨率
screen = QGuiApplication.primaryScreen()
width = screen.geometry().width()
height = screen.geometry().height()
print(window.geometry().height())
# 计算窗口坐标
window.move(int(width / 2 - window.geometry().width() / 2),
int(height / 2.8 - window.geometry().height() / 2)
)
def AppInfoShowerRefresh():
global appInfoShowerTime
appInfoShower.setText(f"<h3 align='center'>星火Windows应用兼容助手</h3><p align='center'>正在为您启动以下应用:{os.getenv('WINE_APP_NAME')} {'.' * (appInfoShowerTime % 3 + 1)}</p>")
appInfoShowerTime += 1
programPath = os.path.split(os.path.realpath(__file__))[0] # 返回 string
app = QApplication(sys.argv)
# 构建窗口
window = QMainWindow()
widget = QWidget()
layout = QGridLayout()
appInfoShower = QLabel()
appInfoShowerTime = 0
AppInfoShowerRefresh()
backgroundImgPath = f"{programPath}/back.jpg"
# GXDE 彩蛋
if os.path.exists("/usr/share/gxde-resources/spark-dwine-helper.png"):
backgroundImgPath = "/usr/share/gxde-resources/spark-dwine-helper.png"
window.setWindowTitle("星火Windows应用兼容助手")
layout.addWidget(QLabel(f""), 1, 0)
layout.addWidget(appInfoShower, 2, 0)
layout.addWidget(QLabel(f"<hr>由 Wine 运行器提供支持"), 4, 0)
widget.setLayout(layout)
window.setCentralWidget(widget)
window.setWindowFlags(Qt.CustomizeWindowHint | Qt.WindowStaysOnTopHint)
window.show()
SetWindowSize(window)
layout.addWidget(QLabel(f"<p align='center'><img width='{window.geometry().width()}' src='{backgroundImgPath}'></p>"), 0, 0)
threading.Thread(target=check_wmclass).start()
MoveCenter(window)
app.exec_()
+61
View File
@@ -0,0 +1,61 @@
{
"Version": "3.6.1",
"Time": "未知",
"Thank": [
"感谢 @ёжезийлёзйз 进行 Loongarch 架构的测试(旧世界,远程)",
"感谢 @run@3a4k 提供 3a4000 测试机器(远程)",
"感谢 RacoonGX 的付出与贡献",
"感谢 @Amber 编写的《使用wine运行器打包无安装包的软件》:https://bbs.deepin.org/post/247720",
"感谢 @豪 提供程序图标",
"感谢 @鹤舞白沙 对程序文案进行优化以及编写《Wine运行器和Wine打包器傻瓜式使用教程(小白专用) 》:https://bbs.deepin.org/post/246837",
"感谢 @璀璨星空 提供的彩蛋图标",
"感谢 @Bail 反馈的更新策略问题",
"感谢 @白水 反馈的安装 exagear 后无法识别和调用 box86 的问题",
"感谢 @汐光. 提供的翻译接口",
"感谢 @鹤舞白沙 专门为小白用户编写的使用 Wine 运行器非基于生态适配脚本的程序打包教程",
"感谢 @牦牛儿苗 进行了龙芯 3a5000 平台的测试与移植",
"感谢 @鹤舞白沙 优化了程序文案",
"感谢 @豪 的程序测试和制作的论坛 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",
"感谢 @zhangs https://bbs.deepin.org/post/227948",
"感谢 @gtjmaster https://bbs.deepin.org/post/225509",
"感谢 @统信UCARE服务 https://mp.weixin.qq.com/s/iOdfNv6phc8F4inackFFTw",
"感谢 @星火应用商店 提供部分安装包的源以及本程序的下载地址",
"感谢 @delsin 和 @神末shenmo 在 deepin 论坛提供打包器打包的 deb 包自动删除容器的建议",
"感谢 @shenmo 反馈的 2.1.0 打包器问题和 2.1.0-1 终端调用问题",
"感谢 @GershonWang 在 https://github.com/gfdgd-xi/deep-wine-runner/issues/1 提供窗口居中的建议",
"感谢 @134******28 和 @sgb76 提供的新程序 GUI 布局和实现代码",
"感谢 @sgb76 为 Wine 打包器(非生态适配脚本)打包的 i386 deb 提供建议",
"感谢 @PossibleVing 提供的新版应用图标",
"感谢 @zhengjl 反馈的 1.7.0 中 .net framrwork 3.5 非离线版安装包的问题以及 1.8.0 重复路径一直自动重复增加的问题",
"感谢 @国川 @刘岐 提供的非 i386、amd64 运行 wine 使用 i386/amd64 可执行文件的教程和脚本",
"感谢 @王俊文 @189******09 @tfhyl 提供在非 X86 平台的国产 PC 进行测试",
"感谢 @cuisirwork 提供的提供视频教程的建议",
"感谢 @办公助手 提供的非 X86 平台 Wine 运行自定义 exe 应用教程和 deb 包",
"感谢 @季星火 反馈的无法使用该程序删除生成的 .desktop 的问题",
"感谢 @ZYH 提供的敏感词列表",
"感谢 @五行缺钱 反馈的 2.0.0 在 Deepin 23 缺失依赖 toilet 的问题",
"感谢 @云的眼泪 @zhengjl 反馈的 2.0.0 发布忘记把安装包传蓝奏云的问题",
"感谢 @虚幻的早晨 提出的添加 DXVK、VKD3D 的功能(VKD3D 暂未实现)",
"感谢 @以勒 修改 Dll 提取工具提示文本的建议",
"感谢 @历山居士 反馈的获取自动配置容器脚本工具无法正常加载数据的问题",
"感谢 @Nick @奋斗ing 反馈的 2.1.0-2 的快捷方式故障",
"感谢 @俊生鹏程 反馈的 2.1.0-2 及以前版本在鲲鹏运行 wine 错误的问题并积极测试,以及组件安装工具在 arm 架构的异常",
"感谢 @云的眼泪 反馈的 2.1.0-2 更新死循环的问题,可见:https://bbs.deepin.org/post/243241,以及感谢 @神末shenmo @忘记、过去 和 @历山居士 的讨论",
"感谢 @186******75 反馈的 2.2.0 基于生态适配脚本打包器对话框异常的问题",
"感谢微信用户 @华为 @办公助手 @白水 @北冥没有鱼 @俊生鹏程 @^♀莫離♪^ @姚洪安 @гυи @杨飞 在 arm(飞腾/鲲鹏)架构上提供提供测试与帮助",
"感谢 @办公助手 提供的 2.4.0 打包器支持生成的 arm 架构 deb 包同时支持 UOS box86+exagear 的建议",
"",
"感谢统信在 Wine 生态适配活动中提供的打包脚本",
"也感谢 Deepin Wine 团体制作的 Deepin Wine 和对应的 Deepin Wine Tools,对本程序有很大的帮助",
"也感谢 DXVK 的开发者开发了 DXVK 这个程序,项目链接:https://github.com/doitsujin/dxvk",
"也感谢 WineHQ 开发团队开发的 WineHQ,项目网址:https://dl.winehq.org/",
"也感谢来自 Vek 的灵感和 Vek 开发者的支持,项目链接:https://jihulab.com/vk",
"最后也感谢支持本程序的用户和上传相关软件运行情况数据的用户,有你们的支持和使用,使这个程序变得更好",
"",
"可以从上面的各种解决方案更好的学习 Wine 生态适配,也可以看 deepin 论坛板块 https://bbs.deepin.org/module/detail/116 进行学习,最后也向各位有进行 Wine 生态适配的大佬进行由衷的感谢!",
"如果上面有遗漏,请向我反馈补充"
]
}
+22
View File
@@ -0,0 +1,22 @@
#include "mainwindow.h"
#include <QApplication>
#include <QLocale>
#include <QTranslator>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QTranslator translator;
const QStringList uiLanguages = QLocale::system().uiLanguages();
for (const QString &locale : uiLanguages) {
const QString baseName = "deep-wine-runner-cpp_" + QLocale(locale).name();
if (translator.load(":/i18n/" + baseName)) {
a.installTranslator(&translator);
break;
}
}
MainWindow w;
return a.exec();
}
+584
View File
@@ -0,0 +1,584 @@
#include "mainwindow.h"
#include <QGridLayout>
#include <QLabel>
#include <QComboBox>
#include <QPushButton>
#include <QMainWindow>
#include <QObject>
#include <QSizePolicy>
#include <QSpacerItem>
#include <QTextBrowser>
#include <QCoreApplication>
#include <iostream>
#include <QDebug>
#include <QIODevice>
#include <QJsonDocument>
#include <QJsonObject>
#include <QFile>
#include <QProcess>
#include <QMessageBox>
#include <QObject>
using namespace std;
QComboBox *MainWindow::e1;
QComboBox *MainWindow::e2;
QComboBox *MainWindow::o1;
QMap<QString, QString> MainWindow::setting;
QMap<QString, QString> MainWindow::wine;
QString MainWindow::lastRunCommand = "";
MainWindow::MainWindow(){
/*********
* 设置变量
*********/
// 如果要添加其他 wine,请使用安装更多 Wine 功能
QMainWindow *window = new QMainWindow();
QWidget *widget = new QWidget();
window->setCentralWidget(widget);
QGridLayout *mainLayout = new QGridLayout();
QSizePolicy size;
//size->setVerticalPolicy(0);
QWidget *leftUp = new QWidget();
mainLayout->addWidget(leftUp, 0, 0, 1, 1);
QGridLayout *leftUpLayout = new QGridLayout();
leftUp->setLayout(leftUpLayout);
QLabel *fastLabel = new QLabel(QObject::tr("快速启动"));
fastLabel->setStyleSheet("font: 30px;");
leftUpLayout->addWidget(fastLabel, 0, 0, 1, 2);
leftUpLayout->addWidget(new QLabel("<hr>"), 1, 0, 1, 2);
leftUpLayout->addWidget(new QLabel(QObject::tr("请选择容器路径:")), 2, 0, 1, 1);
e1 = new QComboBox();
e1->setEditable(1);
leftUpLayout->addWidget(e1, 3, 0, 1, 1);
button1 = new QPushButton("浏览");
//button1.clicked.connect(liulanbutton);
leftUpLayout->addWidget(button1, 3, 1, 1, 1);
leftUpLayout->addWidget(new QLabel(QObject::tr("请选择要执行的程序(EXE、MSI或者命令):")), 4, 0, 1, 1);
e2 = new QComboBox();
e2->setEditable(1);
leftUpLayout->addWidget(e2, 5, 0, 1, 1);
button2 = new QPushButton(QObject::tr("浏览"));
//button2.clicked.connect(liulanexebutton);
leftUpLayout->addWidget(button2, 5, 1, 1, 1);
leftUpLayout->addWidget(new QLabel(QObject::tr("请选择WINE版本:")), 6, 0, 1, 1);
o1 = new QComboBox();
leftUpLayout->addWidget(o1, 7, 0, 1, 1);
// 设置空间权重
button1->setSizePolicy(size);
button2->setSizePolicy(size);
// UI 创建
QWidget *leftDown = new QWidget();
mainLayout->addWidget(leftDown, 1, 0, 1, 1);
QVBoxLayout *leftDownLayout = new QVBoxLayout();
leftDown->setLayout(leftDownLayout);
QLabel *highLabel = new QLabel(QObject::tr("高级功能"));
highLabel->setStyleSheet("font: 30px;");
leftDownLayout->addWidget(highLabel);
leftDownLayout->addWidget(new QLabel("<hr>"));
leftDownLayout->addWidget(new QLabel(QObject::tr("创建快捷方式(Desktop文件):")));
QHBoxLayout *createDesktopLink = new QHBoxLayout();
QLabel *label_r_2 = new QLabel(QObject::tr("名称:"));
createDesktopLink->addWidget(label_r_2);
QComboBox *combobox1 = new QComboBox();
combobox1->setEditable(1);
createDesktopLink->addWidget(combobox1);
QPushButton *button5 = new QPushButton(QObject::tr("创建到桌面"));
//button5.clicked.connect(make_desktop_on_desktop);
createDesktopLink->addWidget(button5);
QPushButton *saveDesktopFileOnLauncher = new QPushButton(QObject::tr("创建到开始菜单"));
//saveDesktopFileOnLauncher.clicked.connect(make_desktop_on_launcher);
createDesktopLink->addWidget(saveDesktopFileOnLauncher);
leftDownLayout->addLayout(createDesktopLink);
QGridLayout *programManager = new QGridLayout();
leftDownLayout->addLayout(programManager);
programManager->addWidget(new QLabel(QObject::tr("程序管理:")), 0, 0, 1, 1);
getProgramIcon = new QPushButton(QObject::tr("提取图标"));
//getProgramIcon.clicked.connect(lambda: RunWineProgram(f"{programPath}/BeCyIconGrabber.exe' '{e2.currentText()}" if e2.currentText()[:2].upper() == "C:" else f"{programPath}/BeCyIconGrabber.exe' 'z:/{e2.currentText()}"));
programManager->addWidget(getProgramIcon, 1, 0, 1, 1);
programManager->addWidget(new QLabel(" "), 1, 1, 1, 1);
trasButton = new QPushButton(QObject::tr("窗口透明工具"));
//trasButton.clicked.connect(lambda: RunWineProgram(f"{programPath}/窗体透明度设置工具.exe"));
programManager->addWidget(trasButton, 1, 2, 1, 1);
uninstallProgram = new QPushButton(QObject::tr("卸载程序"));
//uninstallProgram.clicked.connect(lambda: RunWineProgram(f"{programPath}/geek.exe"));
programManager->addWidget(new QLabel(" "), 1, 3, 1, 1);
programManager->addWidget(uninstallProgram, 1, 4, 1, 1);
miniAppStore = new QPushButton(QObject::tr("微型应用商店"));
//miniAppStore.clicked.connect(lambda: threading.Thread(target=MiniAppStore).start());
programManager->addWidget(new QLabel(" "), 1, 5, 1, 1);
programManager->addWidget(miniAppStore, 1, 6, 1, 1);
programManager->addWidget(new QLabel(" "), 1, 7, 1, 1);
QPushButton *getProgramStatus = new QPushButton(QObject::tr("获取该程序运行情况"));
//getProgramStatus.clicked.connect(ProgramRunStatusShow.ShowWindow);
programManager->addWidget(getProgramStatus, 1, 8, 1, 1);
QPushButton *getLoseDll = new QPushButton(QObject::tr("检测静态下程序缺少DLL"));
//getLoseDll.clicked.connect(GetLoseDll);
programManager->addWidget(new QLabel(" "), 1, 9, 1, 1);
programManager->addWidget(getLoseDll, 1, 10, 1, 1);
programManager->addItem(new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum), 1, 11, 1, 1);
programManager->addWidget(new QLabel(QObject::tr("WINE配置:")), 2, 0, 1, 1);
wineConfig = new QPushButton(QObject::tr("配置容器"));
//wineConfig.clicked.connect(lambda: RunWineProgram("winecfg"));
programManager->addWidget(wineConfig, 3, 0, 1, 1);
QPushButton *fontAppStore = new QPushButton(QObject::tr("字体商店"));
//fontAppStore.clicked.connect(FontAppStore);
programManager->addWidget(fontAppStore, 3, 2, 1, 1);
button_r_6 = new QPushButton(QObject::tr("RegShot"));
//button_r_6.clicked.connect(lambda: RunWineProgram(f"{programPath}/RegShot/regshot.exe"));
programManager->addWidget(button_r_6, 3, 4, 1, 1);
QPushButton *sparkWineSetting = new QPushButton(QObject::tr("星火wine配置"));
//sparkWineSetting.clicked.connect(lambda: threading.Thread(target=os.system, args=["bash /opt/durapps/spark-dwine-helper/spark-dwine-helper-settings/settings.sh"]).start());
programManager->addWidget(sparkWineSetting, 3, 6, 1, 1);
QPushButton *wineAutoConfig = new QPushButton(QObject::tr("自动/手动配置 Wine 容器"));
//wineAutoConfig.clicked.connect(WineBottonAutoConfig);
programManager->addWidget(wineAutoConfig, 3, 8, 1, 1);
QPushButton *wineBottleReboot = new QPushButton(QObject::tr("重启指定Wine容器"));
//wineBottleReboot.clicked.connect(lambda: RunWineProgram(f"wineboot' '-k"));
programManager->addWidget(wineBottleReboot, 3, 10, 1, 1);
// 权重
button5->setSizePolicy(size);
saveDesktopFileOnLauncher->setSizePolicy(size);
label_r_2->setSizePolicy(size);
getProgramIcon->setSizePolicy(size);
//trasButton.setSizePolicy(size);
button_r_6->setSizePolicy(size);
wineConfig->setSizePolicy(size);
QTextBrowser *returnText = new QTextBrowser();
returnText->setStyleSheet("background-color: black;"\
"color: white;");
returnText->setText(QObject::tr("在此可以看到wine安装应用时的终端输出内容\n"\
"=============================================\n"\
"如果解决了你的问题,请不要吝啬你的star哟!\n"\
"地址:\n"\
"https://gitee.com/gfdgd-xi/deep-wine-runner\n"\
"https://github.com/gfdgd-xi/deep-wine-runner\n"\
"https://sourceforge.net/projects/deep-wine-runner"));
mainLayout->setRowStretch(0, 2);
mainLayout->setRowStretch(1, 1);
mainLayout->setColumnStretch(0, 2);
mainLayout->setColumnStretch(1, 1);
mainLayout->addWidget(returnText, 0, 1, 2, 1);
// 版权
QLabel *copy = new QLabel("程序版本:{version}<b>提示:Wine 无法保证可以运行所有的 Windows 程序,如果想要运行更多 Windows 程序,可以考虑虚拟机和双系统</b><br/>"\
"<b>注:部分二进制兼容层会自动注册 binfmt(如原版的 Box86/64、Qemu User Static),则意味着无需在 Wine 版本那里特别指定兼容层,直接指定 Wine 即可</b><br/>"\
"©2020~" + QDateTime(QDateTime::currentDateTime()).toString("yyyy") + " gfdgd xi");
mainLayout->addWidget(copy, 2, 0, 1, 1);
// 程序运行
QWidget *programRun = new QWidget();
QHBoxLayout *programRunLayout = new QHBoxLayout();
programRun->setLayout(programRunLayout);
programRunLayout->addItem(new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum));
QPushButton *button3 = new QPushButton(QObject::tr("运行程序"));
//button3.clicked.connect(runexebutton);
programRunLayout->addWidget(button3);
QPushButton *killProgram = new QPushButton(QObject::tr("终止程序"));
//killProgram.clicked.connect(KillProgram);
programRunLayout->addWidget(killProgram);
QPushButton *killBottonProgram = new QPushButton(QObject::tr("终止指定容器的程序"));
//killBottonProgram.clicked.connect(lambda: threading.Thread(target=os.system, args=[f"'{programPath}/kill.sh' '{os.path.basename(e1.currentText())}'"]).start());
programRunLayout->addWidget(killBottonProgram);
mainLayout->addWidget(programRun, 2, 1, 1, 1);
// 窗口设置
window->resize(widget->frameGeometry().width() * 2, widget->frameGeometry().height());
window->setWindowIcon(QIcon(":/Icon/deepin-wine-runner.svg"));
widget->setLayout(mainLayout);
window->show();
CheckWine();
// 控件设置
e1->addItems(findExeHistory);
e2->addItems(wineBottonHistory);
combobox1->addItems(shellHistory);
o1->addItems(canUseWine);
// 一个 Wine 都没有却用 Wine 的功能
// 还是要处理的,至少不会闪退
if(o1->currentText() == ""){
o1->addItem("没有识别到任何Wine,请在菜单栏“程序”安装Wine或安装任意Wine应用");
}
QObject::connect(button3, &QPushButton::clicked, [&](){
Runexebutton_threading *thread = new Runexebutton_threading();
//QObject::connect(thread, &Runexebutton_threading::signal, this, [this](){});
thread->start();
});
}
void MainWindow::Runexebutton_threading::run(){
QString programPath = QCoreApplication::applicationDirPath();
QString wineBottlePath = "";
if(e1->currentText() == ""){
wineBottlePath = setting.value("DefultBotton");
}
else{
wineBottlePath = e1->currentText();
}
QString option = "";
if(setting.value("Architecture") != "Auto"){
option += "WINEARCH=" + setting.value("Architecture") + " ";
}
if(setting.value("MonoGeckoInstaller") == "1"){
option += "WINEDLLOVERRIDES=\"mscoree,mshtml=\" ";
}
if(setting.value("") != "1"){
option += "WINEDEBUG=-all ";
}
else{
option += "WINEDEBUG=FIXME,ERR,WARN,TRACE,Message ";
}
QString wineUsingOption = "";
QString exePath = e2->currentText();
QStringList fileName = {".exe"};
bool changePath = false;
for(QString i: fileName){
if(exePath.contains(i)){
qDebug() << i;
qDebug() << exePath;
int l = exePath.indexOf(i);
exePath = exePath.mid(0, l + 4) + "' " + exePath.mid(l + 4) + " '";
qDebug() << l;
qDebug() << exePath;
changePath = true;
break;
}
}
if(!changePath && QFile::exists(exePath)){
// 删除前后无用空格以防止出现问题
qDebug() << exePath;
exePath = exePath.trimmed();
// 有空格再说
if(exePath.contains(" ")){
int l = exePath.indexOf(" ");
exePath = exePath.mid(0, l) + "' " + exePath.mid(l) + " '";
qDebug() << l;
}
qDebug() << exePath;
}
if(o1->currentText() == "基于 UOS exagear 的 deepin-wine6-stable" ||
o1->currentText() == "基于 UOS box86 的 deepin-wine6-stable"){
wineUsingOption = "";
}
if(o1->currentText() == "基于 UOS box86 的 deepin-wine6-stable" ||
o1->currentText() == "基于 UOS exagear 的 deepin-wine6-stable"){
if(!QDir(programPath + "/dlls-arm").exists()){
if(system(("7z x -y \"" + programPath + "/dlls-arm.7z\" -o\"" + programPath + "\"").toUtf8())){
QMessageBox::critical(NULL, "错误", "无法解压资源");
return;
}
QFile::remove(programPath + "/dlls-arm.7z");
}
}
//QString runCommand = "";
QString runCommand = "";
QProcess *process = new QProcess();
//if(setting.value("TerminalOpen") == "True"){
if(0){
if(e2->currentText().mid(-4) == ".msi" && QFile::exists(e2->currentText())){
runCommand = "env WINEPREFIX='" + wineBottlePath + "' " + option + wine[o1->currentText()] + " msiexec /i '" + e2->currentText() + "' " + setting.value("WineOption");
// OpenTerminal(runCommand)
}
// ……
}
else{
if(e2->currentText().mid(-4) == ".msi" && QFile::exists(e2->currentText())){
runCommand = "env WINEPREFIX='" + wineBottlePath + "' " + option + wine[o1->currentText()] + " msiexec /i '" + e2->currentText() + "' " + setting.value("WineOption");
}
else if(e2->currentText().mid(-4) == ".bat" && QFile::exists(e2->currentText())){
runCommand = "WINEPREFIX='" + wineBottlePath + "' " + option + wine[o1->currentText()] + " wineconsole '" + e2->currentText() + "' " + setting["WineOption"];
}
else{
runCommand = "WINEPREFIX='" + wineBottlePath + "' " + option + wine[o1->currentText()] + " '" + exePath + "' " + setting["WineOption"];
}
}
// 实时读取程序返回
qDebug() << runCommand;
lastRunCommand = runCommand;
// 连接槽
connect(process, &QProcess::readyReadStandardOutput, this, [this, process](){
//emit this->signal(QString::fromUtf8(process.readAll()));
});
//if(setting.value("TerminalOpen") != "True"){
if(1){
process->setReadChannel(QProcess::StandardOutput);
process->start(runCommand);
process->waitForStarted();
process->waitForFinished();
process->close();
}
// ……
}
void MainWindow::DisableButton(bool things){
button_r_6->setDisabled(things);
button1->setDisabled(things);
button2->setDisabled(things);
button3->setDisabled(things);
wineConfig->setDisabled(things);
e1->setDisabled(things);
e2->setDisabled(things);
o1->setDisabled(things);
miniAppStore->setDisabled(things);
//winetricksOpen->configure(state=a[things])
getProgramIcon->setDisabled(things);
uninstallProgram->setDisabled(things);
trasButton->setDisabled(things);
}
void MainWindow::runexebutton(){
DisableButton(1);
}
MainWindow::~MainWindow()
{
//delete ui;
}
QString MainWindow::get_home(){
return QDir::homePath();
}
QString MainWindow::readtxt(QString path){
QFile file(path);
file.open(QIODevice::ReadOnly);
QString things = file.readAll();
file.close();
return things;
}
QByteArray MainWindow::readtxtByte(QString path){
QFile file(path);
file.open(QIODevice::ReadOnly);
QByteArray things = file.readAll();
file.close();
return things;
}
void MainWindow::write_txt(QString path, QByteArray things){
QFile file(path);
file.open(QIODevice::WriteOnly);
file.write(things);
file.close();
}
QString MainWindow::GetCommandResult(QString command){
QProcess process;
process.start(command);
process.waitForStarted();
process.waitForFinished();
QString result = process.readAll();
process.close();
return result;
}
/*
* 检测 Wine
*/
void MainWindow::CheckWine(){
QStringList wine7zUse = {"wine", "wine64", "wine-i386", "wine-aarch64", "wine-x86_64"};
wine.clear();
wine.insert("基于 UOS box86 的 deepin-wine6-stable",
"WINEPREDLL='" + programPath + "/dlls-arm' "\
"WINEDLLPATH=/opt/deepin-wine6-stable/lib BOX86_NOSIGSEGV=1 "\
"/opt/deepin-box86/box86 /opt/deepin-wine6-stable/bin/wine ");
wine.insert("基于 UOS exagear 的 deepin-wine6-stable",
"WINEPREDLL='" + programPath + "/dlls-arm' WINEDLLPATH=/opt/deepin-wine6-stable/lib"\
" /opt/exagear/bin/ubt_x64a64_al --path-prefix " + get_home() + "/.deepinwine/debian-buster --utmp-paths-list " + get_home() + ""\
"/.deepinwine/debian-buster/.exagear/utmp-list --vpaths-list " + get_home() + "/.deepinwine/debian-buster/.exagear/vpaths-list"\
" --opaths-list " + get_home() + "/.deepinwine/debian-buster/.exagear/opaths-list --smo-mode fbase --smo-severity smart "\
"--fd-limit 8192 --foreign-ubt-binary /opt/exagear/bin/ubt_x32a64_al -- /opt/deepin-wine6-stable/bin/wine ");
wine.insert("使用 Flatpak 安装的 Wine", "flatpak run org.winehq.Wine");
wine.insert("deepin-wine8-stable", "deepin-wine8-stable");
wine.insert("deepin-wine6 stable", "deepin-wine6-stable");
wine.insert("deepin-wine6-vannila", "deepin-wine6-vannila");
wine.insert("deepin-wine5 stable", "deepin-wine5-stable");
wine.insert("spark-wine", "spark-wine");
wine.insert("spark-wine7-devel", "spark-wine7-devel");
wine.insert("spark-wine8", "spark-wine8");
wine.insert("spark-wine8-wow", "spark-wine8-wow");
wine.insert("deepin-wine", "deepin-wine");
wine.insert("deepin-wine5", "deepin-wine5");
wine.insert("wine", "wine");
wine.insert("wine64", "wine64");
wine.insert("ukylin-wine", "ukylin-wine");
wine.insert("okylin-wine", "okylin-wine");
wine.insert("mono(这不是 wine,但可以实现初步调用运行 .net 应用)", "mono");
wine.insert("基于 linglong 的 deepin-wine6-stable(不推荐)", "ll-cli run '' --exec '/bin/deepin-wine6-stable'");
if(QFile::exists("/opt/deepin-box86/box86") && QFile::exists("/opt/deepin-wine6-stable/bin/wine")){
canUseWine.append("基于 UOS box86 的 deepin-wine6-stable");
}
if(QFile::exists("/opt/exagear/bin/ubt_x64a64_al") && QFile::exists("/opt/deepin-wine6-stable/bin/wine")){
canUseWine.append("基于 UOS exagear 的 deepin-wine6-stable");
}
for(QString i : wine.keys()){
if(!system(("which '" + wine.key(i) + "'").toUtf8())){
canUseWine.append(i);
}
}
if(!system("which flatpak") && QDir("/var/lib/flatpak/app/org.winehq.Wine").exists()){
canUseWine.append("使用 Flatpak 安装的 Wine");
}
if(QDir("/persistent/linglong/layers/").exists()){ // 判断是否使用 linglong
for(QString i : QDir("/persistent/linglong/layers/").entryList()){
try{
break; // bug
QString dire = QDir("/persistent/linglong/layers/" + i).entryList()[-1];
QString arch = QDir("/persistent/linglong/layers/" + i + "/" + dire)[-1];
if(QFile::exists("/persistent/linglong/layers/" + i + "/" + dire + "/" + arch + "/runtime/bin/deepin-wine6-stable")){
wine.insert("基于 linglong 的 deepin-wine6-stable(不推荐)", "ll-cli run " + i + " --exec '/bin/deepin-wine6-stable'");
canUseWine.append("基于 linglong 的 deepin-wine6-stable(不推荐)");
break;
}
}
catch(QString msg){
qDebug() << msg;
}
}
}
// 读取自定义安装的 Wine(需要解包的才能使用)
if(!system("which qemu-i386-static")){
if(QDir(qemuPath).exists()){
for(QString g: QDir(qemuPath).entryList()){
QString archPath = qemuPath + "/" + g;
QString arch = g;
if(QFileInfo(archPath).isDir()){
for(QString d: QDir(archPath).entryList()){
QString bottlePath = archPath + "/" + g;
if(QFileInfo(bottlePath).isDir()){
qemuBottleList.append(QStringList() << arch << d << bottlePath);
}
}
}
}
}
}
QJsonParseError jsonError;
QJsonDocument jsonDocument;
QJsonObject jsonObject;
QStringList historyList[] = {shellHistory, findExeHistory, wineBottonHistory, isoPath, isoPathFound};
QStringList historyListPath = {homePath + "/.config/deepin-wine-runner/ShellHistory.json",
homePath + "/.config/deepin-wine-runner/FindExeHistory.json",
homePath + "/.config/deepin-wine-runner/WineBottonHistory.json",
homePath + "/.config/deepin-wine-runner/ISOPath.json",
homePath + "/.config/deepin-wine-runner/ISOPathFound.json"};
for(int i = 0; i <= historyList->size(); i++){
QStringList *list = &historyList[i];
jsonDocument = QJsonDocument(QJsonDocument::fromJson(readtxtByte(historyListPath[i])));
jsonObject = jsonDocument.object();
list->clear();
for(QString i: jsonObject.keys()){
list->append(jsonObject.value(i).toString());
}
}
qDebug() << jsonError.errorString();
jsonDocument = QJsonDocument(QJsonDocument::fromJson(readtxtByte(homePath + "/.config/deepin-wine-runner/WineSetting.json")));
jsonObject = jsonDocument.object();
setting.clear();
for(QString i: jsonObject.keys()){
setting.insert(i, jsonObject.value(i).toString());
}
for(QString i: QDir(programPath + "/wine/").entryList()){
if(QDir(programPath + "/wine/" + i).exists() && QFileInfo(programPath + "/wine/" + i).isDir()){
QStringList nameValue = {{"", ""}};
try{
if(QFile::exists("/opt/deepin-box86/box86")){
nameValue.append(QStringList() << "基于 UOS box86 的 " <<
"WINEPREDLL='" + programPath + "/dlls-arm' WINEDLLPATH=/opt/deepin-wine6-stable/lib BOX86_NOSIGSEGV=1"\
" /opt/deepin-box86/box86 ");
}
if(!system("which box86")){
nameValue.append(QStringList() << "基于 box86 的 " << "box86 ");
}
if(!system("which box64")){
nameValue.append(QStringList() << "基于 box64 的 " << "box64 ");
}
if(!system("which qemu-i386") &&
GetCommandResult("arch").replace(" ", "").replace("\n", "") != "x86_64" &&
GetCommandResult("arch").replace(" ", "").replace("\n", "") != "i686"){
nameValue.append(QStringList() << "基于 qemu-i386 的 " << "qemu-i386 ");
}
if(!system("which qemu-x86_64") &&
GetCommandResult("arch").replace(" ", "").replace("\n", "") != "x86_64" &&
GetCommandResult("arch").replace(" ", "").replace("\n", "") != "i686"){
nameValue.append(QStringList() << "基于 qemu-x86_64 的 " << "qemu-x86_64 ");
}
if(QFile::exists("/opt/exagear/bin/ubt_x64a64_al") && QFile::exists(homePath + "/.deepinwine/debian-buster")){
nameValue.append(QStringList() << "基于 UOS exagear 的 " << "WINEPREDLL='" + programPath + "/dlls-arm' "\
"WINEDLLPATH=/opt/deepin-wine6-stable/lib /opt/exagear/bin/ubt_x64a64_al --path-prefix " + get_home() + "/.deepinwine/debian-buster "\
"--utmp-paths-list " + homePath + "/.deepinwine/debian-buster/.exagear/utmp-list --vpaths-list " + homePath + "/.deepinwine/debian-buster/.exagear/vpaths-list "\
"--opaths-list " + homePath + "/.deepinwine/debian-buster/.exagear/opaths-list --smo-mode fbase --smo-severity smart --fd-limit 8192 --foreign-ubt-binary /opt/exagear/bin/ubt_x32a64_al -- ");
}
if(!system("which exagear")){
nameValue.append(QStringList() << "运行 exagear 容器内的 " << "exagear -- ");
}
if(QFile::exists("/opt/exagear/bin/ubt_x64a64_al")){
nameValue.append(QStringList() << "使用 ubt_x64a64_al 运行" << "/opt/exagear/bin/ubt_x64a64_al -- ");
}
if(QFile::exists("/opt/exagear/bin/ubt_x32a64_al")){
nameValue.append(QStringList() << "使用 ubt_x32a64_al 运行" << "/opt/exagear/bin/ubt_x32a64_al -- ");
}
/*for(QString g: qemuBottleList){
nameValue.append(QStringList() << "使用qemu-" + g[0] + "-static 调用容器" + g[1] + "运行 " << "python3 '" + programPath + "/QemuRun.py' '" + g[0] + "/" + g[1] + "' " + setting.value("QemuUnMountHome").toInt());
}*/
}
catch(QString msg){
qDebug() << msg;
}
/*for(QString k: nameValue){
qDebug() << k;
if(k.contains("qemu")){
}
}*/
try{
for(QString i: QDir(homePath + "/.deepinwine/").entryList()){
for(QString j: wine7zUse){
if(QFile::exists(homePath + "/.deepinwine/" + i + "/bin/" + j)){
wine.insert(homePath + "/.deepinwine/" + i + "/bin/" + j, homePath + "/.deepinwine/" + i + "/bin/" + j);
canUseWine.append(homePath + "/.deepinwine/" + i + "/bin/" + j);
}
}
}
}
catch(QString msg){
qDebug() << msg;
}
try{
QStringList canUseWineOld = canUseWine;
for(QString i: canUseWineOld){
if(QDir(programPath + "/WineLib/usr").exists()){
wine.insert("使用运行器的运行库运行 " + i, "bash '" + programPath + "/WineLib/run.sh' " + wine.value(i));
canUseWine.append("使用运行器的运行库运行 " + i);
untipsWine.append("使用运行器的运行库运行 " + i);
}
}
if(QDir("/opt/exagear/images").exists()){
for(QString k: QDir("/opt/exagear/images").entryList()){
if(QFileInfo("/opt/exagear/images/" + k).isDir()){
continue;
}
for(QString i: canUseWineOld){
wine.insert("使用Exagear容器运行库运行 " + i, "bash '" + programPath + "/WineLib/run-more.sh' '/opt/exagear/images/" + k + "' " + wine.value(i));
canUseWine.append("使用Exagear容器运行库运行 " + i);
untipsWine.append("使用Exagear容器运行库运行 " + i);
}
}
}
}
catch(QString msg){
qDebug() << msg;
}
}
}
}
+65
View File
@@ -0,0 +1,65 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMap>
#include <QDir>
#include <QCoreApplication>
#include <QPushButton>
#include <QComboBox>
#include <QThread>
class MainWindow
{
public:
MainWindow();
~MainWindow();
void CheckWine();
QString get_home();
QString readtxt(QString path);
void write_txt(QString path, QByteArray things);
QByteArray readtxtByte(QString path);
QString GetCommandResult(QString command);
private:
class Runexebutton_threading: public QThread{
signals:
void signal(QString str);
void showHistory(QString str);
public:
void run();
};
void runexebutton();
void DisableButton(bool things);
static QString lastRunCommand;
QString homePath = QDir::homePath();
QString programPath = QCoreApplication::applicationDirPath();
static QMap<QString, QString> wine;
QStringList untipsWine = {"使用 Flatpak 安装的 Wine", "基于 exagear 的 deepin-wine6-stable", "基于 UOS box86 的 deepin-wine6-stable", "基于 UOS exagear 的 deepin-wine6-stable", "基于 linglong 的 deepin-wine6-stable(不推荐)"};
QStringList canUseWine = {};
QStringList qemuBottleList = {};
QString qemuPath = homePath + "/.deepin-wine-runner-ubuntu-images";
QStringList shellHistory;
QStringList findExeHistory;
QStringList wineBottonHistory;
QStringList isoPath;
QStringList isoPathFound;
static QMap<QString, QString> setting;
// 控件
QPushButton *button_r_6;
QPushButton *button1;
QPushButton *button2;
QPushButton *button3;
QPushButton *wineConfig;
QPushButton *miniAppStore;
QPushButton *getProgramIcon;
QPushButton *uninstallProgram;
QPushButton *trasButton;
static QComboBox *e1;
static QComboBox *e2;
static QComboBox *o1;
};
#endif // MAINWINDOW_H
+72
View File
@@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="window">
<layout class="QGridLayout" name="gridLayout" rowstretch="2,0" columnstretch="2,0">
<item row="0" column="0">
<widget class="QWidget" name="leftUp" native="true"/>
</item>
<item row="0" column="1">
<widget class="QTextBrowser" name="returnText">
<property name="styleSheet">
<string notr="true">background-color: black;
color: white;</string>
</property>
<property name="html">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Noto Sans CJK SC'; font-size:10.5pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Noto Mono'; font-size:11pt;&quot;&gt;在此可以看到wine安装应用时的终端输出内容&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Noto Mono'; font-size:11pt;&quot;&gt;=============================================&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Noto Mono'; font-size:11pt;&quot;&gt;如果解决了你的问题,请不要吝啬你的star哟!&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Noto Mono'; font-size:11pt;&quot;&gt;地址:&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Noto Mono'; font-size:11pt;&quot;&gt;https://gitee.com/gfdgd-xi/deep-wine-runner&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Noto Mono'; font-size:11pt;&quot;&gt;https://github.com/gfdgd-xi/deep-wine-runner&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Noto Mono'; font-size:11pt;&quot;&gt;https://sourceforge.net/projects/deep-wine-runner&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QWidget" name="leftDown" native="true"/>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>36</height>
</rect>
</property>
<widget class="QMenu" name="menu">
<property name="title">
<string>程序</string>
</property>
<addaction name="action"/>
</widget>
<addaction name="menu"/>
</widget>
<action name="action">
<property name="text">
<string>退出程序</string>
</property>
</action>
</widget>
<resources/>
<connections/>
</ui>
+14
View File
@@ -0,0 +1,14 @@
#include "qr.h"
#include "ui_qr.h"
QR::QR(QWidget *parent) :
QDialog(parent),
ui(new Ui::QR)
{
ui->setupUi(this);
}
QR::~QR()
{
delete ui;
}
+22
View File
@@ -0,0 +1,22 @@
#ifndef QR_H
#define QR_H
#include <QDialog>
namespace Ui {
class QR;
}
class QR : public QDialog
{
Q_OBJECT
public:
explicit QR(QWidget *parent = nullptr);
~QR();
private:
Ui::QR *ui;
};
#endif // QR_H
+69
View File
@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QR</class>
<widget class="QDialog" name="QR">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>656</width>
<height>410</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<property name="windowIcon">
<iconset resource="Resources.qrc">
<normaloff>:/Icon/deepin-wine-runner.svg</normaloff>:/Icon/deepin-wine-runner.svg</iconset>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTextBrowser" name="qRShow">
<property name="html">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Noto Sans CJK SC'; font-size:10.5pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:11pt;&quot;&gt;如果您觉得 Wine 运行器对你有帮助,可以请作者喝杯茶&lt;/span&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;微信:&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;img src=&quot;:/Icon/QR/Icon/QR/Wechat.png&quot; width=&quot;256&quot; /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;支付宝:&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;img src=&quot;:/Icon/QR/Icon/QR/Alipay.jpg&quot; width=&quot;256&quot; /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;QQ&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;img src=&quot;:/Icon/QR/Icon/QR/QQ.png&quot; width=&quot;256&quot; /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="ok">
<property name="text">
<string>确定</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources>
<include location="Resources.qrc"/>
</resources>
<connections/>
</ui>