1 Star 0 Fork 26

laranlan/Wine 运行器

forked from gfdgd xi/Wine 运行器 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
mainwindow.py 184.98 KB
一键复制 编辑 原始数据 按行查看 历史
gfdgd xi 提交于 2023-12-25 22:18 . 3.6.1
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421
#!/usr/bin/env python3
# 使用系统默认的 python3 运行
#################################################################################################################
# 作者:gfdgd xi
# 版本:3.0.0
# 更新时间:2022年12月10日
# 感谢:感谢 wine、deepin-wine 以及星火团队,提供了 wine、deepin-wine、spark-wine-devel 给大家使用,让我能做这个程序
# 基于 Python3 的 PyQt5 构建
#################################################################################################################
#################
# 引入所需的库
#################
import os
import sys
import time
import json
import random
import base64
import shutil
import hashlib
import platform
import pyperclip
import threading
import traceback
import webbrowser
import updatekiller
import subprocess
import req as requests
import urllib.parse as parse
import PyQt5.QtGui as QtGui
import PyQt5.QtCore as QtCore
import PyQt5.QtWidgets as QtWidgets
try:
import PyQt5.QtWebEngineWidgets as QtWebEngineWidgets
bad = False
except:
bad = True
from trans import *
from Model import *
from DefaultSetting import *
def PythonLower():
app = QtWidgets.QApplication(sys.argv)
QtWidgets.QMessageBox.critical(None, "错误", "Python 至少需要 3.6 及以上版本,目前版本:" + platform.python_version() + "")
sys.exit(1)
# Python 版本检测,因为 f-string 格式化要至少 Python 3.6 及以上的版本,所以需要检测
# 判断主版本号
if sys.version_info[0] < 3:
PythonLower()
if sys.version_info[1] < 6:
PythonLower()
###################
# 程序所需事件
###################
def MiniMode(mode):
for i in [sparkWineSetting, qemuMenu, installLib, log, safeWebsize,
checkValue, virtualMachine, killProgram, killBottonProgram,
fontAppStore, wineConfig, trasButton, button5,
saveDesktopFileOnLauncher, label_r_2, combobox1,
leftDown]:
i.setVisible(not mode)
# 打开程序官网
def OpenProgramURL():
webbrowser.open_new_tab(programUrl)
# 读取文本文档
def readtxt(path):
f = open(path, "r") # 设置文件对象
str = f.read() # 获取内容
f.close() # 关闭文本对象
return str # 返回结果
# 写入文本文档
def write_txt(path, things):
file = open(path, 'w', encoding='UTF-8') # 设置文件对象
file.write(things) # 写入文本
file.close() # 关闭文本对象
# 获取用户桌面目录
def get_desktop_path():
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 # 返回目录
# 获取用户主目录
def get_home():
return os.path.expanduser('~')
# 第一个浏览按钮事件
def liulanbutton():
path = QtWidgets.QFileDialog.getExistingDirectory(widget, "选择 wine 容器", json.loads(readtxt(get_home() + "/.config/deepin-wine-runner/WineBotton.json"))["path"])
if path != "" and path != "()":
e1.setEditText(path)
write_txt(get_home() + "/.config/deepin-wine-runner/WineBotton.json", json.dumps({"path": path})) # 写入配置文件
# 第二个浏览按钮事件
def liulanexebutton():
path = QtWidgets.QFileDialog.getOpenFileName(widget, "选择 exe 可执行文件", json.loads(readtxt(get_home() + "/.config/deepin-wine-runner/FindExe.json"))["path"], "exe 可执行文件(*.exe);;MSI 文件(*.msi);;所有文件(*.*)")
if path != "" and path != "()":
e2.setEditText(path[0]) # 显示路径
write_txt(get_home() + "/.config/deepin-wine-runner/FindExe.json", json.dumps({"path": os.path.dirname(path[0])})) # 写入配置文件
run = None
# 使用多线程运行可执行文件
def runexebutton(self):
global run
DisableButton(True)
if not CheckProgramIsInstall(wine[o1.currentText()]) and not o1.currentText() in untipsWine:
if QtWidgets.QMessageBox.question(widget, "提示", "检查到您未安装这个 wine,是否继续使用这个 wine 运行?") == QtWidgets.QMessageBox.No:
DisableButton(False)
return
if e2.currentText() == "": # 判断文本框是否有内容
QtWidgets.QMessageBox.information(widget, "提示", "没有填写需要使用的 exe 应用")
DisableButton(False)
return
returnText.setText("")
run = Runexebutton_threading()
run.signal.connect(QT.ShowWineReturn)
run.showHistory.connect(QT.ShowHistory)
run.start()
class QT:
message = None
def ShowWineReturn(things):
returnText.insertPlainText(things)
def ShowHistory(temp):
e1.clear()
e2.clear()
e2.addItems(wineBottonHistory)
e2.setEditText(wineBottonHistory[-1])
e1.addItems(findExeHistory)
e1.setEditText(findExeHistory[-1])
repairList = []
# Flag: 日志推断解决方案功能
class LogChecking():
def ShowWindow():
global logThread
global logWindow
global questionList
global repairButton
logWindow = QtWidgets.QWidget()
logWindowLayout = QtWidgets.QGridLayout()
questionList = QtWidgets.QListView()
repairButton = QtWidgets.QPushButton("一键修复")
repairButton.setDisabled(True)
repairButton.clicked.connect(LogChecking.RepairButton)
nmodel = QtGui.QStandardItemModel(window)
item = QtGui.QStandardItem("正在分析中……")
questionList.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
nmodel.appendRow(item)
questionList.setModel(nmodel)
logWindowLayout.addWidget(questionList, 0, 0, 3, 1)
logWindowLayout.addWidget(repairButton, 0, 2, 1, 1)
logWindow.setWindowTitle("分析日志")
logWindow.setLayout(logWindowLayout)
logThread = LogThreading()
logThread.done.connect(LogChecking.Show)
logThread.start()
logWindow.setWindowIcon(QtGui.QIcon(f"{programPath}/deepin-wine-runner.svg"))
logWindow.resize(int(logWindow.frameGeometry().width() * 1.2), int(logWindow.frameGeometry().height() * 1.2))
logWindow.show()
def RepairButton():
index = questionList.currentIndex().row()
lists = questionMap[index]
print(f"{programPath}/CheckDLL/bash/{lists[1].lower()}.sh")
if lists[0] == 1 and os.path.exists(f"{programPath}/CheckDLL/bash/{lists[1].lower()}.sh"):
OpenTerminal(f"'{programPath}/AutoShell/main.py' '{programPath}/CheckDLL/bash/{lists[1].lower()}.sh'")
return
if lists[0] == 2:
QtWidgets.QMessageBox.information(logWindow, "修复方法", "切换其它 Wine")
return
if lists[0] == 4:
QtWidgets.QMessageBox.information(logWindow, "修复方法", "如是 Deepin Wine 可以尝试切换 WineHQ,\n并且取消勾选运行器主页面菜单栏“程序”=>“设置Wine”,取消勾选“屏蔽 Wine 默认 Mono 和 Gecko 安装器”\n然后尝试在菜单栏的“Wine”=>“在指定 Wine、容器安装组件”=>“在指定 Wine、容器安装 Gecko”来安装 Gecko")
return
if lists[0] == 5:
InstallMonoGecko("mono")
return
QtWidgets.QMessageBox.critical(logWindow, "错误", "无法修复该问题")
def Show(lists):
global questionMap
nmodel = QtGui.QStandardItemModel(window)
disbledButton = False
print(lists)
if not len(lists):
nmodel.appendRow(QtGui.QStandardItem(f"√ 无法分析到错误"))
disbledButton = True
for i in lists:
if i[0] == 0:
nmodel.appendRow(QtGui.QStandardItem(f"√ 无法分析到错误"))
disbledButton = True
break
if i[0] == 1:
nmodel.appendRow(QtGui.QStandardItem(f"× 无法调用 Dll:{i[1]}"))
if i[0] == 2:
nmodel.appendRow(QtGui.QStandardItem(f"× 尝试用 Mono 运行非 .net 应用 {i[1]}?"))
if i[0] == 3:
nmodel.appendRow(QtGui.QStandardItem(f"! 无法加载 Gecko,是被禁用或未安装?"))
if i[0] == 4:
nmodel.appendRow(QtGui.QStandardItem(f"× 无法更新 Wine 容器版本,是否还有 Wine 程序运行?"))
if i[0] == 5:
nmodel.appendRow(QtGui.QStandardItem(f"× Mono 禁用/未安装"))
questionMap = lists[:]
repairButton.setDisabled(disbledButton)
questionList.setModel(nmodel)
class LogThreading(QtCore.QThread):
done = QtCore.pyqtSignal(list)
def __init__(self):
super().__init__()
def run(self):
global logText
repairList = []
logText = returnText.toPlainText()
print(logText.splitlines())
for i in logText.splitlines():
print(i)
checkingText = i.lower()
if "err:module:import_dll Library".lower() in checkingText:
# Lose Dll
repairList.append([1, i[i.index("Library") + 8: i.index("(")].strip()])
continue
if "err:module:fixup_imports_ilonly".lower() in checkingText:
# Lose Dll
repairList.append([1, i[i.index("_ilonly") + 8: i.index("not")].strip()])
continue
if "Cannot open assembly".lower() in checkingText and ": File does not contain a valid CIL image.".lower() in checkingText:
# Mono
repairList.append([2, i.replace(": File does not contain a valid CIL image.", "").replace("Cannot open assembly", "").strip()[1: -1]])
if "Could not load wine-gecko. HTML rendering will be disabled.".lower() in checkingText and "Could not find Wine Gecko. HTML rendering will be disabled.".lower() in checkingText:
# Disbled Gecko
repairList.append([3, ""])
if "Your wineserver binary was not upgraded correctly".lower() in checkingText:
repairList.append([4, ""])
if "Wine Mono is not installed".lower() in checkingText:
repairList.append([5, ""])
self.done.emit(repairList)
def DisableButton(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)
def CheckProgramIsInstall(program):
return not bool(os.system(f"which '{program}'"))
class Runexebutton_threading(QtCore.QThread):
signal = QtCore.pyqtSignal(str)
showHistory = QtCore.pyqtSignal(str)
def __init__(self):
super().__init__()
def run(self):
global lastRunCommand
if e1.currentText() == "":
wineBottonPath = setting["DefultBotton"]
else:
wineBottonPath = e1.currentText()
option = ""
if setting["Architecture"] != "Auto":
option += f"WINEARCH={setting['Architecture']} "
if setting["MonoGeckoInstaller"]:
option += f"WINEDLLOVERRIDES=\"mscoree,mshtml=\" "
if not setting["Debug"]:
option += "WINEDEBUG=-all "
else:
option += "WINEDEBUG=FIXME,ERR,WARN,TRACE,Message "
wineUsingOption = ""
exePath = e2.currentText()
if True:
fileName = [".exe"]
changePath = False
for i in fileName:
if i in exePath:
print(i)
print(exePath)
l = exePath.index(i)
exePath = f"{exePath[:l+4]}' {exePath[l+4:]} '"
print(l)
print(exePath)
changePath = True
break
#if not changePath and not os.path.exists(changePath):
if not changePath and not os.path.exists(exePath):
# 删除前后无用空格以防止出现问题
print(exePath)
exePath = exePath.strip()
# 有空格再说
if " " in exePath:
l = exePath.index(" ")
exePath = f"{exePath[:l]}' {exePath[l:]} '"
print(l)
#print(i)
print(exePath)
if o1.currentText() == "基于 UOS exagear 的 deepin-wine6-stable" or o1.currentText() == "基于 UOS box86 的 deepin-wine6-stable":
wineUsingOption = ""
if o1.currentText() == "基于 UOS box86 的 deepin-wine6-stable" or o1.currentText() == "基于 UOS exagear 的 deepin-wine6-stable":
if not os.path.exists(f"{programPath}/dlls-arm"):
if os.system(f"7z x -y \"{programPath}/dlls-arm.7z\" -o\"{programPath}\""):
QtWidgets.QMessageBox.critical(widget, "错误", "无法解压资源")
return
os.remove(f"{programPath}/dlls-arm.7z")
if setting["TerminalOpen"]:
res = ""
if e2.currentText()[-4:] == ".msi" and os.path.exists(e2.currentText()):
runCommand = "env WINEPREFIX='" + wineBottonPath + "' " + option + wine[o1.currentText()] + " msiexec /i '" + e2.currentText() + "' " + setting["WineOption"]
OpenTerminal(runCommand)
elif e2.currentText()[-4:] == ".bat" and os.path.exists(e2.currentText()):
runCommand = "env WINEPREFIX='" + wineBottonPath + "' " + option + wine[o1.currentText()] + " wineconsole '" + e2.currentText() + "' " + setting["WineOption"]
OpenTerminal(runCommand)
else:
runCommand = "env WINEPREFIX='" + wineBottonPath + "' " + option + wine[o1.currentText()] + " '" + exePath + "' " + setting["WineOption"]
OpenTerminal(runCommand)
#res = subprocess.Popen([f"'{programPath}/launch.sh' deepin-terminal -C \"WINEPREFIX='" + wineBottonPath + "' " + option + wine[o1.currentText()] + " '" + e2.currentText() + "' " + setting["WineOption"] + "\" --keep-open" + wineUsingOption], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
else:
if e2.currentText()[-4:] == ".msi" and os.path.exists(e2.currentText()):
runCommand = "WINEPREFIX='" + wineBottonPath + "' " + option + wine[o1.currentText()] + " msiexec /i '" + e2.currentText() + "' " + setting["WineOption"]
res = subprocess.Popen([runCommand], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
elif e2.currentText()[-4:] == ".bat" and os.path.exists(e2.currentText()):
runCommand = "WINEPREFIX='" + wineBottonPath + "' " + option + wine[o1.currentText()] + " wineconsole '" + e2.currentText() + "' " + setting["WineOption"]
res = subprocess.Popen([runCommand], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
else:
runCommand = "WINEPREFIX='" + wineBottonPath + "' " + option + wine[o1.currentText()] + " '" + exePath + "' " + setting["WineOption"]
print(["WINEPREFIX='" + wineBottonPath + "' " + option + wine[o1.currentText()] + " '" + exePath + "' " + setting["WineOption"]])
res = subprocess.Popen([runCommand], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
# 实时读取程序返回
#
if not setting["TerminalOpen"]:
while res.poll() is None:
try:
text = res.stdout.readline().decode("utf8")
except:
text = ""
self.signal.emit(text)
print(text, end="")
lastRunCommand = runCommand
print(runCommand)
if len(findExeHistory) == 0 or findExeHistory[-1] != wineBottonPath:
findExeHistory.append(wineBottonPath) # 将记录写进数组
write_txt(get_home() + "/.config/deepin-wine-runner/FindExeHistory.json", str(json.dumps(ListToDictionary(findExeHistory)))) # 将历史记录的数组转换为字典并写入
if len(wineBottonHistory) == 0 or wineBottonHistory[-1] != e2.currentText():
wineBottonHistory.append(e2.currentText()) # 将记录写进数组
write_txt(get_home() + "/.config/deepin-wine-runner/WineBottonHistory.json", str(json.dumps(ListToDictionary(wineBottonHistory)))) # 将历史记录的数组转换为字典并写入
self.showHistory.emit("")
# 针对 QQ、TIM 安装后不会生成 lnk 的问题,由程序读取以及自动创建
# 判断是否安装了 QQ/TIM
for i in iconListUnBuild:
if os.path.exists(i[1].replace("wineBottonPath", wineBottonPath)):
if not os.path.exists(f"{get_home()}/.local/share/applications/wine/{i[0]}-{os.path.basename(wineBottonPath)}.desktop"):
print("图标不存在,创建图标")
# 图标不存在
# 写入 .desktop 文件
try:
os.system(f"mkdir -p '{get_home()}/.local/share/applications/wine'")
name = i[0]
if setting["BuildByBottleName"]:
name = f"{i[0]}——{os.path.basename(wineBottonPath)}"
write_txt(f"{get_home()}/.local/share/applications/wine/{i[0]}-{os.path.basename(wineBottonPath)}.desktop", f'''[Desktop Entry]
Name={name}
Exec=env WINEPREFIX='{wineBottonPath}' {option} {wine[o1.currentText()]} '{i[1].replace("wineBottonPath", wineBottonPath)}' {setting["WineOption"]} {wineUsingOption}
Icon={programPath}/Icon/{i[0]}.svg
Type=Application
StartupNotify=true''')
except:
# 写入不进去就别写入了,当什么事情都没发生就行
traceback.print_exc()
DisableButton(False)
class Temp:
webWindow = None
def OpenUrl(url):
print(url.url())
# 判断是否可以使用小窗打开
if not bad:
'''Temp.webWindow = QtWidgets.QMainWindow()
web = QtWebEngineWidgets.QWebEngineView()
web.setUrl(url)
Temp.webWindow.setWindowTitle("浏览页面")
Temp.webWindow.setCentralWidget(web)
Temp.webWindow.setWindowIcon(QtGui.QIcon(iconPath))
Temp.webWindow.show()
return'''
webbrowser.open_new_tab(url.url())
#QtCore.QUrl().url()
# 显示“关于这个程序”窗口
def about_this_program()->"显示“关于这个程序”窗口":
global about
global title
global iconPath
global clickIconTime
clickIconTime = 0
QT.message = QtWidgets.QMainWindow()
QT.message.setWindowIcon(QtGui.QIcon(iconPath))
messageWidget = QtWidgets.QWidget()
QT.message.setWindowTitle(f"关于 {title}")
messageLayout = QtWidgets.QGridLayout()
iconShow = QtWidgets.QLabel(f"<a href='https://www.gfdgdxi.top'><img width=256 src='{iconPath}'></a>")
def ChangeIcon():
global clickIconTime
if clickIconTime >= 0:
clickIconTime = clickIconTime + 1
if clickIconTime > 5:
clickIconTime = -1
for k in ["", "Function"]:
for i in os.listdir(f"{programPath}/Icon/{k}"):
if i[-4:] == ".svg" or i[-4:] == ".png":
iconPathList.append(f"{programPath}/Icon/{k}/{i}")
randomNumber = random.randint(0, len(iconPathList) - 1)
iconShow.setText(f"<a href='https://www.gfdgdxi.top'><img width=256 src='{iconPathList[randomNumber]}'></a><p align='center'>{randomNumber + 1}/{len(iconPathList)}</p>")
iconShow.linkActivated.connect(ChangeIcon)
messageLayout.addWidget(iconShow, 0, 0, 1, 1, QtCore.Qt.AlignTop)
aboutInfo = QtWidgets.QTextBrowser(messageWidget)
aboutInfo.setFocusPolicy(QtCore.Qt.NoFocus)
#aboutInfo.copyAvailable.connect(lambda: print("b"))
aboutInfo.anchorClicked.connect(OpenUrl)
aboutInfo.setOpenLinks(False)
aboutInfo.setHtml(about)
aboutInfo.setOpenExternalLinks(False)
messageLayout.addWidget(aboutInfo, 0, 1, 1, 1)
ok = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "确定"))
ok.clicked.connect(QT.message.close)
messageLayout.addWidget(ok, 1, 1, 1, 1, QtCore.Qt.AlignBottom | QtCore.Qt.AlignRight)
messageWidget.setLayout(messageLayout)
QT.message.setCentralWidget(messageWidget)
QT.message.resize(int(messageWidget.frameGeometry().width() * 1.5), int(messageWidget.frameGeometry().height() * 1.5))
QT.message.show()
# 显示“提示”窗口
def helps():
global tips
QtWidgets.QMessageBox.information(widget, "提示", tips)
# 显示更新内容窗口
def UpdateThings():
QtWidgets.QMessageBox.information(widget, "更新内容", updateThings)
# 生成 desktop 文件在启动器
def make_desktop_on_launcher():
try:
if combobox1.currentText() == "" or e2.currentText() == "": # 判断文本框是否有内容
QtWidgets.QMessageBox.information(widget, "提示", "没有填写需要使用 exe 应用或保存的文件名")
return
if not CheckProgramIsInstall(wine[o1.currentText()]) and not o1.currentText() in untipsWine:
if QtWidgets.QMessageBox.question(widget, "提示", "检查到您未安装这个 wine,是否继续使用这个 wine 写入?") == QtWidgets.QMessageBox.No:
DisableButton(False)
return
else: # 如果都有
if os.path.exists(get_home() + "/.local/share/applications/" + combobox1.currentText() + ".desktop"): # 判断目录是否有该文件,如果有
choose = QtWidgets.QMessageBox.question(widget, "提示", "文件已经存在,是否覆盖?") == QtWidgets.QMessageBox.Yes
if choose: # 如要覆盖
os.remove(get_home() + "/.local/share/applications/" + combobox1.currentText() + ".desktop") # 删除该文件
else: # 如不覆盖
return # 结束
if e1.currentText() == "":
wineBottonPath = setting["DefultBotton"]
else:
wineBottonPath = e1.currentText()
option = ""
if setting["Architecture"] != "Auto":
option += f"WINEARCH={setting['Architecture']} "
if not setting["Debug"]:
option += "WINEDEBUG=-all "
else:
option += "WINEDEBUG=FIXME,ERR,WARN,TRACE,Message "
wineUsingOption = ""
if o1.currentText() == "基于 UOS box86 的 deepin-wine6-stable" or o1.currentText() == "基于 UOS exagear 的 deepin-wine6-stable":
if not os.path.exists(f"{programPath}/dlls-arm"):
if os.system(f"7z x -y \"{programPath}/dlls-arm.7z\" -o\"{programPath}\""):
QtWidgets.QMessageBox.critical(widget, "错误", "无法解压资源")
return
os.remove(f"{programPath}/dlls-arm.7z")
if o1.currentText() == "基于 UOS exagear 的 deepin-wine6-stable" or o1.currentText() == "基于 UOS box86 的 deepin-wine6-stable":
wineUsingOption = ""
value = ""
if e2.currentText()[:2].upper() == "C:":
value = f"{wineBottonPath}/drive_c/{e2.currentText()[2:]}".replace("\\", "/").replace("//", "/")
print(value)
iconPaths = iconPath
for i in iconList:
listValue = i[1].replace("wineBottonPath", wineBottonPath)
if listValue == e2.currentText() or listValue == value:
# 如果路径相同,即可以用程序对应的图标
iconPaths = f"{programPath}/Icon/{i[0]}.svg"
# 读到了就不需要再读取了
break
os.system(f"mkdir -p '{get_home()}/.local/share/applications/wine'")
write_txt(get_home() + "/.local/share/applications/wine/" + combobox1.currentText() + ".desktop", f'''[Desktop Entry]
Name={combobox1.currentText()}
Exec=env WINEPREFIX='{wineBottonPath}' {option} {wine[o1.currentText()]} '{e2.currentText()}' {setting["WineOption"]} {wineUsingOption}
Icon={iconPaths}
Type=Application
StartupNotify=true''') # 写入文本文档
if len(shellHistory) == 0 or shellHistory[-1] != combobox1.currentText():
shellHistory.append(combobox1.currentText()) # 将记录写进数组
write_txt(get_home() + "/.config/deepin-wine-runner/ShellHistory.json", str(json.dumps(ListToDictionary(shellHistory)))) # 将历史记录的数组转换为字典并写入
combobox1.clear()
combobox1.addItems(shellHistory)
QtWidgets.QMessageBox.information(widget, "提示", "生成完成!") # 显示完成对话框
except:
traceback.print_exc()
QtWidgets.QMessageBox.critical(widget, "错误", f"快捷方式创建失败,错误如下:\n{traceback.format_exc()}")
def ConfigQemu():
lists = []
for i in qemuBottleList:
lists.append(f"{i[0]}/{i[1]}")
choose = QtWidgets.QInputDialog.getItem(window, "提示", "选择需要 Chroot 到里面的容器", lists, 0, False)
if not choose[1]:
return
threading.Thread(target=OpenTerminal, args=[f"python3 '{programPath}/QemuRun.py' '{choose[0]}' '{int(setting['QemuUnMountHome'])}' "]).start()
print(choose)
# 生成 desktop 文件在桌面
# (第四个按钮的事件)
def make_desktop_on_desktop():
try:
if combobox1.currentText() == "" or e2.currentText() == "": # 判断文本框是否有内容
QtWidgets.QMessageBox.information(widget, "提示", "没有填写需要使用 exe 应用或保存的文件名")
return
if not CheckProgramIsInstall(wine[o1.currentText()]) and not o1.currentText() in untipsWine:
if QtWidgets.QMessageBox.question(widget, "提示", "检查到您未安装这个 wine,是否继续使用这个 wine 写入?") == QtWidgets.QMessageBox.No:
DisableButton(False)
return
else: # 如果都有
if os.path.exists(get_desktop_path() + "/" + combobox1.currentText() + ".desktop"): # 判断目录是否有该文件,如果有
choose = QtWidgets.QMessageBox.question(widget, "提示", "文件已经存在,是否覆盖?") == QtWidgets.QMessageBox.Yes
if choose: # 如要覆盖
os.remove(get_desktop_path() + "/" + combobox1.currentText() + ".desktop") # 删除该文件
else: # 如不覆盖
return # 结束
if e1.currentText() == "":
wineBottonPath = setting["DefultBotton"]
else:
wineBottonPath = e1.currentText()
wineUsingOption = ""
if o1.currentText() == "基于 UOS exagear 的 deepin-wine6-stable" or o1.currentText() == "基于 UOS box86 的 deepin-wine6-stable":
wineUsingOption = ""
if o1.currentText() == "基于 UOS box86 的 deepin-wine6-stable" or o1.currentText() == "基于 UOS exagear 的 deepin-wine6-stable":
if not os.path.exists(f"{programPath}/dlls-arm"):
if os.system(f"7z x -y \"{programPath}/dlls-arm.7z\" -o\"{programPath}\""):
QtWidgets.QMessageBox.critical(widget, "错误", "无法解压资源")
return
os.remove(f"{programPath}/dlls-arm.7z")
if not os.path.exists(get_desktop_path()):
os.makedirs(get_home())
os.mknod(get_desktop_path() + "/" + combobox1.currentText() + ".desktop")
option = ""
if setting["Architecture"] != "Auto":
option += f"WINEARCH={setting['Architecture']} "
if not setting["Debug"]:
option += "WINEDEBUG=-all "
value = ""
if e2.currentText()[:2].upper() == "C:":
value = f"{wineBottonPath}/drive_c/{e2.currentText()[2:]}".replace("\\", "/").replace("//", "/")
print(value)
iconPaths = iconPath
for i in iconList:
listValue = i[1].replace("wineBottonPath", wineBottonPath)
if listValue == e2.currentText() or listValue == value:
# 如果路径相同,即可以用程序对应的图标
iconPaths = f"{programPath}/Icon/{i[0]}.svg"
# 读到了就不需要再读取了
break
os.system(f"mkdir -p '{get_home()}/.local/share/applications/wine'")
write_txt(get_desktop_path() + "/" + combobox1.currentText() + ".desktop", f'''[Desktop Entry]
Name={combobox1.currentText()}
Exec=env WINEPREFIX='{wineBottonPath}' {option} {wine[o1.currentText()]} '{e2.currentText()}' {setting["WineOption"]} {wineUsingOption}
Icon={iconPaths}
Type=Application
StartupNotify=true''') # 写入文本文档
if len(shellHistory) == 0 or shellHistory[-1] != combobox1.currentText():
shellHistory.append(combobox1.currentText()) # 将记录写进数组
write_txt(get_home() + "/.config/deepin-wine-runner/ShellHistory.json", str(json.dumps(ListToDictionary(shellHistory)))) # 将历史记录的数组转换为字典并写入
combobox1.clear()
combobox1.addItems(shellHistory)
QtWidgets.QMessageBox.information(widget, "提示", "生成完成!") # 显示完成对话框
except:
traceback.print_exc()
QtWidgets.QMessageBox.critical(widget, "错误", f"快捷方式创建失败,错误如下:\n{traceback.format_exc()}")
# 数组转字典
def ListToDictionary(list):
dictionary = {}
for i in range(len(list)):
dictionary[i] = list[i]
return dictionary
def CleanProgramHistory():
if QtWidgets.QMessageBox.question(widget, "警告", "删除后将无法恢复,你确定吗?\n删除后软件将会自动重启。") == QtWidgets.QMessageBox.Yes:
try:
shutil.rmtree(get_home() + "/.config/deepin-wine-runner")
except:
traceback.print_exc()
QtWidgets.QMessageBox.critical(widget, "错误", traceback.format_exc())
ReStartProgram()
def CleanProgramCache():
try:
shutil.rmtree(get_home() + "/.cache/deepin-wine-runner")
QtWidgets.QMessageBox.information(widget, "提示", "缓存清理完毕!")
except:
traceback.print_exc()
QtWidgets.QMessageBox.critical(widget, "错误", traceback.format_exc())
def SetFont(size):
font = QtGui.QFont(defaultFont)
if size == 1:
app.setFont(defaultFont)
return
font.setPixelSize(int(defaultFont.pixelSize() / size))
font.setPointSize(int(defaultFont.pointSize() / size))
app.setFont(font)
# 重启本应用程序
def ReStartProgram():
python = sys.executable
os.execl(python, python, * sys.argv)
def KillAllProgram():
pass
def KillProgram():
os.system(f"killall {wine[o1.currentText()]} -9")
os.system("killall winedbg -9")
exeName = os.path.basename(e2.currentText())
os.system(f"killall {exeName} -9")
def InstallWine():
threading.Thread(target=OpenTerminal, args=[f"'{programPath}/AllInstall.py'"]).start()
def InstallWineOnDeepin23():
threading.Thread(target=OpenTerminal, args=[f"'{programPath}/InstallWineOnDeepin23.py'"]).start()
class DllWindow():
def ShowWindow():
global dllMessage
global dllInfoMap
global textInfo
global dllName
dllMessage = QtWidgets.QWidget()
dllLayout = QtWidgets.QGridLayout()
try:
dllInfoMap["check"]
except:
try:
with open(f"{programPath}/CheckDLL/lists.json", "r") as file:
dllInfoMap = json.loads(file.read())
except:
traceback.print_exc()
QtWidgets.QMessageBox.critical(dllMessage, "错误", traceback.format_exc())
# UI
dllName = QtWidgets.QLineEdit()
dllButton = QtWidgets.QPushButton("查询")
textInfo = QtWidgets.QTextBrowser()
dllButton.clicked.connect(DllWindow.Find)
dllLayout.addWidget(QtWidgets.QLabel("Dll 名称:"), 0, 0)
dllLayout.addWidget(dllName, 0, 1)
dllLayout.addWidget(dllButton, 0, 2)
dllLayout.addWidget(textInfo, 1, 0, 1, 3)
dllMessage.setWindowTitle(f"{title}——查询 Dll")
dllMessage.setLayout(dllLayout)
dllMessage.resize(int(dllMessage.frameGeometry().width() * 1.2), int(dllMessage.frameGeometry().height() * 1.1))
dllMessage.setWindowIcon(QtGui.QIcon(f"{programPath}/deepin-wine-runner.svg"))
dllMessage.show()
def Find():
dllNameText = dllName.text().strip().lower()
if dllNameText[-4:] != ".dll":
dllNameText += ".dll"
try:
textInfo.setText(dllInfoMap[dllNameText])
except:
textInfo.setText(f"未查询到有关 Dll '{dllNameText}' 有关的内容")
def InstallWineOnDeepin23Alpha():
threading.Thread(target=OpenTerminal, args=[f"'{programPath}/InstallWineOnDeepin23Alpha.py'"]).start()
def InstallWineHQ():
threading.Thread(target=OpenTerminal, args=[f"{programPath}/InstallNewWineHQ.sh"]).start()
def OpenWineBotton():
if e1.currentText() == "":
wineBottonPath = setting["DefultBotton"]
else:
wineBottonPath = e1.currentText()
os.system("xdg-open \"" + wineBottonPath.replace("\'", "\\\'") + "\"")
def OpenWineFontPath():
if e1.currentText() == "":
wineBottonPath = setting["DefultBotton"]
else:
wineBottonPath = e1.currentText()
QtWidgets.QMessageBox.information(widget, "提示", QtCore.QCoreApplication.translate("U", "如果安装字体?只需要把字体文件复制到此字体目录\n按下“OK”按钮可以打开字体目录"))
os.system("xdg-open \"" + wineBottonPath.replace("\'", "\\\'") + "/drive_c/windows/Fonts\"")
def GetLoseDll():
if e1.currentText() == "":
wineBottonPath = setting["DefultBotton"]
else:
wineBottonPath = e1.currentText()
option = ""
if setting["MonoGeckoInstaller"]:
option += f"WINEDLLOVERRIDES=\"mscoree,mshtml=\" "
if setting["Architecture"] != "Auto":
option += f"WINEARCH={setting['Architecture']} "
if not setting["Debug"]:
option += "WINEDEBUG=-all "
wineUsingOption = ""
if o1.currentText() == "基于 UOS exagear 的 deepin-wine6-stable":
os.system(f"'{programPath}/deepin-wine-runner-create-botton.py' '{wineBottonPath}'")
if o1.currentText() == "基于 UOS exagear 的 deepin-wine6-stable" or o1.currentText() == "基于 UOS box86 的 deepin-wine6-stable":
wineUsingOption = ""
if o1.currentText() == "基于 UOS box86 的 deepin-wine6-stable" or o1.currentText() == "基于 UOS exagear 的 deepin-wine6-stable":
if not os.path.exists(f"{programPath}/dlls-arm"):
if os.system(f"7z x -y \"{programPath}/dlls-arm.7z\" -o\"{programPath}\""):
QtWidgets.QMessageBox.critical(widget, "错误", "无法解压资源")
return
os.remove(f"{programPath}/dlls-arm.7z")
threading.Thread(target=os.system, args=[f"python3 '{programPath}/CheckDLL/main.py' '{e2.currentText()}' '{wineBottonPath}' '{wine[o1.currentText()]}'" + setting["WineOption"]]).start()
class RunWineProgramThread(QtCore.QThread):
signal = QtCore.pyqtSignal(str)
showHistory = QtCore.pyqtSignal(str)
def __init__(self, wineProgram, history = False, Disbled = True):
super().__init__()
self.wineProgram = wineProgram
self.history = history
self.Disbled = Disbled
def run(self):
global lastRunCommand
if e1.currentText() == "":
wineBottonPath = setting["DefultBotton"]
else:
wineBottonPath = e1.currentText()
option = ""
if setting["MonoGeckoInstaller"]:
option += f"WINEDLLOVERRIDES=\"mscoree,mshtml=\" "
if setting["Architecture"] != "Auto":
option += f"WINEARCH={setting['Architecture']} "
if not setting["Debug"]:
option += "WINEDEBUG=-all "
wineUsingOption = ""
if o1.currentText() == "基于 UOS exagear 的 deepin-wine6-stable":
os.system(f"'{programPath}/deepin-wine-runner-create-botton.py' '{wineBottonPath}'")
if o1.currentText() == "基于 UOS exagear 的 deepin-wine6-stable" or o1.currentText() == "基于 UOS box86 的 deepin-wine6-stable":
wineUsingOption = ""
if o1.currentText() == "基于 UOS box86 的 deepin-wine6-stable" or o1.currentText() == "基于 UOS exagear 的 deepin-wine6-stable":
if not os.path.exists(f"{programPath}/dlls-arm"):
if os.system(f"7z x -y \"{programPath}/dlls-arm.7z\" -o\"{programPath}\""):
QtWidgets.QMessageBox.critical(widget, "错误", "无法解压资源")
return
os.remove(f"{programPath}/dlls-arm.7z")
if setting["TerminalOpen"]:
res = ""
runCommand = f"env WINEPREFIX='" + wineBottonPath + "' " + option + wine[o1.currentText()] + " '" + self.wineProgram + "' " + setting["WineOption"] + " " + wineUsingOption
OpenTerminal(runCommand)
#res = subprocess.Popen([f"'{programPath}/launch.sh' deepin-terminal -C \"WINEPREFIX='" + wineBottonPath + "' " + option + wine[o1.currentText()] + " '" + self.wineProgram + "' " + setting["WineOption"] + " " + wineUsingOption + "\" --keep-open"], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
else:
runCommand = "WINEPREFIX='" + wineBottonPath + "' " + option + wine[o1.currentText()] + " '" + self.wineProgram + "' " + setting["WineOption"]
res = subprocess.Popen([runCommand], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
print(runCommand)
lastRunCommand = runCommand
# 实时读取程序返回
if not setting["TerminalOpen"]:
while res.poll() is None:
try:
text = res.stdout.readline().decode("utf8")
except:
text = ""
self.signal.emit(text)
print(text, end="")
if self.history:
if len(findExeHistory) == 0 or findExeHistory[-1] != wineBottonPath:
findExeHistory.append(wineBottonPath) # 将记录写进数组
write_txt(get_home() + "/.config/deepin-wine-runner/FindExeHistory.json", str(json.dumps(ListToDictionary(findExeHistory)))) # 将历史记录的数组转换为字典并写入
if len(wineBottonHistory) == 0 or wineBottonHistory[-1] != e2.currentText():
wineBottonHistory.append(e2.currentText()) # 将记录写进数组
write_txt(get_home() + "/.config/deepin-wine-runner/WineBottonHistory.json", str(json.dumps(ListToDictionary(wineBottonHistory)))) # 将历史记录的数组转换为字典并写入
self.showHistory.emit("")
if self.Disbled:
DisableButton(False)
runProgram = None
def RunWineProgram(wineProgram, history = False, Disbled = True):
global runProgram
DisableButton(True)
if not CheckProgramIsInstall(wine[o1.currentText()]) and o1.currentText() != "基于 linglong 的 deepin-wine6-stable(不推荐)" and o1.currentText() != "基于 UOS exagear 的 deepin-wine6-stable" and o1.currentText() != "基于 UOS box86 的 deepin-wine6-stable":
if not CheckProgramIsInstall(wine[o1.currentText()]) and not o1.currentText() in untipsWine:
if QtWidgets.QMessageBox.question(widget, "提示", "检查到您未安装这个 wine,是否继续使用这个 wine 运行?") == QtWidgets.QMessageBox.No:
DisableButton(False)
return
returnText.setText("")
runProgram = RunWineProgramThread(wineProgram, history, Disbled)
runProgram.signal.connect(QT.ShowWineReturn)
runProgram.showHistory.connect(QT.ShowHistory)
runProgram.start()
class RunWinetricksThread(QtCore.QThread):
signal = QtCore.pyqtSignal(str)
bwrap = QtCore.pyqtSignal(str)
def __init__(self, bwrap):
self.bwrap = bwrap
super().__init__()
def run(self):
wineBottonPath = setting["DefultBotton"]
if not e1.currentText() == "":
wineBottonPath = e1.currentText()
option = ""
if setting["Architecture"] != "Auto":
option += f"WINEARCH={setting['Architecture']} "
if not setting["Debug"]:
option += "WINEDEBUG=-all "
wineUsingOption = ""
if o1.currentText() == "基于 UOS exagear 的 deepin-wine6-stable" or o1.currentText() == "基于 UOS box86 的 deepin-wine6-stable":
wineUsingOption = ""
if o1.currentText() == "基于 UOS box86 的 deepin-wine6-stable" or o1.currentText() == "基于 UOS exagear 的 deepin-wine6-stable":
if not os.path.exists(f"{programPath}/dlls-arm"):
if os.system(f"7z x -y \"{programPath}/dlls-arm.7z\" -o\"{programPath}\""):
QtWidgets.QMessageBox.critical(widget, "错误", "无法解压资源")
return
os.remove(f"{programPath}/dlls-arm.7z")
## 获取 WineServer 路径
wineServer = None
winePath = wine[o1.currentText()]
winePath = winePath.replace(f"bash '{programPath}/WineLib/run.sh'", "").strip()
# 判断类似 xxx-server 的 WineServer
if not os.system(f"{winePath}-server") >> 8:
wineServer = f"{winePath}-server"
# 判断类似 deepin-wine6-stable 的 WineServer
elif os.path.exists(f"/opt/{winePath}/bin/wineserver"):
wineServer = f"/opt/{winePath}/bin/wineserver"
elif os.path.exists(winePath):
wineServer = os.path.normpath(f"{winePath}/../wineserver")
runtime = ""
if self.bwrap:
runtime = f"'{programPath}/WineLib/run.sh'"
winetricksPath = "winetricks"
if os.system("which winetricks") >> 8:
winetricksPath = f"'{programPath}/winetricks'"
print(wineServer)
wineProgramP = wine[o1.currentText()].replace(f"bash '{programPath}/WineLib/run.sh'", "").strip()
wineProgramP = subprocess.getoutput(f"which {wineProgramP}").strip()
if setting["TerminalOpen"]:
res = ""
# 用终端开应该不用返回输出内容了
if wineServer == None:
OpenTerminal(f"WINEPREFIX='{wineBottonPath}' {option} WINE='{wineProgramP}' {runtime} {winetricksPath} --gui {wineUsingOption}")
else:
OpenTerminal(f"WINEPREFIX='{wineBottonPath}' {option} WINESERVER='{wineServer}' WINE='{wineProgramP}' {runtime} {winetricksPath} --gui {wineUsingOption}")
#res = subprocess.Popen([f"'{programPath}/launch.sh' deepin-terminal -C \"WINEPREFIX='{wineBottonPath}' {option} WINE=" + subprocess.getoutput(f"which {wine[o1.currentText()]}").replace(" ", "").replace("\n", "") + f" winetricks --gui {wineUsingOption}\" --keep-open"], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
else:
if wineServer == None:
res = subprocess.Popen([f"WINEPREFIX='{wineBottonPath}' {option} WINE='{wineProgramP}' {runtime} {winetricksPath} --gui"], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
else:
res = subprocess.Popen([f"WINEPREFIX='{wineBottonPath}' {option} WINESERVER='{wineServer}' WINE='{wineProgramP}' {runtime} {winetricksPath} --gui"], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
# 实时读取程序返回
while res.poll() is None:
try:
text = res.stdout.readline().decode("utf8")
except:
text = ""
self.signal.emit(text)
print(text, end="")
DisableButton(False)
runWinetricks = None
def RunWinetricksWithWineLib():
global runWinetricks
DisableButton(True)
if not CheckProgramIsInstall(wine[o1.currentText()]) and o1.currentText() != "基于 linglong 的 deepin-wine6-stable(不推荐)" and o1.currentText() != "基于 UOS exagear 的 deepin-wine6-stable" and o1.currentText() != "基于 UOS box86 的 deepin-wine6-stable":
if not CheckProgramIsInstall(wine[o1.currentText()]) and not o1.currentText() in untipsWine:
DisableButton(False)
return
if o1.currentText() == "基于 UOS box86 的 deepin-wine6-stable" or o1.currentText() == "基于 UOS exagear 的 deepin-wine6-stable":
if not os.path.exists(f"{programPath}/dlls-arm"):
if os.system(f"7z x -y \"{programPath}/dlls-arm.7z\" -o\"{programPath}\""):
QtWidgets.QMessageBox.critical(widget, "错误", "无法解压资源")
return
os.remove(f"{programPath}/dlls-arm.7z")
returnText.setText("")
runWinetricks = RunWinetricksThread(False)
runWinetricks.signal.connect(QT.ShowWineReturn)
runWinetricks.start()
def RunWinetricks():
global runWinetricks
DisableButton(True)
if not CheckProgramIsInstall(wine[o1.currentText()]) and o1.currentText() != "基于 linglong 的 deepin-wine6-stable(不推荐)" and o1.currentText() != "基于 UOS exagear 的 deepin-wine6-stable" and o1.currentText() != "基于 UOS box86 的 deepin-wine6-stable":
if not CheckProgramIsInstall(wine[o1.currentText()]) and not o1.currentText() in untipsWine:
DisableButton(False)
return
if o1.currentText() == "基于 UOS box86 的 deepin-wine6-stable" or o1.currentText() == "基于 UOS exagear 的 deepin-wine6-stable":
if not os.path.exists(f"{programPath}/dlls-arm"):
if os.system(f"7z x -y \"{programPath}/dlls-arm.7z\" -o\"{programPath}\""):
QtWidgets.QMessageBox.critical(widget, "错误", "无法解压资源")
return
os.remove(f"{programPath}/dlls-arm.7z")
returnText.setText("")
runWinetricks = RunWinetricksThread(False)
runWinetricks.signal.connect(QT.ShowWineReturn)
runWinetricks.start()
def CleanWineBottonByUOS():
if e1.currentText() == "":
wineBottonPath = setting["DefultBotton"]
else:
wineBottonPath = e1.currentText()
OpenTerminal(f"env WINE='{wine[o1.currentText()]}' '{programPath}/cleanbottle.sh' '{wineBottonPath}'")
def FontAppStore():
if e1.currentText() == "":
wineBottonPath = setting["DefultBotton"]
else:
wineBottonPath = e1.currentText()
OpenTerminal(f"env WINE='{programPath}/launch.sh' '{programPath}/InstallFont.py' '{wineBottonPath}' {int(setting['RuntimeCache'])}")
def GetDllFromInternet():
if e1.currentText() == "":
wineBottonPath = setting["DefultBotton"]
else:
wineBottonPath = e1.currentText()
OpenTerminal(f"env WINE='{programPath}/launch.sh' '{programPath}/InstallDll.py' '{wineBottonPath}' '{wine[o1.currentText()]}' {int(setting['RuntimeCache'])}")
def WineBottonAutoConfig():
if e1.currentText() == "":
wineBottonPath = setting["DefultBotton"]
else:
wineBottonPath = e1.currentText()
option = ""
if setting["Architecture"] != "Auto":
option += f"WINEARCH={setting['Architecture']} "
if setting["MonoGeckoInstaller"]:
option += f"WINEDLLOVERRIDES=\"mscoree,mshtml=\" "
if not setting["Debug"]:
option += "WINEDEBUG=-all "
else:
option += "WINEDEBUG=FIXME,ERR,WARN,TRACE,Message "
os.system(f"env WINEPREFIX='{wineBottonPath}' {option} WINE='{wine[o1.currentText()]}' '{programPath}/AutoConfig.py' '{wine[o1.currentText()]}' '{wineBottonPath}'")
def InstallMonoGecko(program):
if e1.currentText() == "":
wineBottonPath = setting["DefultBotton"]
else:
wineBottonPath = e1.currentText()
OpenTerminal(f"'{programPath}/InstallMono.py' '{wineBottonPath}' '{wine[o1.currentText()]}' {program} {int(setting['RuntimeCache'])}")
def InstallNetFramework():
if e1.currentText() == "":
wineBottonPath = setting["DefultBotton"]
else:
wineBottonPath = e1.currentText()
OpenTerminal(f"'{programPath}/InstallNetFramework.py' '{wineBottonPath}' '{wine[o1.currentText()]}' {int(setting['RuntimeCache'])}")
def InstallVB():
if e1.currentText() == "":
wineBottonPath = setting["DefultBotton"]
else:
wineBottonPath = e1.currentText()
OpenTerminal(f"'{programPath}/InstallVisualBasicRuntime.py' '{wineBottonPath}' '{wine[o1.currentText()]}' {int(setting['RuntimeCache'])}")
def InstallFoxPro():
if e1.currentText() == "":
wineBottonPath = setting["DefultBotton"]
else:
wineBottonPath = e1.currentText()
OpenTerminal(f"'{programPath}/InstallFoxpro.py' '{wineBottonPath}' '{wine[o1.currentText()]}' {int(setting['RuntimeCache'])}")
def InstallVisualStudioCPlusPlus():
if e1.currentText() == "":
wineBottonPath = setting["DefultBotton"]
else:
wineBottonPath = e1.currentText()
OpenTerminal(f"'{programPath}/InstallVisualCPlusPlus.py' '{wineBottonPath}' '{wine[o1.currentText()]}' {int(setting['RuntimeCache'])}")
def InstallMSXML():
if e1.currentText() == "":
wineBottonPath = setting["DefultBotton"]
else:
wineBottonPath = e1.currentText()
OpenTerminal(f"'{programPath}/InstallMsxml.py' '{wineBottonPath}' '{wine[o1.currentText()]}' {int(setting['RuntimeCache'])}")
def InstallDXVK():
if not os.path.exists(f"{programPath}/dxvk"):
if os.system(f"7z x -y \"{programPath}/dxvk.7z\" -o\"{programPath}\""):
QtWidgets.QMessageBox.critical(widget, "错误", "无法解压资源")
return
os.remove(f"{programPath}/dxvk.7z")
if e1.currentText() == "":
wineBottonPath = setting["DefultBotton"]
else:
wineBottonPath = e1.currentText()
OpenTerminal(f"env WINE='{wine[o1.currentText()]}' WINE64='{wine[o1.currentText()]}' WINEPREFIX='{wineBottonPath}' '{programPath}/dxvk/setup_dxvk.sh' uninstall")
def InstallVkd3d():
if not os.path.exists(f"{programPath}/vkd3d-proton"):
if os.system(f"7z x -y \"{programPath}/vkd3d-proton.7z\" -o\"{programPath}\""):
QtWidgets.QMessageBox.critical(widget, "错误", "无法解压资源")
return
os.remove(f"{programPath}/vkd3d-proton.7z")
if e1.currentText() == "":
wineBottonPath = setting["DefultBotton"]
else:
wineBottonPath = e1.currentText()
OpenTerminal(f"env WINE='{wine[o1.currentText()]}' WINE64='{wine[o1.currentText()]}' WINEPREFIX='{wineBottonPath}' '{programPath}/vkd3d-proton/setup_vkd3d_proton.sh' install")
def UninstallVkd3d():
if not os.path.exists(f"{programPath}/vkd3d-proton"):
if os.system(f"7z x -y \"{programPath}/vkd3d-proton.7z\" -o\"{programPath}\""):
QtWidgets.QMessageBox.critical(widget, "错误", "无法解压资源")
return
os.remove(f"{programPath}/vkd3d-proton.7z")
if e1.currentText() == "":
wineBottonPath = setting["DefultBotton"]
else:
wineBottonPath = e1.currentText()
OpenTerminal(f"env WINE='{wine[o1.currentText()]}' WINE64='{wine[o1.currentText()]}' WINEPREFIX='{wineBottonPath}' '{programPath}/vkd3d-proton/setup_vkd3d_proton.sh' uninstall")
#process = QtCore.QProcess()
#process.startDetached(f"{programPath}/launch.sh", ["deepin-terminal", "-e",
#"env", f"WINE={wine[o1.currentText()]}", f"WINE64={wine[o1.currentText()]}", f"WINEPREFIX={wineBottonPath}", "bash",
#f"{programPath}/dxvk/setup_dxvk.sh", "install"])
def UninstallDXVK():
if not os.path.exists(f"{programPath}/dxvk"):
if os.system(f"7z x -y \"{programPath}/dxvk.7z\" -o\"{programPath}\""):
QtWidgets.QMessageBox.critical(widget, "错误", "无法解压资源")
return
os.remove(f"{programPath}/dxvk.7z")
if e1.currentText() == "":
wineBottonPath = setting["DefultBotton"]
else:
wineBottonPath = e1.currentText()
OpenTerminal(f"env WINE='{wine[o1.currentText()]}' WINE64='{wine[o1.currentText()]}' WINEPREFIX='{wineBottonPath}' '{programPath}/dxvk/setup_dxvk.sh' uninstall")
#process = QtCore.QProcess()
#process.startDetached(f"{programPath}/launch.sh", ["deepin-terminal", "-e",
#"env", f"WINE={wine[o1.currentText()]}", f"WINE64={wine[o1.currentText()]}", f"WINEPREFIX={wineBottonPath}",
#f"{programPath}/dxvk/setup_dxvk.sh", "uninstall"])
def MiniAppStore():
if e1.currentText()== "":
wineBottonPath = setting["DefultBotton"]
else:
wineBottonPath = e1.currentText()
OpenTerminal(f"'{programPath}/AppStore.py' '{wineBottonPath}' '{wine[o1.currentText()]}'")
def InstallOther():
if e1.currentText()== "":
wineBottonPath = setting["DefultBotton"]
else:
wineBottonPath = e1.currentText()
OpenTerminal(f"'{programPath}/InstallOther.py' '{wineBottonPath}' '{wine[o1.currentText()]}' {int(setting['RuntimeCache'])}")
def BuildExeDeb():
if e1.currentText() == "":
wineBottonPath = setting["DefultBotton"]
else:
wineBottonPath = e1.currentText()
threading.Thread(target=os.system, args=[f"python3 '{programPath}/deepin-wine-packager.py' '{wineBottonPath}' '{wine[o1.currentText()]}'"]).start()
def SetDeepinFileDialogDeepin():
code = os.system(f"pkexec \"{programPath}/deepin-wine-venturi-setter.py\" deepin")
if code != 0:
if code == 1:
QtWidgets.QMessageBox.critical(widget, "错误", "无法更新配置:配置不准重复配置")
return
QtWidgets.QMessageBox.critical(widget, "错误", "配置失败")
return
QtWidgets.QMessageBox.information(widget, "提示", "设置完成!")
def AddReg():
path = QtWidgets.QFileDialog.getOpenFileName(window, "保存路径", get_home(), "reg文件(*.reg);;所有文件(*.*)")
if path[0] == "" and not path[1]:
return
RunWineProgram(f"regedit' /S '{path[0]}' 'HKEY_CURRENT_USER\Software\Wine\DllOverrides")
def SaveDllList():
path = QtWidgets.QFileDialog.getSaveFileName(window, "保存路径", get_home(), "reg文件(*.reg);;所有文件(*.*)")
if path[0] == "" and not path[1]:
return
RunWineProgram(f"regedit' /E '{path[0]}' 'HKEY_CURRENT_USER\Software\Wine\DllOverrides")
def SetDeepinFileDialogDefult():
code = os.system(f"pkexec \"{programPath}/deepin-wine-venturi-setter.py\" defult")
if code != 0:
if code == 1:
QtWidgets.QMessageBox.critical(widget, "错误", "无法更新配置:配置不准重复配置")
return
QtWidgets.QMessageBox.critical(widget, "错误", "配置失败")
return
QtWidgets.QMessageBox.information(widget, "提示", "设置完成!")
def SetDeepinFileDialogRecovery():
threading.Thread(target=OpenTerminal, args=[f"pkexec '{programPath}/deepin-wine-venturi-setter.py' recovery"]).start()
def DeleteDesktopIcon():
if os.path.exists(f"{get_home()}/.local/share/applications/wine"):
try:
shutil.rmtree(f"{get_home()}/.local/share/applications/wine")
except:
traceback.print_exc()
QtWidgets.QMessageBox.critical(widget, "错误", traceback.format_exc())
return
QtWidgets.QMessageBox.information(widget, "提示", "删除完成")
def DeleteWineBotton():
if QtWidgets.QMessageBox.question(widget, "提示", "你确定要删除容器吗?删除后将无法恢复!\n如果没有选择 wine 容器,将会自动删除默认的容器!") == QtWidgets.QMessageBox.No:
return
if e1.currentText() == "":
wineBottonPath = setting["DefultBotton"]
else:
wineBottonPath = e1.currentText()
try:
shutil.rmtree(wineBottonPath)
QtWidgets.QMessageBox.information(widget, "提示", "删除完毕!")
except:
traceback.print_exc()
QtWidgets.QMessageBox.critical(widget, "错误", traceback.format_exc())
def ThankWindow():
# 直接显示关于窗口,关于窗口已经添加
about_this_program()
def InstallWineFont():
# 筛选 apt
if not os.system("which aptss"):
threading.Thread(target=OpenTerminal, args=[f"sudo aptss install ms-core-fonts -y"]).start()
elif not os.system("which ss-apt-fast"):
threading.Thread(target=OpenTerminal, args=[f"sudo ss-apt-fast install ms-core-fonts -y"]).start()
elif not os.system("which apt-fast"):
threading.Thread(target=OpenTerminal, args=[f"sudo apt-fast install ms-core-fonts -y"]).start()
else:
threading.Thread(target=OpenTerminal, args=[f"sudo apt install ms-core-fonts -y"]).start()
def WineRunnerBugUpload():
threading.Thread(target=os.system, args=[f"'{programPath}/deepin-wine-runner-update-bug'"]).start()
def SetHttpProxy():
QtWidgets.QMessageBox.information(window, "提示", "请在下面的对话框正确输入内容以便设置代理")
proxyServerAddress = QtWidgets.QInputDialog.getText(window, "提示", "请输入代理服务器地址")[0]
port = QtWidgets.QInputDialog.getText(window, "提示", "请输入代理服务器端口")[0]
if proxyServerAddress == "" or port == "":
return
RunWineProgram("reg' add 'HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings' /v ProxyEnable /t REG_DWORD /d 00000001 '/f")
RunWineProgram(f"reg' add 'HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings' /v ProxyServer /d '{proxyServerAddress}:{port}' '/f")
def DisbledHttpProxy():
RunWineProgram("reg' add 'HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings' /v ProxyEnable /t REG_DWORD /d 00000000 '/f")
def GetScreenSize():
screenInformation = []
# 使用 xrandr 进行筛选
for i in subprocess.getoutput("xrandr").split('\n'):
if not " connected " in i: # 检测连接的显示器
continue
# 获取分辨率基本信息,如
# DisplayPort-0 connected 1600x900+1280+0 (normal left inverted right x axis y axis) 434mm x 236mm
# 先判断是否为主屏幕
main = False
if "primary" in i:
main = True
# 进行进一步筛选
i = i[i.index("connected"):].replace("connected", "").replace("primary", "")
# 进行初步筛选,如
# 1600x900+1280+0 (normal left inverted right x axis y axis) 434mm x 236mm
i = i[:i.index("(")].replace(" ", "")
# 筛选为 1600x900+0+0 进行最后数值的提取
screenInformation.append([
int(i[:i.index("x")]), # 获取宽度
int(i[i.index("x") + 1 :i.index("+")]), # 获取高度
int(i[i.index("+") + 1:].split('+')[0]), # 获取显示屏 X 坐标
int(i[i.index("+") + 1:].split('+')[1]), # 获取显示屏 Y 坐标
main # 是否为主屏幕
])
return screenInformation # 返回结果
def UOSPackageScript():
threading.Thread(target=os.system, args=[f"python3 '{programPath}/deepin-wine-packager-with-script.py'"]).start()
def RunVM():
threading.Thread(target=os.system, args=[f"bash '{programPath}/RunVM.sh'"]).start()
def CleanProgram():
OpenTerminal(f"{programPath}/clean-unuse-program.py")
class UpdateWindow():
data = {}
update = None
def ShowWindow():
UpdateWindow.update = QtWidgets.QMainWindow()
updateWidget = QtWidgets.QWidget()
updateWidgetLayout = QtWidgets.QGridLayout()
versionLabel = QtWidgets.QLabel(f"当前版本:{version}\n最新版本:未知\n更新内容:")
updateText = QtWidgets.QTextBrowser()
updateText.anchorClicked.connect(OpenUrl)
updateText.setOpenExternalLinks(False)
ok = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "更新(更新时会自动关闭 Wine 运行器)"))
ok.clicked.connect(UpdateWindow.Update)
cancel = QtWidgets.QPushButton("取消")
cancel.clicked.connect(UpdateWindow.update.close)
url = "http://update.gfdgdxi.top/update.json"
try:
UpdateWindow.data = json.loads(requests.get(url).text)
versionLabel = QtWidgets.QLabel(f"当前版本:{version}\n最新版本:{UpdateWindow.data['Version']}\n更新内容:")
if UpdateWindow.data["Version"] == version:
updateText.setText("此为最新版本,无需更新")
ok.setDisabled(True)
else:
# 版本号读取(防止出现高版本号提示要“升级”到低版本号的问题)
localVersionList = version.split(".")
webVersionList = UpdateWindow.data['Version'].split(".")
for i in range(len(localVersionList)):
local = int(localVersionList[i])
web = int(webVersionList[i])
if web < local:
updateText.setHtml(f"""<p>此为最新版本,无需更新,但似乎您当前使用的程序版本比云端版本还要高。</p>
<p>出现这个问题可能会有如下几种情况:</p>
<p>1、使用编译或者内测版本</p>
<p>2、自己修改了程序版本</p>
<p>3、作者忘记更新云端上的更新信息了</p>
<p>如果是第三种情况,请反馈到此:<a href='https://gitee.com/gfdgd-xi/deep-wine-runner/issues/I6T3FG'>https://gitee.com/gfdgd-xi/deep-wine-runner/issues/I6T3FG</a></p>
<p><img src='{programPath}/Icon/doge.png'></p>""")
ok.setDisabled(True)
break
if web > local:
updateText.setText(UpdateWindow.data["New"].replace("\\n", "\n"))
ok.setEnabled(True)
break
except:
traceback.print_exc()
QtWidgets.QMessageBox.critical(updateWidget, "错误", "无法连接服务器!")
updateWidgetLayout.addWidget(versionLabel, 0, 0, 1, 1)
updateWidgetLayout.addWidget(updateText, 1, 0, 1, 3)
updateWidgetLayout.addWidget(ok, 2, 2, 1, 1)
updateWidgetLayout.addWidget(cancel, 2, 1, 1, 1)
updateWidget.setLayout(updateWidgetLayout)
UpdateWindow.update.setCentralWidget(updateWidget)
UpdateWindow.update.setWindowTitle(QtCore.QCoreApplication.translate("U", "检查更新"))
UpdateWindow.update.resize(updateWidget.frameGeometry().width(), int(updateWidget.frameGeometry().height() * 1.5))
UpdateWindow.update.show()
def Update():
if os.path.exists("/tmp/spark-deepin-wine-runner/update"):
shutil.rmtree("/tmp/spark-deepin-wine-runner/update")
os.makedirs("/tmp/spark-deepin-wine-runner/update")
try:
print(UpdateWindow.data["Url"])
if os.path.exists(f"{programPath}/off-line.lock") or programPath != "/opt/apps/deepin-wine-runner":
# 使用解压法更新
write_txt("/tmp/spark-deepin-wine-runner/update.sh", f"""#!/bin/bash
echo 删除多余的安装包
rm -rfv /tmp/spark-deepin-wine-runner/update/*
echo 关闭“Wine 运行器”
python3 "{programPath}/updatekiller.py"
echo 下载安装包
wget -P /tmp/spark-deepin-wine-runner/update {UpdateWindow.data["Url"][0]}
echo 安装安装包
cd /tmp/spark-deepin-wine-runner/update
7z x *.deb
7z x data.tar
cp opt/apps/deepin-wine-runner/* "{programPath}" -rv
notify-send -i "{iconPath}" "更新完毕!"
zenity --info --text=\"更新完毕!\" --ellipsize
""")
OpenTerminal("bash /tmp/spark-deepin-wine-runner/update.sh")
return
else:
# 使用 deb 安装更新
write_txt("/tmp/spark-deepin-wine-runner/update.sh", f"""#!/bin/bash
echo 删除多余的安装包
rm -rfv /tmp/spark-deepin-wine-runner/update/*
echo 关闭“Wine 运行器”
python3 "{programPath}/updatekiller.py"
echo 下载安装包
wget -P /tmp/spark-deepin-wine-runner/update {UpdateWindow.data["Url"][0]}
echo 安装安装包
dpkg -i /tmp/spark-deepin-wine-runner/update/*
echo 修复依赖关系
apt install -f -y
notify-send -i "{iconPath}" "更新完毕!"
zenity --info --text=\"更新完毕!\" --ellipsize
""")
OpenTerminal("pkexec bash /tmp/spark-deepin-wine-runner/update.sh")
except:
traceback.print_exc()
QtWidgets.QMessageBox.critical(None, "出现错误,无法继续更新", traceback.format_exc())
class GetDllFromWindowsISO:
wineBottonPath = get_home() + "/.wine"
isoPath = None
dllList = None
message = None
dllFound = None
dllControl = None
foundButton = None
saveDll = None
setWineBotton = None
browser = None
mount = False
mountButton = None
dllListModel = None
arch = 0
def ShowWindow():
#DisableButton(True)
GetDllFromWindowsISO.message = QtWidgets.QMainWindow()
widget = QtWidgets.QWidget()
widgetLayout = QtWidgets.QGridLayout()
if not e1.currentText() == "":
GetDllFromWindowsISO.wineBottonPath = e1.currentText()
widgetLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", f"""提示:
目前本提取功能暂只支持 NT 内核系统的官方安装镜像,不支持读取 ghost 等第三方封装方式的安装镜像
以及不要拷贝/替换太多的 dll,否则可能会导致 wine 容器异常,以及不要替换 Wine 的核心 dll
最后,拷贝/替换 dll 后,建议点击下面“设置 wine 容器”按钮==》函数库 进行设置
当前选择的 Wine 容器:{GetDllFromWindowsISO.wineBottonPath}""")), 0, 0, 1, 5)
isoLabel = QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "ISO镜像:"))
GetDllFromWindowsISO.isoPath = QtWidgets.QComboBox()
GetDllFromWindowsISO.browser = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "浏览"))
isoControl = QtWidgets.QWidget()
isoControlLayout = QtWidgets.QHBoxLayout()
isoControl.setLayout(isoControlLayout)
dllControl = QtWidgets.QWidget()
dllControlLayout = QtWidgets.QHBoxLayout()
dllControl.setLayout(dllControlLayout)
GetDllFromWindowsISO.mountButton = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "读取/挂载ISO镜像"))
umountButton = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "关闭/卸载ISO镜像"))
GetDllFromWindowsISO.dllFound = QtWidgets.QComboBox()
GetDllFromWindowsISO.foundButton = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "查找"))
GetDllFromWindowsISO.dllList = QtWidgets.QListView()
GetDllFromWindowsISO.saveDll = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "保存到 wine 容器中"))
GetDllFromWindowsISO.setWineBotton = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "设置 wine 容器"))
isoLabel.setSizePolicy(size)
GetDllFromWindowsISO.isoPath.setEditable(True)
GetDllFromWindowsISO.isoPath.addItems(isoPath)
GetDllFromWindowsISO.isoPath.setEditText("")
GetDllFromWindowsISO.browser.setSizePolicy(size)
GetDllFromWindowsISO.mountButton.setSizePolicy(size)
isoControlLayout.addWidget(GetDllFromWindowsISO.mountButton)
umountButton.setSizePolicy(size)
isoControlLayout.addWidget(umountButton)
GetDllFromWindowsISO.dllFound.setEditable(True)
GetDllFromWindowsISO.dllFound.addItems(isoPathFound)
GetDllFromWindowsISO.dllFound.setEditText("")
GetDllFromWindowsISO.saveDll.setSizePolicy(size)
dllControlLayout.addWidget(GetDllFromWindowsISO.saveDll)
GetDllFromWindowsISO.setWineBotton.setSizePolicy(size)
GetDllFromWindowsISO.DisbledDown(True)
dllControlLayout.addWidget(GetDllFromWindowsISO.setWineBotton)
widgetLayout.addWidget(isoLabel, 1, 0, 1, 1)
widgetLayout.addWidget(GetDllFromWindowsISO.isoPath, 1, 1, 1, 1)
widgetLayout.addWidget(GetDllFromWindowsISO.browser, 1, 2, 1, 1)
widgetLayout.addWidget(isoControl, 2, 1, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "查找DLL\n(为空则代表不查找,\n将显示全部内容):")), 3, 0, 1, 1)
widgetLayout.addWidget(GetDllFromWindowsISO.dllFound, 3, 1, 1, 1)
widgetLayout.addWidget(GetDllFromWindowsISO.foundButton, 3, 2, 1, 1)
widgetLayout.addWidget(GetDllFromWindowsISO.dllList, 4, 1, 1, 1)
widgetLayout.addWidget(dllControl, 5, 1, 1, 1)
widget.setLayout(widgetLayout)
GetDllFromWindowsISO.browser.clicked.connect(GetDllFromWindowsISO.Browser)
GetDllFromWindowsISO.mountButton.clicked.connect(GetDllFromWindowsISO.MountDisk)
umountButton.clicked.connect(GetDllFromWindowsISO.UmountDisk)
GetDllFromWindowsISO.foundButton.clicked.connect(GetDllFromWindowsISO.Found)
GetDllFromWindowsISO.saveDll.clicked.connect(GetDllFromWindowsISO.CopyDll)
GetDllFromWindowsISO.setWineBotton.clicked.connect(lambda: RunWineProgram("winecfg", Disbled=False))
GetDllFromWindowsISO.message.setCentralWidget(widget)
GetDllFromWindowsISO.dllListModel = QtCore.QStringListModel()
GetDllFromWindowsISO.dllListModel.setStringList([])
GetDllFromWindowsISO.dllList.setModel(GetDllFromWindowsISO.dllListModel)
GetDllFromWindowsISO.isoPath.currentText()
GetDllFromWindowsISO.message.setWindowTitle(f"Wine 运行器 {version}——从 ISO 提取 DLL")
GetDllFromWindowsISO.message.setWindowIcon(QtGui.QIcon(iconPath))
GetDllFromWindowsISO.message.show()
def DisbledUp(state):
GetDllFromWindowsISO.isoPath.setDisabled(state)
GetDllFromWindowsISO.browser.setDisabled(state)
GetDllFromWindowsISO.mountButton.setDisabled(state)
def DisbledDown(state):
GetDllFromWindowsISO.dllList.setDisabled(state)
GetDllFromWindowsISO.dllFound.setDisabled(state)
GetDllFromWindowsISO.saveDll.setDisabled(state)
GetDllFromWindowsISO.setWineBotton.setDisabled(state)
GetDllFromWindowsISO.foundButton.setDisabled(state)
def Browser():
path = QtWidgets.QFileDialog.getOpenFileName(GetDllFromWindowsISO.message, "选择 ISO 镜像文件", json.loads(readtxt(get_home() + "/.config/deepin-wine-runner/FindISO.json"))["path"], "iso 镜像文件(*.iso);;ISO 镜像文件(*.ISO);;所有文件(*.*)")[0]
if path == None or path == "":
return
GetDllFromWindowsISO.isoPath.setEditText(path)
write_txt(get_home() + "/.config/deepin-wine-runner/FindISO.json", json.dumps({"path": os.path.dirname(path)})) # 写入配置文件
def Found():
found = GetDllFromWindowsISO.dllFound.currentText()
findList = []
try:
if found == "":
# 显示所有内容
# 下面内容需要分类讨论
if GetDllFromWindowsISO.arch == 0:
for i in os.listdir("/tmp/wine-runner-getdll/i386"):
if i[-3:] == "dl_":
findList.append(i[:-1] + "l")
elif GetDllFromWindowsISO.arch == 32:
for i in os.listdir("/tmp/wine-runner-getdll-wim/Windows/SysWOW64"):
if i[-3:] == "dll":
findList.append(i[:-1] + "l")
elif GetDllFromWindowsISO.arch == 64:
for i in os.listdir("/tmp/wine-runner-getdll-wim/Windows/System32"):
if i[-3:] == "dll":
findList.append(i[:-1] + "l")
GetDllFromWindowsISO.dllListModel.setStringList(findList)
return
if GetDllFromWindowsISO.arch == 0:
for i in os.listdir("/tmp/wine-runner-getdll/i386"):
if found in i[:-1] + "l":
findList.append(i[:-1] + "l")
elif GetDllFromWindowsISO.arch == 32:
for i in os.listdir("/tmp/wine-runner-getdll-wim/Windows/SysWOW64"):
if found in i[:-1] + "l":
findList.append(i[:-1] + "l")
elif GetDllFromWindowsISO.arch == 64:
for i in os.listdir("/tmp/wine-runner-getdll-wim/Windows/System32"):
if found in i[:-1] + "l":
findList.append(i[:-1] + "l")
if len(isoPath) == 0:
if isoPathFound[-1] != found:
isoPathFound.append(found) # 将记录写进数组
write_txt(get_home() + "/.config/deepin-wine-runner/ISOPathFound.json", str(json.dumps(ListToDictionary(isoPathFound)))) # 将历史记录的数组转换为字典并写入
GetDllFromWindowsISO.dllFound.clear()
GetDllFromWindowsISO.dllFound.addItems(isoPathFound)
GetDllFromWindowsISO.dllListModel.setStringList(findList)
except:
traceback.print_exc()
QtWidgets.QMessageBox.critical(GetDllFromWindowsISO.message, transla.trans("错误"), traceback.format_exc())
def MountDisk():
if not os.path.exists(GetDllFromWindowsISO.isoPath.currentText()):
QtWidgets.QMessageBox.critical(GetDllFromWindowsISO.message, transla.trans("错误"), transla.trans("您选择的 ISO 镜像文件不存在"))
return
if os.path.exists("/tmp/wine-runner-getdll"):
try:
os.rmdir("/tmp/wine-runner-getdll")
os.system("rm -rf /tmp/wine-runner-getdll-wim")
except:
# 如果无法删除可能是挂载了文件
os.system("wimunmount /tmp/wine-runner-getdll-wim")
os.system("pkexec umount /tmp/wine-runner-getdll")
try:
os.rmdir("/tmp/wine-runner-getdll")
os.rmdir("/tmp/wine-runner-getdll-wim")
except:
traceback.print_exc()
QtWidgets.QMessageBox.critical(GetDllFromWindowsISO.message, "错误", traceback.format_exc())
return
os.makedirs("/tmp/wine-runner-getdll")
os.system(f"pkexec mount '{GetDllFromWindowsISO.isoPath.currentText()}' /tmp/wine-runner-getdll")
findList = []
# 判断是新版的 Windows ISO(Windows Vista 及以上版本)
if os.path.exists("/tmp/wine-runner-getdll/sources/install.wim"):
# 如果没有安装 wimtools 的话
if os.system("which wimmount") != 0:
QtWidgets.QMessageBox.critical(GetDllFromWindowsISO.message, "错误", f"镜像内容读取/挂载失败,因为没有安装 wimtools 以至无法读取")
return
# 是新版,挂载 wim
# 需要让用户选择挂载内容
QtWidgets.QInputDialog.getMultiLineText(GetDllFromWindowsISO.message, "提示", "挂载文件需要用户记住并在下一个对话框输入 Index 以挂载正确的镜像,按下下方任意按钮即可继续", subprocess.getoutput("wiminfo '/tmp/wine-runner-getdll/sources/install.wim'"))
choose = QtWidgets.QInputDialog.getInt(GetDllFromWindowsISO.message, "提示", "请输入 Index")
if not choose[1]:
return
os.makedirs("/tmp/wine-runner-getdll-wim")
os.system(f"wimmount /tmp/wine-runner-getdll/sources/install.wim {choose[0]} /tmp/wine-runner-getdll-wim")
if os.path.exists("/tmp/wine-runner-getdll-wim/Windows/SysWOW64"):
# 如果是 64 位镜像
if QtWidgets.QInputDialog.getItem(GetDllFromWindowsISO.message, "选择位数", "选择位数(如果没有选择,默认为 64 位)", ["32", "64"], 1, False) == "32":
# 64 位镜像的 32 位是存在 SysWOW64 的
try:
for i in os.listdir("/tmp/wine-runner-getdll-wim/Windows/SysWOW64"):
if i[-3:] == "dll":
findList.append(i[:-1] + "l")
GetDllFromWindowsISO.dllListModel.setStringList(findList)
GetDllFromWindowsISO.arch = 32
GetDllFromWindowsISO.DisbledDown(False)
GetDllFromWindowsISO.DisbledUp(True)
GetDllFromWindowsISO.mount = True
if len(isoPath) == 0 or isoPath[-1] != GetDllFromWindowsISO.isoPath.currentText():
isoPath.append(GetDllFromWindowsISO.isoPath.currentText()) # 将记录写进数组
write_txt(get_home() + "/.config/deepin-wine-runner/ISOPath.json", str(json.dumps(ListToDictionary(isoPath)))) # 将历史记录的数组转换为字典并写入
GetDllFromWindowsISO.isoPath.clear()
GetDllFromWindowsISO.isoPath.addItems(isoPath)
return
except:
traceback.print_exc()
QtWidgets.QMessageBox.critical(GetDllFromWindowsISO.message, "错误", f"镜像内容读取/挂载失败,报错如下:\n{traceback.format_exc()}")
return
try:
for i in os.listdir("/tmp/wine-runner-getdll-wim/Windows/System32"):
if i[-3:] == "dll":
findList.append(i[:-1] + "l")
GetDllFromWindowsISO.arch = 64
except:
traceback.print_exc()
QtWidgets.QMessageBox.critical(GetDllFromWindowsISO.message, "错误", f"镜像内容读取/挂载失败,报错如下:\n{traceback.format_exc()}")
return
GetDllFromWindowsISO.dllListModel.setStringList(findList)
else:
try:
for i in os.listdir("/tmp/wine-runner-getdll/i386"):
if i[-3:] == "dl_":
findList.append(i[:-1] + "l")
GetDllFromWindowsISO.arch = 0
except:
traceback.print_exc()
QtWidgets.QMessageBox.critical(GetDllFromWindowsISO.message, "错误", f"镜像内容读取/挂载失败,报错如下:\n{traceback.format_exc()}")
return
GetDllFromWindowsISO.dllListModel.setStringList(findList)
GetDllFromWindowsISO.DisbledDown(False)
GetDllFromWindowsISO.DisbledUp(True)
GetDllFromWindowsISO.mount = True
if len(isoPath) == 0 or isoPath[-1] != GetDllFromWindowsISO.isoPath.currentText():
isoPath.append(GetDllFromWindowsISO.isoPath.currentText()) # 将记录写进数组
write_txt(get_home() + "/.config/deepin-wine-runner/ISOPath.json", str(json.dumps(ListToDictionary(isoPath)))) # 将历史记录的数组转换为字典并写入
GetDllFromWindowsISO.isoPath.clear()
GetDllFromWindowsISO.isoPath.addItems(isoPath)
#GetDllFromWindowsISO.isoPath['value'] = isoPath
def UmountDisk():
os.system("wimunmount /tmp/wine-runner-getdll-wim")
os.system("pkexec umount /tmp/wine-runner-getdll")
try:
shutil.rmtree("/tmp/wine-runner-getdll")
os.system("rm -rf /tmp/wine-runner-getdll-wim")
except:
traceback.print_exc()
QtWidgets.QMessageBox.critical(GetDllFromWindowsISO.message, QtCore.QCoreApplication.translate("U", "错误"), f"关闭/卸载镜像失败,报错如下:\n{traceback.format_exc()}")
return
GetDllFromWindowsISO.DisbledDown(True)
GetDllFromWindowsISO.DisbledUp(False)
GetDllFromWindowsISO.mount = False
QtWidgets.QMessageBox.information(GetDllFromWindowsISO.message, QtCore.QCoreApplication.translate("U", "提示"), QtCore.QCoreApplication.translate("U", "关闭/卸载成功!"))
def CopyDll():
choose = GetDllFromWindowsISO.dllList.selectionModel().selectedIndexes()[0].data()
if os.path.exists(f"{GetDllFromWindowsISO.wineBottonPath}/drive_c/windows/system32/{choose}"):
if QtWidgets.QMessageBox.question(GetDllFromWindowsISO.message, "提示", f"DLL {choose} 已经存在,是否覆盖?") == QtWidgets.QMessageBox.No:
return
try:
# 要分类讨论
if GetDllFromWindowsISO.arch == 0:
shutil.copy(f"/tmp/wine-runner-getdll/i386/{choose[:-1]}_", f"{GetDllFromWindowsISO.wineBottonPath}/drive_c/windows/system32/{choose}")
elif GetDllFromWindowsISO.arch == 32:
shutil.copy(f"/tmp/wine-runner-getdll-wim/Windows/SysWOW64/{choose[:-1]}l", f"{GetDllFromWindowsISO.wineBottonPath}/drive_c/windows/system32/{choose}")
elif GetDllFromWindowsISO.arch == 64:
shutil.copy(f"/tmp/wine-runner-getdll-wim/Windows/System32/{choose[:-1]}l", f"{GetDllFromWindowsISO.wineBottonPath}/drive_c/windows/system32/{choose}")
# 选择原装或优于内建
if QtWidgets.QInputDialog.getItem(GetDllFromWindowsISO.message, "选择", "选择模式", ["原装先于内建", "原装"], 0, False) == "原装先于内建":
# 原装先于内建
os.system(f"WINEPREFIX='{GetDllFromWindowsISO.wineBottonPath}' '{wine[o1.currentText()]}' reg add 'HKEY_CURRENT_USER\Software\Wine\DllOverrides' /v {os.path.splitext(choose)[0]} /d native,builtin /f")
else:
# 原装
os.system(f"WINEPREFIX='{GetDllFromWindowsISO.wineBottonPath}' '{wine[o1.currentText()]}' reg add 'HKEY_CURRENT_USER\Software\Wine\DllOverrides' /v {os.path.splitext(choose)[0]} /d native /f")
QtWidgets.QMessageBox.information(GetDllFromWindowsISO.message, "提示", "提取成功!")
except:
traceback.print_exc()
QtWidgets.QMessageBox.critical(GetDllFromWindowsISO.message, "错误", traceback.format_exc())
choose = None
class ProgramRunStatusShow():
msgWindow = None
def ShowWindow():
global choose
choose = None
dateVersion = ""
if not os.path.exists(e2.currentText()):
QtWidgets.QMessageBox.information(widget, "提示", "您输入的 exe 不存在")
return
try:
sha = ProgramRunStatusUpload.GetSHA1(e2.currentText())
lists = json.loads(requests.get(base64.b64decode("aHR0cDovLzEyMC4yNS4xNTMuMTQ0L3NwYXJrLWRlZXBpbi13aW5lLXJ1bm5lci9hcHAv").decode("utf-8") + sha + base64.b64decode("L2FsbC5qc29u").decode("utf-8")).text)
r = requests.get(base64.b64decode("aHR0cDovLzEyMC4yNS4xNTMuMTQ0L3NwYXJrLWRlZXBpbi13aW5lLXJ1bm5lci9hcHAv").decode("utf-8") + sha + base64.b64decode("L3RpdGxlLnR4dA==").decode("utf-8"))
r.encoding = "utf-8"
title = r.text
except:
choosemsg = QtWidgets.QMessageBox()
choosemsg.setText("""暂时还没有该软件的运行情况信息,请问需要?""")
choosemsg.setWindowTitle("提示")
def Choose(choices):
global choose
choose = choices
choosemsg.addButton("取消", QtWidgets.QMessageBox.ActionRole).clicked.connect(lambda: Choose(0))
choosemsg.addButton("提交评分", QtWidgets.QMessageBox.ActionRole).clicked.connect(lambda: Choose(1))
choosemsg.addButton("预测评分(不准确)", QtWidgets.QMessageBox.ActionRole).clicked.connect(lambda: Choose(2))
choosemsg.exec_()
if choose == None or choose == 0:
return
if choose == 1:
ProgramRunStatusUpload.ShowWindow(sha)
return
if choose == 2:
try:
lists = [0, 0, 0, 0, 0, 0, 0, 0]
info = json.loads(requests.get(base64.b64decode("aHR0cDovLzEyMC4yNS4xNTMuMTQ0OjMwMjUwL0FJP1NIQTE9").decode("utf-8") + sha).text)
lists[int(info["Fen"])] = 1
dateVersion = info["Version"]
title = "null"
except:
traceback.print_exc()
QtWidgets.QMessageBox.critical(window, "错误", "无法获取预测数值")
return
informationList = [
"0分:无法运行并且也没有报错,自己无法解决",
"1分:无法运行但有报错,自己无法解决",
"2分:可以运行但是效果很差,几乎无法使用",
"3分:可以运行且勉强可以使用",
"4分:可以运行,体验大差不差,还是有点小问题",
"5分:可以运行且完全没有bug和问题,和在 Windows 上一样",
"含有不良内容,不宜安装",
"含有病毒、木马等对计算机有害的软件"
]
try:
if title.lower() == "null":
title = "未知应用"
except:
title = "未知应用"
maxHead = lists.index(max(lists))
ProgramRunStatusShow.msgWindow = QtWidgets.QMainWindow()
msgWidget = QtWidgets.QWidget()
msgWidgetLayout = QtWidgets.QGridLayout()
starLayout = QtWidgets.QHBoxLayout()
uploadButton = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "点此上传运行情况"))
uploadButton.clicked.connect(lambda: ProgramRunStatusUpload.ShowWindow(sha, title))
msgWidgetLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "综合评价:")), 0, 0)
msgWidgetLayout.addLayout(starLayout, 0, 1)
msgWidgetLayout.addWidget(QtWidgets.QLabel(informationList[maxHead]), 1, 0, 1, 2)
msgWidgetLayout.addWidget(QtWidgets.QLabel("" if dateVersion == "" else f"数据版本:{dateVersion}"), 2, 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"应用“{title}”的运行情况")
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(sha="", title=""):
ProgramRunStatusUpload.starList = []
ProgramRunStatusUpload.sha1Value = sha
ProgramRunStatusUpload.msgWindow = QtWidgets.QMainWindow()
msgWidget = QtWidgets.QWidget()
msgWidgetLayout = QtWidgets.QGridLayout()
ProgramRunStatusUpload.programName = QtWidgets.QLineEdit()
ProgramRunStatusUpload.fen = QtWidgets.QComboBox()
ProgramRunStatusUpload.starLayout = QtWidgets.QHBoxLayout()
upload = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "上传"))
upload.clicked.connect(ProgramRunStatusUpload.Upload)
if title != "":
ProgramRunStatusUpload.programName.setText(title)
ProgramRunStatusUpload.programName.setDisabled(True)
# 生成星星列表
for i in [1, 1, 1, 1, 0]:
ProgramRunStatusUpload.starList.append(QtWidgets.QLabel(f"<img src='{programPath}/Icon/{['Un', ''][i]}Star.svg' width=25>"))
ProgramRunStatusUpload.starLayout.addWidget(ProgramRunStatusUpload.starList[-1])
ProgramRunStatusUpload.starLayout.addItem(QtWidgets.QSpacerItem(20, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum))
ProgramRunStatusUpload.programName.setPlaceholderText(QtCore.QCoreApplication.translate("U", "如果这个程序和程序名确实是合法还是检测到敏感词,改为“NULL”即可"))
ProgramRunStatusUpload.fen.addItems(["0分:无法运行并且也没有报错,自己无法解决",
"1分:无法运行但有报错,自己无法解决",
"2分:可以运行但是效果很差,几乎无法使用",
"3分:可以运行且勉强可以使用",
"4分:可以运行,体验大差不差,还是有点小问题",
"5分:可以运行且完全没有bug和问题,和在 Windows 上一样",
"含有不良内容,不宜安装",
"含有病毒、木马等对计算机有害的软件"])
ProgramRunStatusUpload.fen.setCurrentIndex(4)
ProgramRunStatusUpload.fen.currentIndexChanged.connect(ProgramRunStatusUpload.ChangeStar)
msgWidgetLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "程序名:")), 0, 0)
msgWidgetLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "评分:")), 1, 0)
msgWidgetLayout.addWidget(ProgramRunStatusUpload.programName, 0, 1)
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():
if not os.path.exists(e2.currentText()):
QtWidgets.QMessageBox.critical(None, "错误", "exe 文件不存在!")
return
if ProgramRunStatusUpload.programName.text() == "":
QtWidgets.QMessageBox.critical(None, "错误", "程序名称不能为空!")
return
try:
if ProgramRunStatusUpload.sha1Value == "":
ProgramRunStatusUpload.sha1Value = ProgramRunStatusUpload.GetSHA1(e2.currentText())
QtWidgets.QMessageBox.information(None, QtCore.QCoreApplication.translate("U", "提示"), json.loads(requests.post(base64.b64decode("aHR0cDovLzEyMC4yNS4xNTMuMTQ0OjMwMjUw").decode("utf-8"), {
"SHA1": ProgramRunStatusUpload.sha1Value,
"Name": ProgramRunStatusUpload.programName.text(),
"Fen": ProgramRunStatusUpload.fen.currentIndex(),
"Wine": o1.currentText()
}).text)["Error"])
except:
traceback.print_exc()
QtWidgets.QMessageBox.critical(None, QtCore.QCoreApplication.translate("U", "错误"), QtCore.QCoreApplication.translate("U", "数据上传失败!"))
def GetSHA1(filePath):
sha1 = hashlib.sha1()
file = open(filePath, "rb")
while True:
readByte = file.read(1024 * 1024)
sha1.update(readByte)
if not readByte:
break
file.close()
return sha1.hexdigest()
class ProgramSetting():
wineBottonA = None
wineDebug = None
defultWine = None
defultBotton = None
terminalOpen = None
wineOption = None
#wineBottonDifferent = None
centerWindow = None
message = None
theme = None
monogeckoInstaller = None
autoWine = None
runtimeCache = None
buildByBottleName = None
autoPath = None
qemuUnmountHome = None
chineseLanguage = None
fontSize = None
def ShowWindow():
ProgramSetting.message = QtWidgets.QMainWindow()
widget = QtWidgets.QWidget()
widgetLayout = QtWidgets.QGridLayout()
widgetLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "选择 Wine 容器版本:")), 0, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "wine DEBUG 信息输出:")), 1, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "默认 Wine:")), 2, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "默认 Wine 容器:")), 3, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "使用终端打开:")), 4, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "自定义 wine 参数:")), 5, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "程序主题:")), 6, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "Wine 默认 Mono 和 Gecko 安装器:")), 7, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "忽略未安装的 Wine:")), 8, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "下载缓存:")), 9, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "图标生成:")), 10, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "自动根据EXE名称生成路径:")), 11, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "Qemu + Chroot 挂载用户目录:")), 12, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "程序翻译:")), 13, 0, 1, 1)
widgetLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "字体缩小比例(数值越大字体越小,默认为 1):")), 14, 0, 1, 1)
ProgramSetting.wineBottonA = QtWidgets.QComboBox()
ProgramSetting.wineDebug = QtWidgets.QCheckBox(QtCore.QCoreApplication.translate("U", "开启 DEBUG 输出"))
ProgramSetting.defultWine = QtWidgets.QComboBox()
ProgramSetting.defultBotton = QtWidgets.QLineEdit()
ProgramSetting.theme = QtWidgets.QComboBox()
ProgramSetting.theme.addItems(QtWidgets.QStyleFactory.keys())
ProgramSetting.theme.setCurrentText(setting["Theme"])
save = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "保存"))
save.clicked.connect(ProgramSetting.Save)
defultBottonButton = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "浏览"))
defultBottonButton.clicked.connect(ProgramSetting.Browser)
themeTry = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "测试(重启后变回设置的主题)"))
themeTry.clicked.connect(ProgramSetting.Try)
ProgramSetting.terminalOpen = QtWidgets.QCheckBox(QtCore.QCoreApplication.translate("U", "使用终端打开(deepin 终端)"))
ProgramSetting.wineOption = QtWidgets.QLineEdit()
ProgramSetting.monogeckoInstaller = QtWidgets.QCheckBox(QtCore.QCoreApplication.translate("U", "屏蔽 Wine 默认 Mono 和 Gecko 安装器"))
ProgramSetting.autoWine = QtWidgets.QCheckBox(QtCore.QCoreApplication.translate("U", "不显示未检测到的 Wine"))
ProgramSetting.runtimeCache = QtWidgets.QCheckBox(QtCore.QCoreApplication.translate("U", "开启下载缓存"))
ProgramSetting.buildByBottleName = QtWidgets.QCheckBox(QtCore.QCoreApplication.translate("U", "本软件构建的图标后面添加容器名"))
ProgramSetting.autoPath = QtWidgets.QCheckBox(QtCore.QCoreApplication.translate("U", "自动根据文件名生成容器路径(开启后必须通过修改默认wine容器路径才可指定其它路径,重启程序后生效)"))
ProgramSetting.qemuUnmountHome = QtWidgets.QCheckBox(QtCore.QCoreApplication.translate("U", "使用 Qemu + Chroot 时不挂载用户目录并与系统隔离(修改后重启操作系统生效)"))
ProgramSetting.chineseLanguage = QtWidgets.QCheckBox(QtCore.QCoreApplication.translate("U", "禁用程序界面翻译"))
ProgramSetting.fontSize = QtWidgets.QDoubleSpinBox()
ProgramSetting.wineBottonA.addItems(["Auto", "win32", "win64"])
ProgramSetting.wineBottonA.setCurrentText(setting["Architecture"])
ProgramSetting.wineDebug.setChecked(setting["Debug"])
ProgramSetting.defultWine.addItems(wine.keys())
ProgramSetting.defultWine.setCurrentText(setting["DefultWine"])
ProgramSetting.defultBotton.setText(setting["DefultBotton"])
ProgramSetting.terminalOpen.setChecked(setting["TerminalOpen"])
ProgramSetting.wineOption.setText(setting["WineOption"])
ProgramSetting.monogeckoInstaller.setChecked(setting["MonoGeckoInstaller"])
ProgramSetting.autoWine.setChecked(setting["AutoWine"])
ProgramSetting.runtimeCache.setChecked(setting["RuntimeCache"])
ProgramSetting.buildByBottleName.setChecked(setting["BuildByBottleName"])
ProgramSetting.autoPath.setChecked(setting["AutoPath"])
ProgramSetting.qemuUnmountHome.setChecked(setting["QemuUnMountHome"])
ProgramSetting.chineseLanguage.setChecked(setting["Chinese"])
ProgramSetting.fontSize.setValue(setting["FontSize"])
# QemuUnMountHome
widgetLayout.addWidget(ProgramSetting.wineBottonA, 0, 1, 1, 1)
widgetLayout.addWidget(ProgramSetting.wineDebug, 1, 1, 1, 1)
widgetLayout.addWidget(ProgramSetting.defultWine, 2, 1, 1, 1)
widgetLayout.addWidget(ProgramSetting.defultBotton, 3, 1, 1, 1)
widgetLayout.addWidget(defultBottonButton, 3, 2, 1, 1)
widgetLayout.addWidget(ProgramSetting.terminalOpen, 4, 1, 1, 1)
widgetLayout.addWidget(ProgramSetting.wineOption, 5, 1, 1, 1)
widgetLayout.addWidget(ProgramSetting.theme, 6, 1, 1, 1)
widgetLayout.addWidget(themeTry, 6, 2, 1, 1)
widgetLayout.addWidget(ProgramSetting.monogeckoInstaller, 7, 1, 1, 1)
widgetLayout.addWidget(ProgramSetting.autoWine, 8, 1, 1, 1)
widgetLayout.addWidget(ProgramSetting.runtimeCache, 9, 1, 1, 1)
widgetLayout.addWidget(ProgramSetting.buildByBottleName, 10, 1, 1, 1)
widgetLayout.addWidget(ProgramSetting.autoPath, 11, 1, 1, 2)
widgetLayout.addWidget(ProgramSetting.qemuUnmountHome, 12, 1, 1, 2)
widgetLayout.addWidget(ProgramSetting.chineseLanguage, 13, 1, 1, 2)
widgetLayout.addWidget(ProgramSetting.fontSize, 14, 1, 1, 2)
widgetLayout.addWidget(save, 15, 2, 1, 1)
widget.setLayout(widgetLayout)
ProgramSetting.message.setCentralWidget(widget)
ProgramSetting.message.setWindowIcon(QtGui.QIcon(iconPath))
ProgramSetting.message.setWindowTitle(f"设置 wine 运行器 {version}")
ProgramSetting.message.show()
def Browser():
path = QtWidgets.QFileDialog.getExistingDirectory(ProgramSetting.message, QtCore.QCoreApplication.translate("U", "选择 Wine 容器"), json.loads(readtxt(get_home() + "/.config/deepin-wine-runner/WineBotton.json"))["path"])
if path == "" or path == None or path == "()" or path == ():
return
ProgramSetting.defultBotton.setText(path)
def Try():
app.setStyle(QtWidgets.QStyleFactory.create(ProgramSetting.theme.currentText()))
def Save():
# 写入容器位数设置
setting["Architecture"] = ProgramSetting.wineBottonA.currentText()
setting["Debug"] = ProgramSetting.wineDebug.isChecked()
setting["DefultWine"] = ProgramSetting.defultWine.currentText()
setting["DefultBotton"] = ProgramSetting.defultBotton.text()
setting["TerminalOpen"] = ProgramSetting.terminalOpen.isChecked()
setting["WineOption"] = ProgramSetting.wineOption.text()
setting["Theme"] = ProgramSetting.theme.currentText()
setting["MonoGeckoInstaller"] = ProgramSetting.monogeckoInstaller.isChecked()
setting["AutoWine"] = ProgramSetting.autoWine.isChecked()
setting["RuntimeCache"] = ProgramSetting.runtimeCache.isChecked()
setting["BuildByBottleName"] = ProgramSetting.buildByBottleName.isChecked()
setting["AutoPath"] = ProgramSetting.autoPath.isChecked()
setting["QemuUnMountHome"] = ProgramSetting.qemuUnmountHome.isChecked()
setting["Chinese"] = ProgramSetting.chineseLanguage.isChecked()
setting["FontSize"] = ProgramSetting.fontSize.value()
try:
write_txt(get_home() + "/.config/deepin-wine-runner/WineSetting.json", json.dumps(setting))
except:
traceback.print_exc()
QtWidgets.QMessageBox.critical(ProgramSetting.message, "错误", traceback.format_exc())
return
QtWidgets.QMessageBox.information(ProgramSetting.message, "提示", "保存完毕!")
class ValueCheck():
def __init__(self):
pass
def BASE64(self, filePath):
src = ""
with open(filePath, "rb") as f:
base64Byte = base64.b64encode(f.read())
src += base64Byte.decode("utf-8")
return src
def SHA1(self, filePath):
sha1 = hashlib.sha1()
file = open(filePath, "rb")
while True:
readByte = file.read(1024 * 1024)
sha1.update(readByte)
if not readByte:
break
file.close()
return sha1.hexdigest()
def MD5(self, filePath):
md5 = hashlib.md5()
file = open(filePath, "rb")
while True:
readByte = file.read(1024 * 1024)
md5.update(readByte)
if not readByte:
break
file.close()
return md5.hexdigest()
def SHA256(self, filePath):
value = hashlib.sha256()
file = open(filePath, "rb")
while True:
readByte = file.read(1024 * 1024)
value.update(readByte)
if not readByte:
break
file.close()
return value.hexdigest()
def SHA384(self, filePath):
value = hashlib.sha384()
file = open(filePath, "rb")
while True:
readByte = file.read(1024 * 1024)
value.update(readByte)
if not readByte:
break
file.close()
return value.hexdigest()
def SHA224(self, filePath):
value = hashlib.sha224()
file = open(filePath, "rb")
while True:
readByte = file.read(1024 * 1024)
value.update(readByte)
if not readByte:
break
file.close()
return value.hexdigest()
def SHA512(self, filePath):
value = hashlib.sha512()
file = open(filePath, "rb")
while True:
readByte = file.read(1024 * 1024)
value.update(readByte)
if not readByte:
break
file.close()
return value.hexdigest()
link = {
"SHA1": SHA1,
"MD5": MD5,
"SHA256": SHA256,
"SHA512": SHA512,
"SHA224": SHA224,
"SHA384": SHA384,
"BASE64": BASE64
}
def Get(self, types):
QtWidgets.QMessageBox.information(window, "提示", "在计算过程中,程序可能会出现无响应的问题,请稍后\n请在接下来的打开对话框中选择要计算的文件")
file = QtWidgets.QFileDialog.getOpenFileName(window, "打开")[0]
if file == "":
return
try:
value = self.link[types](self, file)
if QtWidgets.QInputDialog.getText(window, "值", "下面是计算得到的值,<b>是否要复制到剪切板?</b>", QtWidgets.QLineEdit.Normal, value)[1]:
pyperclip.copy(value)
QtWidgets.QMessageBox.information(window, "提示", "复制成功!")
except:
traceback.print_exc()
QtWidgets.QMessageBox.critical(window, "错误", traceback.format_exc())
def ChangePath():
e1.setCurrentText(f'{setting["DefultBotton"]}/{os.path.splitext(os.path.basename(e2.currentText()))[0]}')
def ConnectRemoteWindowsPC(ip: str):
if os.system("which xfreerdp"):
if QtWidgets.QMessageBox.question(window, "提示", "未检测到 xfreerdp,是否立即安装?") == QtWidgets.QMessageBox.Yes:
OpenTerminal("sudo apt install xfreerdp -y")
return
os.system(f"xfreerdp '{ip}'")
def UploadLog():
if QtWidgets.QMessageBox.question(window, "提示", "您确定要上传吗?上传内容将不会公开,将用于加强日志分析功能") == QtWidgets.QMessageBox.Yes:
text = QtWidgets.QInputDialog.getMultiLineText(window, "输入内容", "输入描述信息")
try:
returnList = requests.post(base64.b64decode("aHR0cDovLzEyMC4yNS4xNTMuMTQ0OjMwMjUwL2xvZw==").decode("utf-8"), {
"Log": returnText.toPlainText(),
"Wine": wine[o1.currentText()],
"Tips": text
}).json()
if returnList["ExitCode"] == 0:
QtWidgets.QMessageBox.information(window, "提示", "上传成功!")
else:
print(returnList)
QtWidgets.QMessageBox.critical(window, "错误", "上传失败!")
except:
traceback.print_exc()
QtWidgets.QMessageBox.critical(window, "错误", "上传失败!")
def SaveLog():
path = QtWidgets.QFileDialog.getSaveFileName(window, "保存日志", get_home(), "txt文件(*.txt);;html 文件(*.html);;所有文件(*.*))")
if not path[1]:
return
print(path)
try:
with open(path[0], "w") as file:
if path[1] == "html 文件(*.html)":
file.write(returnText.toHtml())
else:
file.write(returnText.toPlainText())
except:
traceback.print_exc()
QtWidgets.QMessageBox.critical(window, "错误", traceback.format_exc())
def GetNewInformation():
try:
text = requests.get("http://wine-runner.gfdgdxi.top/info/").text
except:
traceback.print_exc()
text = f"""<p>无法连接到服务器</p>
<hr/>
<p>你可以尝试:</p>
<p>1. 判断是否能正常连接网络</p>
<p>2. 作者的服务出问题了?(到这反馈:<a href='https://gitee.com/gfdgd-xi/deep-wine-runner/issues'>https://gitee.com/gfdgd-xi/deep-wine-runner/issues</a>)</p>
<p>3. 玩个<a href="file://{programPath}/2048/index.html">游戏</a>解闷下</p>"""
global webInformation
if bad:
webInformation = QtWidgets.QTextBrowser()
else:
webInformation = QtWebEngineWidgets.QWebEngineView()
webInformation.setHtml(text)
webInformation.setWindowTitle("获取程序公告")
webInformation.setWindowIcon(QtGui.QIcon(iconPath))
webInformation.resize(int(webInformation.frameGeometry().width() * 1.3), int(webInformation.frameGeometry().height() * 1.1))
webInformation.show()
def getFileFolderSize(fileOrFolderPath):
"""get size for file or folder"""
totalSize = 0
try:
if not os.path.exists(fileOrFolderPath):
return totalSize
if os.path.isfile(fileOrFolderPath):
totalSize = os.path.getsize(fileOrFolderPath) # 5041481
return totalSize
if os.path.islink(fileOrFolderPath):
return 0
if os.path.isdir(fileOrFolderPath):
with os.scandir(fileOrFolderPath) as dirEntryList:
for curSubEntry in dirEntryList:
curSubEntryFullPath = os.path.join(fileOrFolderPath, curSubEntry.name)
if curSubEntry.is_dir():
curSubFolderSize = getFileFolderSize(curSubEntryFullPath) # 5800007
totalSize += curSubFolderSize
elif curSubEntry.is_file():
curSubFileSize = os.path.getsize(curSubEntryFullPath) # 1891
totalSize += curSubFileSize
return totalSize
except:
return totalSize
# 获取当前语言
def get_now_lang()->"获取当前语言":
return os.getenv('LANG')
# 又需要修复多线程导致的控件问题
def AddDockerMenu():
global dockers
global openFileManager
global openTerminal
dockers = menu.addMenu("该 Docker 基础管理")
openFileManager = QtWidgets.QAction("打开默认文件管理器")
openTerminal = QtWidgets.QAction("打开默认终端")
openFileManager.triggered.connect(lambda: threading.Thread(target=os.system, args=[f"xdg-open '{get_home()}'"]).start())
openTerminal.triggered.connect(lambda: threading.Thread(target=os.system, args=[f"x-terminal-emulator"]).start())
dockers.addAction(openFileManager)
dockers.addAction(openTerminal)
newPackage = False
class GetVersionThread(QtCore.QThread):
signal = QtCore.pyqtSignal(str)
def __init__(self) -> None:
super().__init__()
def run(self):
global about
global window
global newPackage
global programVersionType
# 目前分为几个版本(在 control 文件区分):
# 星火版本:~spark
# 商店版本:~uos
# 编译版本:无版本号
# Gitee/Github……:正常版本
# Docker 版本
programVersionTypeLnk = {
"spark": "普通版本",
"uos": "普通版本"
}
# 直接判断是不是 Docker 版本
if os.path.exists(f"{programPath}/docker.txt") or os.path.exists("/.dockerenv"):
programVersionType = "普通版本"
self.signal.emit("")
else:
programVersionType = "从源码运行的版本"
try:
if not os.path.exists("/var/lib/dpkg/status"):
print("无 dpkg,结束")
file = open("/var/lib/dpkg/status", "r")
fileName = file.read().splitlines()
package = False
for i in range(0, len(fileName)):
if fileName[i] == "Package: spark-deepin-wine-runner-docker":
programVersionType = "普通版本"
#AddDockerMenu()
self.signal.emit("")
break
if fileName[i] == "Package: spark-deepin-wine-runner-52":
programVersionType = "普通版本"
newPackage = False
break
if fileName[i] == "Package: spark-deepin-wine-runner":
package = True
newPackage = True
continue
if fileName[i] == "Package: wine-runner-linux":
package = True
continue
if not package:
continue
if fileName[i].replace(" ", "").replace("\n", "") == "":
# 空行,不再考虑
break
# 搜索版本号
try:
if fileName[i][:fileName[i].index(":")] == "Version":
version = fileName[i][fileName[i].index(":") + 1:].strip()
print(f"版本号为:{version}")
if not "-" in version:
programVersionType = "普通版本"
break
programVersionType = version[version.index("-") + 1:]
print(programVersionType)
if "-" in programVersionType:
# 考虑到如 2.1.0-2-spark 的情况
programVersionType = programVersionType[programVersionType.index("-") + 1:]
try:
programVersionType = programVersionTypeLnk[programVersionType]
except:
programVersionType = "普通版本"
break
except:
traceback.print_exc()
continue
except:
print("无法读取,当没有处理")
print(programVersionType)
about = about.replace("@VersionForType@", programVersionType)
# 获取程序体积
about = about.replace("@programSize@", str(int(getFileFolderSize(programPath) / 1024 / 1024)))
def GetVersion():
global runVersion
runVersion = GetVersionThread()
runVersion.signal.connect(AddDockerMenu)
runVersion.start()
def UnPackage():
QtWidgets.QMessageBox.information(window, "提示", "请在下面两个对话框中选择 deb 包所在路径和容器解压到的路径")
debPath = QtWidgets.QFileDialog.getOpenFileName(window, get_home(), "deb 文件(*.deb);;所有文件(*.*)")
if not debPath[1]:
return
path = QtWidgets.QFileDialog.getExistingDirectory(window, get_home())
print(path)
if not path:
return
tempDebDir = f"/tmp/wine-runner-unpack-deb-{random.randint(0, 1000)}"
if os.system(f"dpkg -x '{debPath[0]}' '{tempDebDir}'"):
QtWidgets.QMessageBox.critical(window, "错误", "解压失败!")
return
zippath = FindFile(tempDebDir, "files.7z")
if zippath == None:
QtWidgets.QMessageBox.critical(window, "错误", "解压失败!")
return
print(path)
# 解压文件
os.system(f"mkdir -p '{path}'")
os.system(f"7z x -y '{zippath}' -o'{path}'")
os.system(f"rm -rfv '{tempDebDir}'")
QtWidgets.QMessageBox.information(window, "提示", "解压完成!")
def FindFile(file, name):
for i in os.listdir(file):
path = f"{file}/{i}"
if os.path.isdir(path):
returnPath = FindFile(path, name)
if returnPath != None:
return returnPath.replace("//", "/")
if os.path.isfile(path):
if i == name:
return path
return None
def TransLog():
oldText = returnText.toPlainText()
lineNumber = 0
transText = ""
chooseText = ""
for i in oldText.splitlines():
lineNumber += 1
chooseText += f"{i}\n"
if lineNumber >= 50:
lineNumber = 0
try:
data = { 'doctype': 'json', 'type': 'auto','i': chooseText.replace("\n\n", "\n")}
jsonReturn = requests.post("http://fanyi.youdao.com/translate", data=data).json()["translateResult"]
for i in jsonReturn:
print(i)
transText += f'{i[0]["tgt"]}\n'
chooseText = ""
except:
transText += f"{chooseText}\n"
chooseText = ""
if lineNumber != 0:
lineNumber = 0
try:
data = { 'doctype': 'json', 'type': 'auto','i': chooseText.replace("\n\n", "\n")}
jsonReturn = requests.post("http://fanyi.youdao.com/translate", data=data).json()["translateResult"]
for i in jsonReturn:
print(i[0])
transText += f'{i[0]["tgt"]}\n'
chooseText = ""
except:
transText += f"{chooseText}\n"
chooseText = ""
#return transText
returnText.setText(transText.replace("\n\n", "\n"))
###########################
# 加载配置
###########################
if not os.path.exists(get_home() + "/.config/"): # 如果没有配置文件夹
os.mkdir(get_home() + "/.config/") # 创建配置文件夹
if not os.path.exists(get_home() + "/.config/deepin-wine-runner"): # 如果没有配置文件夹
os.mkdir(get_home() + "/.config/deepin-wine-runner") # 创建配置文件夹
if not os.path.exists(get_home() + "/.config/deepin-wine-runner/ShellHistory.json"): # 如果没有配置文件
write_txt(get_home() + "/.config/deepin-wine-runner/ShellHistory.json", json.dumps({})) # 创建配置文件
if not os.path.exists(get_home() + "/.config/deepin-wine-runner/FindExeHistory.json"): # 如果没有配置文件
write_txt(get_home() + "/.config/deepin-wine-runner/FindExeHistory.json", json.dumps({})) # 创建配置文件
if not os.path.exists(get_home() + "/.config/deepin-wine-runner/WineBottonHistory.json"): # 如果没有配置文件
write_txt(get_home() + "/.config/deepin-wine-runner/WineBottonHistory.json", json.dumps({})) # 创建配置文件
if not os.path.exists(get_home() + "/.config/deepin-wine-runner/ISOPath.json"): # 如果没有配置文件
write_txt(get_home() + "/.config/deepin-wine-runner/ISOPath.json", json.dumps({})) # 写入(创建)一个配置文件
if not os.path.exists(get_home() + "/.config/deepin-wine-runner/ISOPathFound.json"): # 如果没有配置文件
write_txt(get_home() + "/.config/deepin-wine-runner/ISOPathFound.json", json.dumps({})) # 写入(创建)一个配置文件
if not os.path.exists(get_home() + "/.config/deepin-wine-runner/FindExe.json"): # 如果没有配置文件
write_txt(get_home() + "/.config/deepin-wine-runner/FindExe.json", json.dumps({"path": "~"})) # 写入(创建)一个配置文件
if not os.path.exists(get_home() + "/.config/deepin-wine-runner/FindISO.json"): # 如果没有配置文件
write_txt(get_home() + "/.config/deepin-wine-runner/FindISO.json", json.dumps({"path": "~"})) # 写入(创建)一个配置文件
if not os.path.exists(get_home() + "/.config/deepin-wine-runner/WineBotton.json"): # 如果没有配置文件
write_txt(get_home() + "/.config/deepin-wine-runner/WineBotton.json", json.dumps({"path": "~/.deepinwine"})) # 写入(创建)一个配置文件
if not os.path.exists(get_home() + "/.config/deepin-wine-runner/WineSetting.json"): # 如果没有配置文件
write_txt(get_home() + "/.config/deepin-wine-runner/WineSetting.json", json.dumps(defultProgramList)) # 写入(创建)一个配置文件
###########################
# 设置变量
###########################
programPath = os.path.split(os.path.realpath(__file__))[0] # 返回 string
# 如果要添加其他 wine,请使用安装更多 Wine 功能
#############
# 检测 Wine
#############
def CheckWine():
global wine
global untipsWine
global canUseWine
try:
wine7zUse = ["wine", "wine64", "wine-i386", "wine-aarch64", "wine-x86_64"]
wine = {
"基于 UOS box86 的 deepin-wine6-stable": f"WINEPREDLL='{programPath}/dlls-arm' WINEDLLPATH=/opt/deepin-wine6-stable/lib BOX86_NOSIGSEGV=1 /opt/deepin-box86/box86 /opt/deepin-wine6-stable/bin/wine ",
"基于 UOS exagear 的 deepin-wine6-stable": f"WINEPREDLL='{programPath}/dlls-arm' WINEDLLPATH=/opt/deepin-wine6-stable/lib /opt/exagear/bin/ubt_x64a64_al --path-prefix {get_home()}/.deepinwine/debian-buster --utmp-paths-list {get_home()}/.deepinwine/debian-buster/.exagear/utmp-list --vpaths-list {get_home()}/.deepinwine/debian-buster/.exagear/vpaths-list --opaths-list {get_home()}/.deepinwine/debian-buster/.exagear/opaths-list --smo-mode fbase --smo-severity smart --fd-limit 8192 --foreign-ubt-binary /opt/exagear/bin/ubt_x32a64_al -- /opt/deepin-wine6-stable/bin/wine ",
"使用 Flatpak 安装的 Wine": "flatpak run org.winehq.Wine",
"deepin-wine8-stable": "deepin-wine8-stable",
"deepin-wine6 stable": "deepin-wine6-stable",
"deepin-wine6-vannila": "deepin-wine6-vannila",
"deepin-wine5 stable": "deepin-wine5-stable",
"spark-wine": "spark-wine",
"spark-wine7-devel": "spark-wine7-devel",
"spark-wine8": "spark-wine8",
"spark-wine8-wow": "spark-wine8-wow",
"deepin-wine": "deepin-wine",
"deepin-wine5": "deepin-wine5",
"wine": "wine",
"wine64": "wine64",
"ukylin-wine": "ukylin-wine",
"okylin-wine": "okylin-wine",
"mono(这不是 wine,但可以实现初步调用运行 .net 应用)": "mono",
"基于 linglong 的 deepin-wine6-stable(不推荐)": f"ll-cli run '' --exec '/bin/deepin-wine6-stable'"
}
untipsWine = ["使用 Flatpak 安装的 Wine", "基于 exagear 的 deepin-wine6-stable", "基于 UOS box86 的 deepin-wine6-stable", "基于 UOS exagear 的 deepin-wine6-stable", "基于 linglong 的 deepin-wine6-stable(不推荐)"]
canUseWine = []
if os.path.exists("/opt/deepin-box86/box86") and os.path.exists("/opt/deepin-wine6-stable/bin/wine"):
canUseWine.append("基于 UOS box86 的 deepin-wine6-stable")
if os.path.exists("/opt/exagear/bin/ubt_x64a64_al") and os.path.exists("/opt/deepin-wine6-stable/bin/wine"):
canUseWine.append("基于 UOS exagear 的 deepin-wine6-stable")
#if not os.system("which exagear") and os.path.exists("/opt/deepin-wine6-stable/bin/wine"):
#canUseWine.append("基于 exagear 的 deepin-wine6-stable")
for i in wine.keys():
if not os.system(f"which '{wine[i]}'"):
canUseWine.append(i)
if not os.system("which flatpak") and os.path.exists("/var/lib/flatpak/app/org.winehq.Wine"):
canUseWine.append("使用 Flatpak 安装的 Wine")
if os.path.exists("/persistent/linglong/layers/"): # 判断是否使用 linglong
for i in os.listdir("/persistent/linglong/layers/"):
try:
dire = os.listdir(f"/persistent/linglong/layers/{i}")[-1]
arch = os.listdir(f"/persistent/linglong/layers/{i}/{dire}")[-1]
if os.path.exists(f"/persistent/linglong/layers/{i}/{dire}/{arch}/runtime/bin/deepin-wine6-stable"):
wine["基于 linglong 的 deepin-wine6-stable(不推荐)"] = f"ll-cli run {i} --exec '/bin/deepin-wine6-stable'"
canUseWine.append("基于 linglong 的 deepin-wine6-stable(不推荐)")
break
except:
pass
# 读取自定义安装的 Wine(需要解包的才能使用)
global qemuBottleList
global qemuPath
qemuBottleList = []
qemuPath = f"{get_home()}/.deepin-wine-runner-ubuntu-images"
if not os.system("which qemu-i386-static"):
if os.path.exists(qemuPath):
for g in os.listdir(qemuPath):
archPath = f"{qemuPath}/{g}"
arch = g
if os.path.isdir(archPath):
for d in os.listdir(archPath):
bottlePath = f"{archPath}/{d}"
if os.path.isdir(bottlePath):
qemuBottleList.append([
arch,
d,
bottlePath
])
global shellHistory
global findExeHistory
global wineBottonHistory
global isoPath
global isoPathFound
global setting
shellHistory = list(json.loads(readtxt(get_home() + "/.config/deepin-wine-runner/ShellHistory.json")).values())
findExeHistory = list(json.loads(readtxt(get_home() + "/.config/deepin-wine-runner/FindExeHistory.json")).values())
wineBottonHistory = list(json.loads(readtxt(get_home() + "/.config/deepin-wine-runner/WineBottonHistory.json")).values())
isoPath = list(json.loads(readtxt(get_home() + "/.config/deepin-wine-runner/ISOPath.json")).values())
isoPathFound = list(json.loads(readtxt(get_home() + "/.config/deepin-wine-runner/ISOPathFound.json")).values())
setting = json.loads(readtxt(get_home() + "/.config/deepin-wine-runner/WineSetting.json"))
change = False
if not os.path.exists(get_home() + "/.config/deepin-wine-runner/mono-lock"):
os.mknod(f"{get_home()}/.config/deepin-wine-runner/mono-lock")
setting["MonoGeckoInstaller"] = False
change = True
for i in defultProgramList.keys():
if not i in setting:
change = True
setting[i] = defultProgramList[i]
if change:
write_txt(get_home() + "/.config/deepin-wine-runner/WineSetting.json", json.dumps(setting))
try:
# Read /opt Wine
try:
for i in os.listdir(f"/opt"):
for j in wine7zUse:
if os.path.exists(f"/opt/{i}/bin/{j}"):
wine[f"/opt/{i}/bin/{j}"] = f"/opt/{i}/bin/{j}"
canUseWine.append(f"/opt/{i}/bin/{j}")
except:
traceback.print_exc()
# 不再从列表读取,直接读目录
for i in os.listdir(f"{programPath}/wine/"):
#for i in json.loads(readtxt(f"{programPath}/wine/winelist.json")):
if os.path.exists(f"{programPath}/wine/{i}") and os.path.isdir(f"{programPath}/wine/{i}"):
name = ""
qemuInstall = False
nameValue = [["", ""]]
try:
if os.path.exists("/opt/deepin-box86/box86"):
nameValue.append(
[
"基于 UOS box86 的 ",
f"WINEPREDLL='{programPath}/dlls-arm' WINEDLLPATH=/opt/deepin-wine6-stable/lib BOX86_NOSIGSEGV=1 /opt/deepin-box86/box86 "
]
)
if os.system("which box86") == 0:
nameValue.append(
[
"基于 box86 的 ",
f"box86 "
]
)
if os.system("which box64") == 0:
nameValue.append(
[
"基于 box64 的 ",
f"box64 "
]
)
if os.system("which qemu-i386") == 0 and subprocess.getoutput("arch") != "x86_64" and subprocess.getoutput("arch") != "i386" and subprocess.getoutput("arch") != "i686":
nameValue.append(
[
"基于 qemu-i386 的 ",
f"qemu-i386 "
]
)
if os.system("which qemu-x86_64") == 0 and subprocess.getoutput("arch") != "x86_64" and subprocess.getoutput("arch") != "i386" and subprocess.getoutput("arch") != "i686":
nameValue.append(
[
"基于 qemu-x86_64 的 ",
f"qemu-x86_64 "
]
)
if os.path.exists("/opt/exagear/bin/ubt_x64a64_al") and os.path.exists(f"{get_home()}/.deepinwine/debian-buster"):
nameValue.append(
[
"基于 UOS exagear 的 ",
f"WINEPREDLL='{programPath}/dlls-arm' WINEDLLPATH=/opt/deepin-wine6-stable/lib /opt/exagear/bin/ubt_x64a64_al --path-prefix {get_home()}/.deepinwine/debian-buster --utmp-paths-list {get_home()}/.deepinwine/debian-buster/.exagear/utmp-list --vpaths-list {get_home()}/.deepinwine/debian-buster/.exagear/vpaths-list --opaths-list {get_home()}/.deepinwine/debian-buster/.exagear/opaths-list --smo-mode fbase --smo-severity smart --fd-limit 8192 --foreign-ubt-binary /opt/exagear/bin/ubt_x32a64_al -- "
]
)
if os.system("which exagear") == 0:
nameValue.append(
[
"运行 exagear 容器内的 ",
f"exagear -- "
]
)
if os.path.exists("/opt/exagear/bin/ubt_x64a64_al"):
nameValue.append(
[
"使用 ubt_x64a64_al 运行",
"/opt/exagear/bin/ubt_x64a64_al -- "
]
)
if os.path.exists("/opt/exagear/bin/ubt_x32a64_al"):
nameValue.append(
[
"使用 ubt_x32a64_al 运行",
"/opt/exagear/bin/ubt_x32a64_al -- "
]
)
for g in qemuBottleList:
nameValue.append([
f"使用qemu-{g[0]}-static 调用容器{g[1]}运行 ",
f"python3 '{programPath}/QemuRun.py' '{g[0]}/{g[1]}' {int(setting['QemuUnMountHome'])} "
])
except:
traceback.print_exc()
for k in nameValue:
print(k)
if "qemu" in k[0]:
chrootProgramPath = "/opt/apps/deepin-wine-runner"
else:
chrootProgramPath = programPath
for j in wine7zUse:
if os.path.exists(f"{programPath}/wine/{i}/bin/{j}"):
wine[f"{k[0]}{chrootProgramPath}/wine/{i}/bin/{j}"] = f"{k[1]}{chrootProgramPath}/wine/{i}/bin/{j}"
canUseWine.append(f"{k[0]}{chrootProgramPath}/wine/{i}/bin/{j}")
untipsWine.append(f"{k[0]}{chrootProgramPath}/wine/{i}/bin/{j}")
except:
traceback.print_exc()
try:
for i in os.listdir(f"{get_home()}/.deepinwine/"):
for j in wine7zUse:
if os.path.exists(f"{get_home()}/.deepinwine/{i}/bin/{j}"):
wine[f"{get_home()}/.deepinwine/{i}/bin/{j}"] = f"{get_home()}/.deepinwine/{i}/bin/{j}"
canUseWine.append(f"{get_home()}/.deepinwine/{i}/bin/{j}")
except:
traceback.print_exc()
try:
canUseWineOld = canUseWine[:]
for i in canUseWineOld:
if os.path.exists(f"{programPath}/WineLib/usr"):
wine[f"使用运行器的运行库运行 {i}"] = f"bash '{programPath}/WineLib/run.sh' {wine[i]}"
canUseWine.append(f"使用运行器的运行库运行 {i}")
untipsWine.append(f"使用运行器的运行库运行 {i}")
if os.path.exists("/opt/exagear/images"):
for k in os.listdir("/opt/exagear/images"):
if not os.path.isdir(f"/opt/exagear/images/{k}"):
continue
for i in canUseWineOld:
wine[f"使用Exagear容器运行库运行 {i}"] = f"bash '{programPath}/WineLib/run-more.sh' '/opt/exagear/images/{k}' {wine[i]}"
canUseWine.append(f"使用Exagear容器运行库运行 {i}")
untipsWine.append(f"使用Exagear容器运行库运行 {i}")
#if os.path.exists(f"{get_home()}/.deepinwine/debian-buster"):
#for i in canUseWineOld:
#wine[f"使用UOS Exagear容器运行库运行 {i}"] = f"bash '{programPath}/WineLib/run-more.sh' '{get_home()}/.deepinwine/debian-buster' {wine[i]}"
#canUseWine.append(f"使用UOS Exagear容器运行库运行 {i}")
#untipsWine.append(f"使用UOS Exagear容器运行库运行 {i}")
except:
traceback.print_exc()
except:
traceback.print_exc()
app = QtWidgets.QApplication(sys.argv)
QtWidgets.QMessageBox.critical(None, "错误", f"无法读取配置,无法继续\n{traceback.format_exc()}")
sys.exit(1)
CheckWine()
# transla.transe
programVersionType = ""
print(wine)
###########################
# 程序信息
###########################
app = QtWidgets.QApplication(sys.argv)
trans = QtCore.QTranslator()
transeObject = QtCore.QObject()
transla = QtCore.QCoreApplication.translate
#transeObject.tr("")
# 语言载入
if not "zh_CN".lower() in get_now_lang().lower() and not setting["Chinese"]:
trans.load(f"{programPath}/LANG/deepin-wine-runner-en_US.qm")
else:
pass
app.installTranslator(trans)
iconPath = "{}/deepin-wine-runner.svg".format(programPath)
iconPathList = [
"{}/deepin-wine-runner.svg".format(programPath),
f"{programPath}/Icon/Program/AboutIcon1.png",
f"{programPath}/Icon/Program/AboutIcon0.png",
f"{programPath}/Icon/Program/webp2.png",
f"{programPath}/Icon/Program/webp3.png",
f"{programPath}/Icon/Program/Windows虚拟机.png",
f"{programPath}/Icon/Program/wine打包器.png"
]
#iconPath = "{}/Icon/Program/wine运行器.png".format(programPath)
programUrl = "https://gitee.com/gfdgd-xi/deep-wine-runner\nhttps://github.com/gfdgd-xi/deep-wine-runner\nhttps://gfdgd-xi.github.io"
information = json.loads(readtxt(f"{programPath}/information.json"))
version = information["Version"]
goodRunSystem = QtCore.QCoreApplication.translate("U", "常见 Linux 发行版")
thankText = ""
lastRunCommand = "暂未运行命令"
tips = QtCore.QCoreApplication.translate("U", '''<h4>提示:</h4>
1、使用终端运行该程序,可以看到 wine 以及程序本身的提示和报错;
2、wine 32 位和 64 位的容器互不兼容;
3、所有的 wine 和 winetricks 均需要自行安装(可以从 菜单栏=>程序 里面进行安装);
4、本程序支持带参数运行 wine 程序(之前版本也可以),只需要按以下格式即可:
exe路径\' 参数 \'
即可(单引号需要输入);
5、wine 容器如果没有指定,则会默认为 ~/.wine;
6、如果可执行文件比较大的话,会出现点击“获取该程序运行情况”出现假死的情况,因为正在后台读取 SHA1,只需要等一下即可(读取速度依照您电脑处理速度、读写速度、可执行文件大小等有关);
7、如果非 X86 的用户的 UOS 专业版用户想要使用的话,只需要在应用商店安装一个 Wine 版本微信即可在本程序选择正确的 Wine 运行程序;''')
updateThingsString = QtCore.QCoreApplication.translate("U", '''<b>3.6.1 更新内容:</b>
※1、修复应用无法打开的问题
<b>3.6.0 更新内容:</b>
※1、修复高级打包器选择软件适配脚本后无法打包的问题 https://gitee.com/gfdgd-xi/deep-wine-runner/issues/I8I110
※2、支持调用 Deepin Wine8 Stable
※3、移除过时的 Wine 安装程序入口
※4、Wine 安装器支持根据地区自动选择国内源以及国际源
※5、Wine 安装器新增 Sourceforge 源
※6、新增 Wine 运行报告生成功能
※7、初步英语翻译
※8、新增离线安装包(只支持 amd64)
※9、支持识别 /opt 文件夹下的 Wine
10、新增 Wine 运行器视频教程的 Youtube 入口''')
for i in information["Thank"]:
thankText += f"{i}\n"
updateTime = "2023年12月24日"
aboutProgram = QtCore.QCoreApplication.translate("U", """<p>Wine运行器是一个能让Linux用户更加方便地运行Windows应用的程序。原版的 Wine 只能使用命令操作,且安装过程较为繁琐,对小白不友好。于是该运行器为了解决该痛点,内置了对Wine图形化的支持、Wine 安装器、微型应用商店、各种Wine工具、自制的Wine程序打包器、运行库安装工具等。</p>
<p>它同时还内置了基于Qemu/VirtualBox制作的、专供小白使用的Windows虚拟机安装工具,可以做到只需下载系统镜像并点击安装即可,无需考虑虚拟机的安装、创建、分区等操作,也能在非 X86 架构安装 X86 架构的 Windows 操作系统(但是效率较低,可以运行些老系统)。</p>
<p>而且对于部分 Wine 应用适配者来说,提供了图形化的打包工具,以及提供了一些常用工具以及运行库的安装方式,以及能安装多种不同的 Wine 以测试效果,能极大提升适配效率。</p>
<p>且对于 Deepin23 用户做了特别优化,以便能在缺少 i386 运行库的情况下运行 Wine32。同时也为非 X86 架构用户提供了 Box86/64、Qemu User 的安装方式</p>
<pre>""")
about = f'''<style>
a:link, a:active {{
text-decoration: none;
}}
</style>
<h1>关于</h1>
{aboutProgram}
版本:{version}
适用平台:{goodRunSystem}(@VersionForType@)
安装包构建时间:{information['Time']}
Qt 版本:{QtCore.qVersion()}
程序官网:{programUrl}
<b>Wine 运行器 QQ 交流群:762985460</b>
<b>Wine运行器 QQ 频道:https://pd.qq.com/s/edqkgeydx</b>
当前程序占用体积:@programSize@MB</pre>
<p>本程序依照 GPLV3 协议开源</p>
<hr>
<h1>鸣谢名单</h1>
<pre>{thankText}</pre>
<hr>
<h1>更新内容</h1>
<pre>{updateThingsString}
<b>更新时间:{updateTime}</b></pre>
<hr>
<h1>提示</h1>
<pre>{tips}
</pre>
<hr>
<h1>友谊链接</h1>
<pre>星火应用商店:<a href="https://spark-app.store/">https://spark-app.store/</a>
Deepin 官网:<a href="https://www.deepin.org">https://www.deepin.org</a>
Deepin 论坛:<a href="https://bbs.deepin.org">https://bbs.deepin.org</a>
gfdgd xi:<a href="https://gfdgd-xi.github.io">https://gfdgd-xi.github.io</a>
<hr>
<h1>©2020~{time.strftime("%Y")} By gfdgd xi</h1>'''
if os.path.exists(f"{programPath}/off-line.lock"):
title = "Wine 运行器 {}(离线模式)".format(version)
else:
title = "Wine 运行器 {}".format(version)
#<h1>©2020~{time.strftime("%Y")} <a href="https://gitee.com/gfdgd-xi">By gfdgd xi</h1>'''
updateThings = "{} 更新内容:\n{}\n更新时间:{}".format(version, updateThingsString, updateTime, time.strftime("%Y"))
try:
threading.Thread(target=requests.get, args=[parse.unquote(base64.b64decode("aHR0cDovLzEyMC4yNS4xNTMuMTQ0L3NwYXJrLWRlZXBpbi13aW5lLXJ1bm5lci9vcGVuL0luc3RhbGwucGhw").decode("utf-8")) + "?Version=" + version]).start()
except:
pass
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)
print(iconList)
# Qemu Lock
try:
if os.path.exists("/tmp/deepin-wine-runner-lock.txt"):
print("lock")
with open(f"/tmp/deepin-wine-runner-lock.txt", "r") as file:
setting["QemuUnMountHome"] = bool(int(file.read()))
else:
print("unlock")
with open(f"/tmp/deepin-wine-runner-lock.txt", "w") as file:
# = bool(int(file.read()))
file.write(str(int(setting["QemuUnMountHome"])))
except:
traceback.print_exc()
###########################
# 窗口创建
###########################
# 读取主题
# Qt 窗口
window = QtWidgets.QMainWindow()
defaultFont = app.font()
window.setWindowTitle(title)
widget = QtWidgets.QWidget()
window.setCentralWidget(widget)
mainLayout = QtWidgets.QGridLayout()
# 权重
size = QtWidgets.QSizePolicy()
size.setHorizontalPolicy(0)
widgetSize = QtWidgets.QSizePolicy()
#size.setHorizontalPolicy(0)
widgetSize.setVerticalPolicy(0)
#
leftUp = QtWidgets.QWidget()
mainLayout.addWidget(leftUp, 0, 0, 1, 1)
leftUpLayout = QtWidgets.QGridLayout()
leftUp.setLayout(leftUpLayout)
fastLabel = QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "快速启动"))
fastLabel.setStyleSheet("font: 30px;")
leftUpLayout.addWidget(fastLabel, 0, 0, 1, 2)
leftUpLayout.addWidget(QtWidgets.QLabel("<hr>"), 1, 0, 1, 2)
leftUpLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "请选择容器路径:")), 2, 0, 1, 1)
e1 = QtWidgets.QComboBox()
e1.setEditable(True)
leftUpLayout.addWidget(e1, 3, 0, 1, 1)
button1 = QtWidgets.QPushButton("浏览")
button1.clicked.connect(liulanbutton)
leftUpLayout.addWidget(button1, 3, 1, 1, 1)
leftUpLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "请选择要执行的程序(EXE、MSI或者命令):")), 4, 0, 1, 1)
e2 = QtWidgets.QComboBox()
if setting["AutoPath"]:
e2.editTextChanged.connect(ChangePath)
e2.setEditable(True)
leftUpLayout.addWidget(e2, 5, 0, 1, 1)
button2 = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "浏览"))
button2.clicked.connect(liulanexebutton)
leftUpLayout.addWidget(button2, 5, 1, 1, 1)
leftUpLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "请选择WINE版本:")), 6, 0, 1, 1)
o1 = QtWidgets.QComboBox()
leftUpLayout.addWidget(o1, 7, 0, 1, 1)
# 设置空间权重
button1.setSizePolicy(size)
button2.setSizePolicy(size)
leftDown = QtWidgets.QWidget()
mainLayout.addWidget(leftDown, 1, 0, 1, 1)
leftDownLayout = QtWidgets.QVBoxLayout()
leftDown.setLayout(leftDownLayout)
highLabel = QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "高级功能"))
highLabel.setStyleSheet("font: 30px;")
leftDownLayout.addWidget(highLabel)
leftDownLayout.addWidget(QtWidgets.QLabel("<hr>"))
leftDownLayout.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "创建快捷方式(Desktop文件):")))
createDesktopLink = QtWidgets.QHBoxLayout()
label_r_2 = QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "名称:"))
createDesktopLink.addWidget(label_r_2)
combobox1 = QtWidgets.QComboBox()
combobox1.setEditable(True)
createDesktopLink.addWidget(combobox1)
button5 = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "创建到桌面"))
button5.clicked.connect(make_desktop_on_desktop)
createDesktopLink.addWidget(button5)
saveDesktopFileOnLauncher = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "创建到开始菜单"))
saveDesktopFileOnLauncher.clicked.connect(make_desktop_on_launcher)
createDesktopLink.addWidget(saveDesktopFileOnLauncher)
leftDownLayout.addLayout(createDesktopLink)
programManager = QtWidgets.QGridLayout()
leftDownLayout.addLayout(programManager)
programManager.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "程序管理:")), 0, 0, 1, 1)
getProgramIcon = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "提取图标"))
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(QtWidgets.QLabel(" "*5), 1, 1, 1, 1)
trasButton = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "窗口透明工具"))
trasButton.clicked.connect(lambda: RunWineProgram(f"{programPath}/窗体透明度设置工具.exe"))
programManager.addWidget(trasButton, 1, 2, 1, 1)
uninstallProgram = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "卸载程序"))
uninstallProgram.clicked.connect(lambda: RunWineProgram(f"{programPath}/geek.exe"))
programManager.addWidget(QtWidgets.QLabel(" "*5), 1, 3, 1, 1)
programManager.addWidget(uninstallProgram, 1, 4, 1, 1)
miniAppStore = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "微型应用商店"))
miniAppStore.clicked.connect(lambda: threading.Thread(target=MiniAppStore).start())
programManager.addWidget(QtWidgets.QLabel(" "*5), 1, 5, 1, 1)
programManager.addWidget(miniAppStore, 1, 6, 1, 1)
programManager.addWidget(QtWidgets.QLabel(" "*5), 1, 7, 1, 1)
getProgramStatus = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "获取该程序运行情况"))
getProgramStatus.clicked.connect(ProgramRunStatusShow.ShowWindow)
programManager.addWidget(getProgramStatus, 1, 8, 1, 1)
getLoseDll = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "检测静态下程序缺少DLL"))
getLoseDll.clicked.connect(GetLoseDll)
programManager.addWidget(QtWidgets.QLabel(" "*5), 1, 9, 1, 1)
programManager.addWidget(getLoseDll, 1, 10, 1, 1)
programManager.addItem(QtWidgets.QSpacerItem(20, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum), 1, 11, 1, 1)
programManager.addWidget(QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "WINE配置:")), 2, 0, 1, 1)
wineConfig = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "配置容器"))
wineConfig.clicked.connect(lambda: RunWineProgram("winecfg"))
programManager.addWidget(wineConfig, 3, 0, 1, 1)
fontAppStore = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "字体商店"))
fontAppStore.clicked.connect(FontAppStore)
programManager.addWidget(fontAppStore, 3, 2, 1, 1)
button_r_6 = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "RegShot"))
button_r_6.clicked.connect(lambda: RunWineProgram(f"{programPath}/RegShot/regshot.exe"))
programManager.addWidget(button_r_6, 3, 4, 1, 1)
sparkWineSetting = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "星火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)
wineAutoConfig = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "自动/手动配置 Wine 容器"))
wineAutoConfig.clicked.connect(WineBottonAutoConfig)
programManager.addWidget(wineAutoConfig, 3, 8, 1, 1)
wineBottleReboot = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "重启指定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)
returnText = QtWidgets.QTextBrowser()
returnText.setStyleSheet("""
background-color: black;
color: white;
""")
returnText.setText(QtCore.QCoreApplication.translate("U", """在此可以看到wine安装应用时的终端输出内容
=============================================
如果解决了你的问题,请不要吝啬你的star哟!
地址:
https://gitee.com/gfdgd-xi/deep-wine-runner
https://github.com/gfdgd-xi/deep-wine-runner
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)
# 版权
copy = QtWidgets.QLabel(f"""程序版本:{version},<b>提示:Wine 无法保证可以运行所有的 Windows 程序,如果想要运行更多 Windows 程序,可以考虑虚拟机和双系统</b><br/>
<b>注:部分二进制兼容层会自动注册 binfmt(如原版的 Box86/64、Qemu User Static),则意味着无需在 Wine 版本那里特别指定兼容层,直接指定 Wine 即可</b><br/>
©2020~{time.strftime("%Y")} gfdgd xi""")
mainLayout.addWidget(copy, 2, 0, 1, 1)
# 程序运行
programRun = QtWidgets.QWidget()
programRunLayout = QtWidgets.QHBoxLayout()
programRun.setLayout(programRunLayout)
programRunLayout.addItem(QtWidgets.QSpacerItem(20, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum))
button3 = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "运行程序"))
button3.clicked.connect(runexebutton)
programRunLayout.addWidget(button3)
killProgram = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "终止程序"))
killProgram.clicked.connect(KillProgram)
programRunLayout.addWidget(killProgram)
killBottonProgram = QtWidgets.QPushButton(QtCore.QCoreApplication.translate("U", "终止指定容器的程序"))
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)
# 菜单栏
menu = window.menuBar()
programmenu = menu.addMenu(QtCore.QCoreApplication.translate("U", "程序(&P)"))
p1 = QtWidgets.QAction(QtGui.QIcon(f"{programPath}/Icon/Function/wine.png"), QtCore.QCoreApplication.translate("U", "安装 wine(&I)"))
#installWineOnDeepin23 = QtWidgets.QAction(QtGui.QIcon(f"{programPath}/Icon/Function/wine23P.png"), QtCore.QCoreApplication.translate("U", "安装 wine(只限Deepin23 Preview)"))
#installWineOnDeepin23Alpha = QtWidgets.QAction(QtGui.QIcon(f"{programPath}/Icon/Function/wine23A.png"), QtCore.QCoreApplication.translate("U", "安装 wine(只限Deepin23 Alpha)"))
installWineHQOrg = QtWidgets.QAction(QtGui.QIcon(f"{programPath}/Icon/Function/wine.png"), QtCore.QCoreApplication.translate("U", "安装 WineHQ(官方源)"))
installWineHQ = QtWidgets.QAction(QtGui.QIcon(f"{programPath}/Icon/Function/wine.png"), QtCore.QCoreApplication.translate("U", "安装 WineHQ(国内清华大学镜像源)"))
installMoreWine = QtWidgets.QAction(QtGui.QIcon(f"{programPath}/Icon/Function/more-wine.png"), QtCore.QCoreApplication.translate("U", "安装更多 Wine(Wine 下载工具,推荐)"))
downloadChrootBottle = QtWidgets.QAction(QtGui.QIcon(f"{programPath}/Icon/Function/CHROOT.png"), QtCore.QCoreApplication.translate("U", "下载 Chroot 容器"))
installBox86CN = QtWidgets.QAction(QtGui.QIcon.fromTheme("box"), QtCore.QCoreApplication.translate("U", "安装 Box86/Box64 日构建(国内源)"))
installBox86 = QtWidgets.QAction(QtGui.QIcon.fromTheme("box"), QtCore.QCoreApplication.translate("U", "安装 Box86/Box64 日构建(国外 Github 源)"))
installBox86Own = QtWidgets.QAction(QtGui.QIcon.fromTheme("box"), QtCore.QCoreApplication.translate("U", "安装 Box86/Box64(使用自建源,支持 riscv64)"))
installLat = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "安装 lat(只限 Loongarch64 架构)"))
addWineDebMirrorForDeepin20 = QtWidgets.QAction(QtGui.QIcon(f"{programPath}/Icon/Function/wine.png"), QtCore.QCoreApplication.translate("U", "添加 Wine 运行器源以安装较新版本的 WineHQ(支持 Deepin20/Debian10)"))
p2 = QtWidgets.QAction(QtGui.QIcon.fromTheme("settings"), QtCore.QCoreApplication.translate("U", "设置程序(&S)"))
enabledAll = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "强制启用所有被禁用的组件(不推荐)"))
setMiniFont = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "临时设置小字体"))
setTinyFont = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "临时设置很小的字体"))
setDefaultFont = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "临时设置默认字体"))
p3 = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(47), QtCore.QCoreApplication.translate("U", "清空软件历史记录(&C)"))
cleanCache = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(47), QtCore.QCoreApplication.translate("U", "清空软件缓存"))
cleanProgramUnuse = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(47), QtCore.QCoreApplication.translate("U", "删除程序组件"))
p4 = QtWidgets.QAction(QtGui.QIcon.fromTheme("exit"), QtCore.QCoreApplication.translate("U", "退出程序(&E)"))
programmenu.addAction(p1)
#programmenu.addAction(installWineOnDeepin23)
#programmenu.addAction(installWineOnDeepin23Alpha)
programmenu.addAction(installWineHQ)
programmenu.addAction(installWineHQOrg)
programmenu.addAction(addWineDebMirrorForDeepin20)
programmenu.addAction(installMoreWine)
programmenu.addAction(downloadChrootBottle)
programmenu.addAction(installBox86CN)
programmenu.addAction(installBox86)
programmenu.addAction(installBox86Own)
programmenu.addAction(installLat)
#programmenu.addSeparator()
#programmenu.addAction(setMiniFont)
#programmenu.addAction(setTinyFont)
#programmenu.addAction(setDefaultFont)
programmenu.addSeparator()
programmenu.addAction(p2)
programmenu.addAction(enabledAll)
programmenu.addSeparator()
programmenu.addAction(p3)
programmenu.addAction(cleanCache)
programmenu.addAction(cleanProgramUnuse)
programmenu.addSeparator()
programmenu.addAction(p4)
setDefaultFont.triggered.connect(lambda: SetFont(1))
setMiniFont.triggered.connect(lambda: SetFont(1.2))
setTinyFont.triggered.connect(lambda: SetFont(1.6))
p1.triggered.connect(InstallWine)
#installWineOnDeepin23.triggered.connect(InstallWineOnDeepin23)
#installWineOnDeepin23Alpha.triggered.connect(InstallWineOnDeepin23Alpha)
installWineHQ.triggered.connect(InstallWineHQ)
installWineHQOrg.triggered.connect(lambda: threading.Thread(target=OpenTerminal, args=[f"{programPath}/InstallNewWineHQOrg.sh"]).start())
installLat.triggered.connect(lambda: threading.Thread(target=OpenTerminal, args=[f"{programPath}/InstallLat.sh"]).start())
addWineDebMirrorForDeepin20.triggered.connect(lambda: threading.Thread(target=OpenTerminal, args=[f"bash '{programPath}/AddWineDebMirrorForDeepin20.sh'"]).start())
def InstallMoreWine():
os.system(f"'{programPath}/wine/installwine'")
# 更新 Wine 列表
CheckWine()
o1.clear()
if setting["AutoWine"]:
o1.addItems(canUseWine)
else:
o1.addItems(wine.keys())
#installMoreWine.triggered.connect(lambda: threading.Thread(target=os.system, args=[f"'{programPath}/wine/installwine'"]).start())
installMoreWine.triggered.connect(InstallMoreWine)
downloadChrootBottle.triggered.connect(lambda: threading.Thread(target=os.system, args=[f"'{programPath}/QemuDownload.py'"]).start())
p2.triggered.connect(ProgramSetting.ShowWindow)
enabledAll.triggered.connect(lambda: DisableButton(False))
installBox86CN.triggered.connect(lambda: OpenTerminal(f"sudo bash '{programPath}/InstallBox86-cn.sh'"))
installBox86.triggered.connect(lambda: OpenTerminal(f"sudo bash '{programPath}/InstallBox86.sh'"))
installBox86Own.triggered.connect(lambda: OpenTerminal(f"sudo bash '{programPath}/InstallBox86-own.sh'"))
p3.triggered.connect(CleanProgramHistory)
cleanCache.triggered.connect(CleanProgramCache)
cleanProgramUnuse.triggered.connect(CleanProgram)
p4.triggered.connect(window.close)
wineOption = menu.addMenu(QtCore.QCoreApplication.translate("U", "Wine(&W)"))
w1 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "打开 Wine 容器目录"))
w2 = QtWidgets.QAction(QtGui.QIcon.fromTheme("font"), QtCore.QCoreApplication.translate("U", "安装常见字体"))
w3 = QtWidgets.QAction(QtGui.QIcon.fromTheme("font"), QtCore.QCoreApplication.translate("U", "安装自定义字体"))
w4 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "删除选择的 Wine 容器"))
cleanBottonUOS = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "清理 Wine 容器(基于 Wine 适配活动脚本)"))
wineKeyboardLnk = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "Wine 快捷键映射"))
w5 = QtWidgets.QAction(QtGui.QIcon.fromTheme("deb"), QtCore.QCoreApplication.translate("U", "打包 wine 应用(专业用户使用)"))
w6 = QtWidgets.QAction(QtGui.QIcon.fromTheme("deb"), QtCore.QCoreApplication.translate("U", "使用官方 Wine 适配活动的脚本进行打包"))
easyPackager = QtWidgets.QAction(QtGui.QIcon.fromTheme("deb"), QtCore.QCoreApplication.translate("U", "使用简易打包器进行打包(小白且无特殊需求建议使用这个)"))
getDllOnInternet = QtWidgets.QAction(QtGui.QIcon.fromTheme("1CD8_rundll32.0"), QtCore.QCoreApplication.translate("U", "从互联网获取DLL"))
w7 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "从镜像获取DLL(只支持官方安装镜像,DOS内核如 Windows 95 暂不支持)"))
updateGeek = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "从 Geek Uninstaller 官网升级程序"))
deletePartIcon = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "快捷方式管理工具"))
deleteDesktopIcon = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "删除所有 Wine 程序在启动器的快捷方式"))
wineOption.addAction(w1)
wineOption.addAction(w2)
wineOption.addAction(w3)
wineOption.addAction(w4)
wineOption.addAction(cleanBottonUOS)
wineOption.addSeparator()
wineOption.addAction(w5)
wineOption.addAction(w6)
wineOption.addAction(easyPackager)
wineOption.addAction(deletePartIcon)
wineOption.addSeparator()
wineOption.addAction(wineKeyboardLnk)
wineOption.addSeparator()
wineOption.addAction(getDllOnInternet)
wineOption.addAction(w7)
wineOption.addSeparator()
wineOption.addAction(updateGeek)
wineOption.addSeparator()
wm1 = wineOption.addMenu(QtCore.QCoreApplication.translate("U", "在指定 Wine、容器安装组件"))
wm1_1 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "在指定wine、指定容器安装 .net framework"))
wm1_2 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "在指定wine、指定容器安装 Visual Studio C++"))
wm1_8 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "在指定wine、指定容器安装 Visual FoxPro"))
wm1_3 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "在指定wine、指定容器安装 MSXML"))
wm1_4 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "在指定wine、指定容器安装 gecko"))
wm1_5 = QtWidgets.QAction(QtGui.QIcon.fromTheme("mono"), QtCore.QCoreApplication.translate("U", "在指定wine、指定容器安装 mono"))
wm1_7 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "在指定wine、指定容器安装 Visual Basic Runtime"))
wm1_6 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "在指定wine、指定容器安装其它运行库"))
wm1.addAction(wm1_1)
wm1.addAction(wm1_2)
wm1.addAction(wm1_8)
wm1.addAction(wm1_3)
wm1.addAction(wm1_4)
wm1.addAction(wm1_5)
wm1.addAction(wm1_7)
wm1.addAction(wm1_6)
wm2 = wineOption.addMenu(QtCore.QCoreApplication.translate("U", "在指定 Wine、容器运行基础应用"))
wm2_1 = QtWidgets.QAction(QtGui.QIcon.fromTheme("control-center2"), QtCore.QCoreApplication.translate("U", "打开指定wine、指定容器的控制面板"))
wm2_2 = QtWidgets.QAction(QtGui.QIcon.fromTheme("web-browser"), QtCore.QCoreApplication.translate("U", "打开指定wine、指定容器的浏览器"))
wm2_3 = QtWidgets.QAction(QtGui.QIcon.fromTheme("regedit"), QtCore.QCoreApplication.translate("U", "打开指定wine、指定容器的注册表"))
wm2_4 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "打开指定wine、指定容器的任务管理器"))
wm2_5 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "打开指定wine、指定容器的资源管理器"))
wm2_6 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "打开指定wine、指定容器的关于 wine"))
wm2.addAction(wm2_1)
wm2.addAction(wm2_2)
wm2.addAction(wm2_3)
wm2.addAction(wm2_4)
wm2.addAction(wm2_5)
wm2.addAction(wm2_6)
wineOption.addSeparator()
settingRunV3Sh = wineOption.addMenu(QtCore.QCoreApplication.translate("U", "run_v3.sh 管理"))
w8 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "设置 run_v3.sh 的文管为 Deepin 默认文管"))
w9 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "设置 run_v3.sh 的文管为 Wine 默认文管"))
w10 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "重新安装 deepin-wine-helper"))
w11 = QtWidgets.QAction(QtGui.QIcon.fromTheme("winetricks"), QtCore.QCoreApplication.translate("U", "使用winetricks打开指定容器"))
w11WithWineLib = QtWidgets.QAction(QtGui.QIcon.fromTheme("winetricks"), QtCore.QCoreApplication.translate("U", "使用winetricks打开指定容器(使用Wine运行器运行库)"))
w11WithWineLib.setDisabled(True)
settingRunV3Sh.addAction(w8)
settingRunV3Sh.addAction(w9)
settingRunV3Sh.addAction(w10)
wineOption.addSeparator()
wineOption.addAction(w11)
#wineOption.addAction(w11WithWineLib)
wineOption.addSeparator()
optionCheckDemo = wineOption.addMenu(QtCore.QCoreApplication.translate("U", "组件功能测试"))
vbDemo = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "测试 Visual Basic 6 程序"))
netDemo = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "测试 .net framework 程序"))
netIEDemo = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "测试 .net framework + Internet Explorer 程序"))
optionCheckDemo.addAction(vbDemo)
optionCheckDemo.addAction(netDemo)
optionCheckDemo.addAction(netIEDemo)
wineOption.addSeparator()
wm3 = wineOption.addMenu(QtCore.QCoreApplication.translate("U", "启用/禁用功能"))
ed1 = wm3.addMenu(QtCore.QCoreApplication.translate("U", "启用/禁用 opengl"))
wm3_1 = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(45), QtCore.QCoreApplication.translate("U", "开启 opengl"))
wm3_2 = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(40), QtCore.QCoreApplication.translate("U", "禁用 opengl"))
ed1.addAction(wm3_1)
ed1.addAction(wm3_2)
ed2 = wm3.addMenu(QtCore.QCoreApplication.translate("U", "安装/卸载 winbind"))
wm4_1 = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(45), QtCore.QCoreApplication.translate("U", "安装 winbind"))
wm4_2 = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(40), QtCore.QCoreApplication.translate("U", "卸载 winbind"))
ed2.addAction(wm4_1)
ed2.addAction(wm4_2)
dxvkMenu = wm3.addMenu(QtCore.QCoreApplication.translate("U", "安装/卸载 DXVK"))
installDxvk = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(45), QtCore.QCoreApplication.translate("U", "安装 DXVK"))
uninstallDxvk = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(40), QtCore.QCoreApplication.translate("U", "卸载 DXVK"))
dxvkMenu.addAction(installDxvk)
dxvkMenu.addAction(uninstallDxvk)
vkd3dMenu = wm3.addMenu(QtCore.QCoreApplication.translate("U", "安装/卸载 Vkd3d"))
installvkd3d = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(45), QtCore.QCoreApplication.translate("U", "安装 Vkd3d"))
uninstallvkd3d = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(40), QtCore.QCoreApplication.translate("U", "卸载 Vkd3d"))
vkd3dMenu.addAction(installvkd3d)
vkd3dMenu.addAction(uninstallvkd3d)
wineOption.addSeparator()
wineOption.addAction(deleteDesktopIcon)
wineOption.addSeparator()
settingWineBottleCreateLink = wm3.addMenu(QtCore.QCoreApplication.translate("U", "启用/禁止指定 wine 容器生成快捷方式"))
enabledWineBottleCreateLink = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(45), QtCore.QCoreApplication.translate("U", "允许指定 wine 容器生成快捷方式"))
disbledWineBottleCreateLink = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(40), QtCore.QCoreApplication.translate("U", "禁止指定 wine 容器生成快捷方式"))
settingWineBottleCreateLink.addAction(enabledWineBottleCreateLink)
settingWineBottleCreateLink.addAction(disbledWineBottleCreateLink)
settingWineCrashDialog = wm3.addMenu(QtCore.QCoreApplication.translate("U", "启用/禁用指定 wine 容器崩溃提示窗口"))
disbledWineCrashDialog = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(40), QtCore.QCoreApplication.translate("U", "禁用指定 wine 容器崩溃提示窗口"))
enabledWineCrashDialog = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(45), QtCore.QCoreApplication.translate("U", "启用指定 wine 容器崩溃提示窗口"))
settingWineCrashDialog.addAction(enabledWineCrashDialog)
settingWineCrashDialog.addAction(disbledWineCrashDialog)
settingOpenProgram = wm3.addMenu(QtCore.QCoreApplication.translate("U", "启用/禁止指定 wine 容器创建文件关联"))
enabledOpenProgram = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(45), QtCore.QCoreApplication.translate("U", "允许指定 wine 容器创建文件关联"))
disbledOpenProgram = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(40), QtCore.QCoreApplication.translate("U", "禁止指定 wine 容器创建文件关联"))
settingOpenProgram.addAction(enabledOpenProgram)
settingOpenProgram.addAction(disbledOpenProgram)
settingHttpProxy = wineOption.addMenu(QtCore.QCoreApplication.translate("U", "设置指定 Wine 容器代理"))
enabledHttpProxy = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "设置指定 wine 容器的代理"))
disbledHttpProxy = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(40), QtCore.QCoreApplication.translate("U", "禁用指定 wine 容器的代理"))
settingHttpProxy.addAction(enabledHttpProxy)
settingHttpProxy.addAction(disbledHttpProxy)
dllOver = wineOption.addMenu(QtCore.QCoreApplication.translate("U", "函数顶替库列表"))
saveDllOver = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(43), QtCore.QCoreApplication.translate("U", "导出函数顶替列表"))
addDllOver = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(32), QtCore.QCoreApplication.translate("U", "导入函数顶替列表"))
editDllOver = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "编辑函数顶替库列表"))
dllOver.addAction(saveDllOver)
dllOver.addAction(addDllOver)
dllOver.addAction(editDllOver)
w1.triggered.connect(OpenWineBotton)
w2.triggered.connect(InstallWineFont)
w3.triggered.connect(OpenWineFontPath)
w4.triggered.connect(DeleteWineBotton)
cleanBottonUOS.triggered.connect(CleanWineBottonByUOS)
w5.triggered.connect(BuildExeDeb)
w6.triggered.connect(UOSPackageScript)
easyPackager.triggered.connect(lambda: threading.Thread(target=os.system, args=[f"'{programPath}/deepin-wine-easy-packager.py' '{e2.currentText()}'"]).start())
wineKeyboardLnk.triggered.connect(lambda: threading.Thread(target=os.system, args=[f"'{programPath}/key/key-add-gui.py'"]).start())
getDllOnInternet.triggered.connect(GetDllFromInternet)
w7.triggered.connect(GetDllFromWindowsISO.ShowWindow)
updateGeek.triggered.connect(lambda: os.system(f"'{programPath}/launch.sh' deepin-terminal -C '\"{programPath}/UpdateGeek.sh\"' --keep-open"))
w8.triggered.connect(SetDeepinFileDialogDeepin)
w9.triggered.connect(SetDeepinFileDialogDefult)
w10.triggered.connect(SetDeepinFileDialogRecovery)
w11.triggered.connect(lambda: RunWinetricks())
w11WithWineLib.triggered.connect(lambda: RunWinetricksWithWineLib())
wm1_1.triggered.connect(lambda: threading.Thread(target=InstallNetFramework).start())
wm1_2.triggered.connect(lambda: threading.Thread(target=InstallVisualStudioCPlusPlus).start())
wm1_8.triggered.connect(lambda: threading.Thread(target=InstallFoxPro).start())
wm1_3.triggered.connect(lambda: threading.Thread(target=InstallMSXML).start())
wm1_4.triggered.connect(lambda: threading.Thread(target=InstallMonoGecko, args=["gecko"]).start())
wm1_5.triggered.connect(lambda: threading.Thread(target=InstallMonoGecko, args=["mono"]).start())
wm1_7.triggered.connect(lambda: threading.Thread(target=InstallVB).start())
wm1_6.triggered.connect(lambda: threading.Thread(target=InstallOther).start())
wm2_1.triggered.connect(lambda: RunWineProgram("control"))
wm2_2.triggered.connect(lambda: RunWineProgram("iexplore' 'https://gfdgd-xi.github.io"))
wm2_3.triggered.connect(lambda: RunWineProgram("regedit"))
wm2_4.triggered.connect(lambda: RunWineProgram("taskmgr"))
wm2_5.triggered.connect(lambda: RunWineProgram("explorer"))
wm2_6.triggered.connect(lambda: RunWineProgram("winver"))
wm3_1.triggered.connect(lambda: RunWineProgram(f"regedit.exe' /s '{programPath}/EnabledOpengl.reg"))
wm3_2.triggered.connect(lambda: RunWineProgram(f"regedit.exe' /s '{programPath}/DisabledOpengl.reg"))
wm4_1.triggered.connect(lambda: os.system(f"'{programPath}/launch.sh' deepin-terminal -C 'pkexec apt install winbind -y' --keep-open"))
wm4_2.triggered.connect(lambda: os.system(f"'{programPath}/launch.sh' deepin-terminal -C 'pkexec apt purge winbind -y' --keep-open"))
installDxvk.triggered.connect(InstallDXVK)
uninstallDxvk.triggered.connect(UninstallDXVK)
installvkd3d.triggered.connect(InstallVkd3d)
uninstallvkd3d.triggered.connect(UninstallVkd3d)
deletePartIcon.triggered.connect(lambda: threading.Thread(target=os.system, args=[f"python3 '{programPath}/BuildDesktop.py'"]).start())
deleteDesktopIcon.triggered.connect(DeleteDesktopIcon)
enabledWineBottleCreateLink.triggered.connect(lambda: RunWineProgram("reg' delete 'HKEY_CURRENT_USER\Software\Wine\DllOverrides' /v winemenubuilder.exe '/f"))
disbledWineBottleCreateLink.triggered.connect(lambda: RunWineProgram("reg' add 'HKEY_CURRENT_USER\Software\Wine\DllOverrides' /v winemenubuilder.exe '/f"))
disbledWineCrashDialog.triggered.connect(lambda: RunWineProgram("reg' add 'HKEY_CURRENT_USER\Software\Wine\WineDbg' /v ShowCrashDialog /t REG_DWORD /d 00000000 '/f"))
enabledWineCrashDialog.triggered.connect(lambda: RunWineProgram("reg' add 'HKEY_CURRENT_USER\Software\Wine\WineDbg' /v ShowCrashDialog /t REG_DWORD /d 00000001 '/f"))
disbledOpenProgram.triggered.connect(lambda: RunWineProgram("reg' add 'HKEY_CURRENT_USER\Software\Wine\FileOpenAssociations' /v Enable /d N '/f"))
enabledOpenProgram.triggered.connect(lambda: RunWineProgram("reg' add 'HKEY_CURRENT_USER\Software\Wine\FileOpenAssociations' /v Enable /d Y '/f"))
enabledHttpProxy.triggered.connect(SetHttpProxy)
disbledHttpProxy.triggered.connect(DisbledHttpProxy)
saveDllOver.triggered.connect(SaveDllList)
addDllOver.triggered.connect(AddReg)
editDllOver.triggered.connect(lambda: RunWineProgram("winecfg"))
vbDemo.triggered.connect(lambda: RunWineProgram(f"{programPath}/Test/vb.exe"))
netDemo.triggered.connect(lambda: RunWineProgram(f"{programPath}/Test/net.exe"))
netIEDemo.triggered.connect(lambda: RunWineProgram(f"{programPath}/Test/netandie.exe"))
virtualMachine = menu.addMenu(QtCore.QCoreApplication.translate("U", "虚拟机(&V)"))
v1 = QtWidgets.QAction(QtGui.QIcon.fromTheme("virtualbox"), QtCore.QCoreApplication.translate("U", "使用虚拟机运行 Windows 应用"))
virtualMachine.addAction(v1)
v1.triggered.connect(RunVM)
checkValue = menu.addMenu(QtCore.QCoreApplication.translate("U", "校验值计算(&S)"))
md5Value = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(32), QtCore.QCoreApplication.translate("U", "MD5(&M)"))
sha1Value = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(32), QtCore.QCoreApplication.translate("U", "SHA1(&M)"))
base64Value = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(32), QtCore.QCoreApplication.translate("U", "Base64(建议小文件)(&B)"))
sha256Value = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(32), QtCore.QCoreApplication.translate("U", "SHA256(&S)"))
sha512Value = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(32), QtCore.QCoreApplication.translate("U", "SHA512(&S)"))
md5Value.triggered.connect(lambda: ValueCheck().Get("MD5"))
sha1Value.triggered.connect(lambda: ValueCheck().Get("SHA1"))
base64Value.triggered.connect(lambda: ValueCheck().Get("BASE64"))
sha256Value.triggered.connect(lambda: ValueCheck().Get("SHA256"))
sha512Value.triggered.connect(lambda: ValueCheck().Get("SHA512"))
checkValue.addAction(md5Value)
checkValue.addAction(sha1Value)
checkValue.addAction(base64Value)
checkValue.addAction(sha256Value)
checkValue.addAction(sha512Value)
safeWebsize = menu.addMenu(QtCore.QCoreApplication.translate("U", "云沙箱(&C)"))
s1 = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(9), QtCore.QCoreApplication.translate("U", "360 沙箱云"))
s2 = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(9), QtCore.QCoreApplication.translate("U", "微步云沙箱"))
s3 = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(9), QtCore.QCoreApplication.translate("U", "VIRUSTOTAL"))
s4 = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(9), QtCore.QCoreApplication.translate("U", "计算机病毒防御技术国家工程实验室"))
safeWebsize.addAction(s1)
safeWebsize.addAction(s2)
safeWebsize.addAction(s3)
safeWebsize.addAction(s4)
s1.triggered.connect(lambda: webbrowser.open_new_tab("https://ata.360.net/"))
s2.triggered.connect(lambda: webbrowser.open_new_tab("https://s.threatbook.cn/"))
s3.triggered.connect(lambda: webbrowser.open_new_tab("https://www.virustotal.com/"))
s4.triggered.connect(lambda: webbrowser.open_new_tab("https://cloud.vdnel.cn/"))
log = menu.addMenu(QtCore.QCoreApplication.translate("U", "日志(&L)"))
getDllInfo = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "查询 Dll"))
checkLogText = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "日志分析"))
saveLogText = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(16), QtCore.QCoreApplication.translate("U", "另存为日志"))
saveLogReport = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(16), QtCore.QCoreApplication.translate("U", "输出详细日志报告"))
transLogText = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "翻译日志(翻译后日志分析功能会故障)"))
uploadLogText = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "上传日志"))
getDllInfo.triggered.connect(DllWindow.ShowWindow)
checkLogText.triggered.connect(LogChecking.ShowWindow)
saveLogText.triggered.connect(SaveLog)
saveLogReport.triggered.connect(lambda: SaveLogReport(o1.currentText(), wine[o1.currentText()], lastRunCommand, e2.currentText(), returnText.toPlainText()).SetWindow())
transLogText.triggered.connect(TransLog)
uploadLogText.triggered.connect(UploadLog)
log.addAction(getDllInfo)
#log.addAction(checkLogText)
log.addAction(saveLogText)
log.addAction(saveLogReport)
#log.addAction(transLogText)
#log.addAction(uploadLogText)
actionList = []
def AddLib(install: QtWidgets.QAction, uninstall, menu, info):
actionList.append(install)
actionList.append(uninstall)
install.triggered.connect(lambda: OpenTerminal(f"bash '{programPath}/InstallRuntime/{info}'"))
uninstall.triggered.connect(lambda: OpenTerminal(f"bash '{programPath}/InstallRuntime/remove/{info}'"))
menu.addAction(install)
menu.addAction(uninstall)
installLib = menu.addMenu(QtCore.QCoreApplication.translate("U", "应用运行库(&R)"))
howtouseQemuUser = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "Qemu User 使用教程(配合运行库实现在非 X86 架构运行 X86 Wine)"))
howtouseQemuUser.triggered.connect(lambda: webbrowser.open_new_tab("https://www.bilibili.com/read/cv23185651"))
runnerlibinfo = QtWidgets.QAction("只在运行器使用的运行库(不与其他运行库以及兼容层冲突)")
installRunnerLib = QtWidgets.QAction("安装运行库")
statusRunnerLib = QtWidgets.QAction("当前状态:未安装")
removeRunnerLib = QtWidgets.QAction("移除运行库")
runnerlibinfo.setDisabled(True)
statusRunnerLib.setDisabled(True)
removeRunnerLib.setDisabled(True)
installLib.addAction(howtouseQemuUser)
installLib.addSeparator()
installLib.addAction(runnerlibinfo)
installLib.addAction(statusRunnerLib)
installLib.addAction(installRunnerLib)
installLib.addAction(removeRunnerLib)
diyRunnerLib = installLib.addMenu("定制运行库")
diyRunnerLib.setDisabled(True)
diyRunnerLibRemoveTips = QtWidgets.QAction("移除库")
diyRunnerLibRemoveTips.setDisabled(True)
diyRunnerLib.addAction(diyRunnerLibRemoveTips)
installRunnerLib.triggered.connect(lambda: threading.Thread(target=OpenTerminal, args=[f"bash '{programPath}/WineLib/install.sh'"]).start())
removeRunnerLib.triggered.connect(lambda: threading.Thread(target=OpenTerminal, args=[f"bash '{programPath}/WineLib/remove.sh'"]).start())
if os.path.exists(f"{programPath}/WineLib/usr"):
installRunnerLib.setDisabled(True)
removeRunnerLib.setEnabled(True)
diyRunnerLib.setEnabled(True)
w11WithWineLib.setEnabled(True)
statusRunnerLib.setText("当前状态:已安装")
libPathList = []
mapLink = []
def AddRunnerLib(number, name):
global diyRunnerLib
action = QtWidgets.QAction(f"{name}")
mapLink.append(action)
action.triggered.connect(lambda: DelRunnerLib(int(str(number))))
diyRunnerLib.addAction(action)
def DelRunnerLib(number):
os.system(f"rm -rf '{libPathList[number]}'")
QtWidgets.QMessageBox.information(window, "提示", "删除完成!")
mapLink[number].setDisabled(True)
for libPath in [f"{programPath}/WineLib/usr/lib", f"{programPath}/WineLib/usr/lib64"]:
for i in os.listdir(libPath):
if not os.path.isdir(f"{libPath}/{i}"):
try:
if not os.path.getsize(f"{libPath}/{i}"):
continue
except:
continue
libPathList.append(f"{libPath}/{i}")
AddRunnerLib(len(libPathList) - 1, f"{i}")
else:
if not os.path.exists(f"{libPath}/{i}/libc.so.6"):
continue
libPathList.append(f"{libPath}/{i}/")
AddRunnerLib(len(libPathList) - 1, f"{i}/")
print(libPathList)
if os.path.exists(f"{programPath}/InstallRuntime"):
installLib.addSeparator()
systemalllibinfo = QtWidgets.QAction("全局运行库(与其他运行库以及部分兼容层冲突)")
systemalllibinfo.setDisabled(True)
installLib.addAction(systemalllibinfo)
installQemuMenu = installLib.addMenu(QtCore.QCoreApplication.translate("U", "安装 Qemu User"))
installQemu = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "安装 Qemu User"))
removeQemu = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "卸载 Qemu User"))
installQemuMenu.addAction(installQemu)
installQemuMenu.addAction(removeQemu)
installQemu.triggered.connect(lambda: OpenTerminal(f"bash '{programPath}/InstallQemuUser.sh'"))
removeQemu.triggered.connect(lambda: OpenTerminal(f"bash '{programPath}/RemoveQemuUser.sh'"))
actionList = []
nameList = {}
for i in os.listdir(f"{programPath}/InstallRuntime"):
if i[-3:] == ".sh":
print(f"检测到库 {os.path.splitext(i)[0]}")
AddLib(QtWidgets.QAction(QtCore.QCoreApplication.translate("U", f"安装 {os.path.splitext(i)[0]} 运行库")), QtWidgets.QAction(QtCore.QCoreApplication.translate("U", f"卸载 {os.path.splitext(i)[0]} 运行库")), installLib.addMenu(QtCore.QCoreApplication.translate("U", f"运行库 {os.path.splitext(i)[0]}")), i)
qemuMenu = menu.addMenu(QtCore.QCoreApplication.translate("U", "容器(&C)"))
unpackDeb = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(32), QtCore.QCoreApplication.translate("U", "解包 deb 提取容器"))
qemuMenu.addAction(unpackDeb)
unpackDeb.triggered.connect(UnPackage)
if len(qemuBottleList) >= 1:
configMenu = QtWidgets.QAction(QtGui.QIcon(f"{programPath}/Icon/Function/CHROOT.png"), QtCore.QCoreApplication.translate("U", "配置指定 Chroot 容器"))
qemuMenu.addAction(configMenu)
configMenu.triggered.connect(ConfigQemu)
print(qemuBottleList)
videoHelp = menu.addMenu(QtCore.QCoreApplication.translate("U", "视频教程(&V)"))
videoHelpAction = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(20), QtCore.QCoreApplication.translate("U", "视频教程(Bilibili)"))
videoHelpActionYoutube = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(20), QtCore.QCoreApplication.translate("U", "视频教程(Youtube)"))
videoHelpAction.triggered.connect(lambda: webbrowser.open_new_tab("https://space.bilibili.com/695814694/channel/collectiondetail?sid=1610353"))
videoHelpActionYoutube.triggered.connect(lambda: webbrowser.open_new_tab("https://www.youtube.com/watch?v=qDaPBiIdGAs&list=PLoXD11L1NQAx8A1Qskgu3tUoi0nHKJcmg"))
videoHelp.addAction(videoHelpAction)
videoHelp.addAction(videoHelpActionYoutube)
help = menu.addMenu(QtCore.QCoreApplication.translate("U", "帮助(&H)"))
runStatusWebSize = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(20), QtCore.QCoreApplication.translate("U", "查询程序在 Wine 的运行情况"))
h1 = help.addMenu(QtWidgets.QApplication.style().standardIcon(20), QtCore.QCoreApplication.translate("U", "程序官网"))
h2 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "小提示"))
wineRunnerHelp = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(20), QtCore.QCoreApplication.translate("U", "Wine运行器和Wine打包器傻瓜式使用教程(小白专用) By 鹤舞白沙"))
h3 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "更新内容"))
h4 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "鸣谢名单"))
h5 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "更新这个程序"))
programInformation = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "获取程序公告(也可以在这里看程序安装/打开量)"))
h6 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "反馈这个程序的建议和问题"))
fenUpload = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "程序评分"))
h7 = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(9), QtCore.QCoreApplication.translate("U", "关于这个程序"))
h8 = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(9), QtCore.QCoreApplication.translate("U", "关于 Qt"))
gfdgdxiio = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(20), QtCore.QCoreApplication.translate("U", "作者个人站"))
gitee = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(20), QtCore.QCoreApplication.translate("U", "Gitee"))
github = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(20), QtCore.QCoreApplication.translate("U", "Github"))
gitlab = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(20), QtCore.QCoreApplication.translate("U", "Gitlab"))
jihu = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(20), QtCore.QCoreApplication.translate("U", "Sourceforge"))
h1.addAction(gfdgdxiio)
h1.addAction(gitee)
h1.addAction(github)
h1.addAction(gitlab)
h1.addAction(jihu)
help.addSeparator()
help.addAction(wineRunnerHelp)
help.addAction(runStatusWebSize)
help.addSeparator()
help.addAction(h2)
help.addAction(h3)
help.addAction(h4)
help.addSeparator()
wikiHelp = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(20), QtCore.QCoreApplication.translate("U", "程序 Wiki"))
help.addAction(wikiHelp)
videoHelp = help.addMenu(QtWidgets.QApplication.style().standardIcon(20), QtCore.QCoreApplication.translate("U", "视频教程"))
videoHelp.addAction(videoHelpAction)
help.addSeparator()
help.addAction(h5)
help.addAction(h6)
help.addAction(fenUpload)
help.addAction(programInformation)
help.addAction(h7)
help.addAction(h8)
help.addSeparator()
hm1 = help.addMenu(QtCore.QCoreApplication.translate("U", "更多生态适配应用"))
hm1_1 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "运行 Android 应用:UEngine 运行器"))
hm1.addAction(hm1_1)
gfdgdxiio.triggered.connect(lambda: webbrowser.open_new_tab("https://gfdgd-xi.github.io"))
gitee.triggered.connect(lambda: webbrowser.open_new_tab("https://gitee.com/gfdgd-xi/deep-wine-runner"))
github.triggered.connect(lambda: webbrowser.open_new_tab("https://github.com/gfdgd-xi/deep-wine-runner"))
gitlab.triggered.connect(lambda: webbrowser.open_new_tab("https://gitlab.com/gfdgd-xi/deep-wine-runner"))
jihu.triggered.connect(lambda: webbrowser.open_new_tab("https://sourceforge.net/projects/deep-wine-runner/"))
runStatusWebSize.triggered.connect(lambda: webbrowser.open_new_tab("https://gfdgd-xi.github.io/wine-runner-info"))
h2.triggered.connect(helps)
h3.triggered.connect(UpdateThings)
wineRunnerHelp.triggered.connect(lambda: webbrowser.open_new_tab("https://bbs.deepin.org/post/246837"))
h4.triggered.connect(ThankWindow)
wikiHelp.triggered.connect(lambda: webbrowser.open_new_tab("https://gfdgd-xi.github.io/wine-runner-wiki"))
h5.triggered.connect(UpdateWindow.ShowWindow)
h6.triggered.connect(WineRunnerBugUpload)
fenUpload.triggered.connect(lambda: threading.Thread(target=os.system, args=[f"python3 '{programPath}/ProgramFen.py'"]).start())
h7.triggered.connect(about_this_program)
h8.triggered.connect(lambda: QtWidgets.QMessageBox.aboutQt(widget))
hm1_1.triggered.connect(lambda: webbrowser.open_new_tab("https://gitee.com/gfdgd-xi/uengine-runner"))
programInformation.triggered.connect(GetNewInformation)
# 异同步获取信息
#threading.Thread(target=GetVersion).start()
GetVersion()
# 窗口设置
window.resize(widget.frameGeometry().width() * 2, widget.frameGeometry().height())
widget.setLayout(mainLayout)
window.setWindowIcon(QtGui.QIcon(f"{programPath}/deepin-wine-runner.svg"))
widget.show()
window.show()
# 控件设置
app.setStyle(QtWidgets.QStyleFactory.create(setting["Theme"]))
e1.addItems(findExeHistory)
e2.addItems(wineBottonHistory)
combobox1.addItems(shellHistory)
if setting["AutoWine"]:
o1.addItems(canUseWine)
else:
o1.addItems(wine.keys())
# 禁用被精简掉的控件
for i in [
[[p1, installWineHQ, installWineHQOrg, installMoreWine], f"{programPath}/InstallWineOnDeepin23.py"],
[[w5], f"{programPath}/deepin-wine-packager.py"],
[[w6], f"{programPath}/deepin-wine-packager-with-script.py"],
[[p1, v1], f"{programPath}/RunVM.sh"],
[[getProgramIcon, uninstallProgram, updateGeek, trasButton, miniAppStore, fontAppStore, wm1_1, wm1_2, wm1_3, wm1_6, w7, w2], f"{programPath}/geek.exe"],
]:
if not os.path.exists(i[1]):
for x in i[0]:
x.setDisabled(True)
# 有些功能是非 X86 不适用的,需要屏蔽
if subprocess.getoutput("arch").lower() != "x86_64":
p1.setDisabled(True)
installMoreWine.setEnabled(True)
#virtualMachine.setDisabled(True)
#v1.setDisabled(True)
installWineHQ.setDisabled(True)
installWineHQOrg.setDisabled(True)
pass
o1.setCurrentText(setting["DefultWine"])
e1.setEditText(setting["DefultBotton"])
e2.setEditText("")
combobox1.setEditText("")
if len(sys.argv) > 1 and sys.argv[1]:
e2.setEditText(sys.argv[1])
if not os.path.exists("/opt/durapps/spark-dwine-helper/spark-dwine-helper-settings/settings.sh"):
sparkWineSetting.setEnabled(False)
if o1.currentText() == "":
# 一个 Wine 都没有却用 Wine 的功能
# 还是要处理的,至少不会闪退
wine["没有识别到任何Wine,请在菜单栏“程序”安装Wine或安装任意Wine应用"] = "没有识别到任何Wine,请在菜单栏“程序”安装Wine或安装任意Wine应用"
canUseWine.append("没有识别到任何Wine,请在菜单栏“程序”安装Wine或安装任意Wine应用")
o1.addItem("没有识别到任何Wine,请在菜单栏“程序”安装Wine或安装任意Wine应用")
SetFont(setting["FontSize"])
# Mini 模式
# MiniMode(True)
sys.exit(app.exec_())
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Python
1
https://gitee.com/ChaoYouAi/deep-wine-runner.git
git@gitee.com:ChaoYouAi/deep-wine-runner.git
ChaoYouAi
deep-wine-runner
Wine 运行器
main

搜索帮助

23e8dbc6 1850385 7e0993f3 1850385