1kh
diff --git a/deb/opt/apps/deepin-wine-runner/deepin-wine-packager.py b/deb/opt/apps/deepin-wine-runner/deepin-wine-packager.py
index 404ee51..0bb68d1 100755
--- a/deb/opt/apps/deepin-wine-runner/deepin-wine-packager.py
+++ b/deb/opt/apps/deepin-wine-runner/deepin-wine-packager.py
@@ -102,6 +102,17 @@ def make_deb(build=False):
if QtWidgets.QMessageBox.question(widget, QtCore.QCoreApplication.translate("U", "提示"), QtCore.QCoreApplication.translate("U", "打包将会改动现在选择的容器,是否继续?")) == QtWidgets.QMessageBox.No:
disabled_or_NORMAL_all(True)
return
+ # 警告信息
+ if os.path.exists(e7_text.text()):
+ if QtWidgets.QMessageBox.warning(window, "警告", "输入的路径似乎是一个绝对路径\n不建议打包绝对路径,建议是 Wine 容器内路径\n是否继续打包?", QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No) == QtWidgets.QMessageBox.No:
+ disabled_or_NORMAL_all(True)
+ return
+ if e7_text.text()[:2].lower() == "c:" and not os.path.exists("{}/drive_c/{}".format(
+ e6_text.text(),
+ e7_text.text()[3:].replace("\\", '/'))):
+ if QtWidgets.QMessageBox.warning(window, "警告", "输入的路径似乎在 Wine 容器不存在(如果只是大小写错误导致的误判,请忽略)\n是否继续打包?", QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No) == QtWidgets.QMessageBox.No:
+ disabled_or_NORMAL_all(True)
+ return
#thread = threading.Thread(target=make_deb_threading)
QT.thread = make_deb_threading(build)
QT.thread.signal.connect(chang_textbox1_things)
diff --git a/deb/opt/apps/deepin-wine-runner/deepin-wine-runner b/deb/opt/apps/deepin-wine-runner/deepin-wine-runner
index dbf272b..713ede7 100755
--- a/deb/opt/apps/deepin-wine-runner/deepin-wine-runner
+++ b/deb/opt/apps/deepin-wine-runner/deepin-wine-runner
@@ -161,9 +161,11 @@ class Runexebutton_threading(QtCore.QThread):
option += f"WINEDLLOVERRIDES=\"mscoree,mshtml=\" "
if not setting["Debug"]:
option += "WINEDEBUG=-all "
+ else:
+ option += "WINEDEBUG=FIXME,ERR,WARN,TRACE,Message "
wineUsingOption = ""
if o1.currentText() == "基于 exagear 的 deepin-wine6-stable" or o1.currentText() == "基于 box86 的 deepin-wine6-stable":
- wineUsingOption = "--disable-gpu"
+ wineUsingOption = ""
if o1.currentText() == "基于 exagear 的 deepin-wine6-stable":
os.system(f"'{programPath}/deepin-wine-runner-create-botton.py' '{wineBottonPath}'")
if o1.currentText() == "基于 box86 的 deepin-wine6-stable":
@@ -174,10 +176,16 @@ class Runexebutton_threading(QtCore.QThread):
os.remove(f"{programPath}/dlls-arm.7z")
if setting["TerminalOpen"]:
res = ""
- OpenTerminal("env WINEPREFIX='" + wineBottonPath + "' " + option + wine[o1.currentText()] + " '" + e2.currentText() + "' " + setting["WineOption"])
+ if e2.currentText()[-4:] == ".msi" and os.path.exists(e2.currentText()):
+ OpenTerminal("env WINEPREFIX='" + wineBottonPath + "' " + option + wine[o1.currentText()] + " msiexec /i '" + e2.currentText() + "' " + setting["WineOption"])
+ else:
+ OpenTerminal("env WINEPREFIX='" + wineBottonPath + "' " + option + wine[o1.currentText()] + " '" + e2.currentText() + "' " + setting["WineOption"])
#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:
- res = subprocess.Popen(["WINEPREFIX='" + wineBottonPath + "' " + option + wine[o1.currentText()] + " '" + e2.currentText() + "' " + setting["WineOption"]], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ if e2.currentText()[-4:] == ".msi" and os.path.exists(e2.currentText()):
+ res = subprocess.Popen(["WINEPREFIX='" + wineBottonPath + "' " + option + wine[o1.currentText()] + " msiexec /i '" + e2.currentText() + "' " + setting["WineOption"]], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ else:
+ res = subprocess.Popen(["WINEPREFIX='" + wineBottonPath + "' " + option + wine[o1.currentText()] + " '" + e2.currentText() + "' " + setting["WineOption"]], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
# 实时读取程序返回
#
if not setting["TerminalOpen"]:
@@ -195,6 +203,28 @@ class Runexebutton_threading(QtCore.QThread):
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)
@@ -255,6 +285,8 @@ def make_desktop_on_launcher():
option += f"WINEARCH={setting['Architecture']} "
if not setting["Debug"]:
option += "WINEDEBUG=-all "
+ else:
+ option += "WINEDEBUG=FIXME,ERR,WARN,TRACE,Message "
wineUsingOption = ""
if o1.currentText() == "基于 box86 的 deepin-wine6-stable":
if not os.path.exists(f"{programPath}/dlls-arm"):
@@ -263,11 +295,24 @@ def make_desktop_on_launcher():
return
os.remove(f"{programPath}/dlls-arm.7z")
if o1.currentText() == "基于 exagear 的 deepin-wine6-stable" or o1.currentText() == "基于 box86 的 deepin-wine6-stable":
- wineUsingOption = "--disable-gpu"
- write_txt(get_home() + "/.local/share/applications/" + combobox1.currentText() + ".desktop", f'''[Desktop Entry]
+ 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={iconPath}
+Icon={iconPaths}
Type=Application
StartupNotify=true''') # 写入文本文档
if len(shellHistory) == 0 or shellHistory[-1] != combobox1.currentText():
@@ -304,7 +349,7 @@ def make_desktop_on_desktop():
wineBottonPath = e1.currentText()
wineUsingOption = ""
if o1.currentText() == "基于 exagear 的 deepin-wine6-stable" or o1.currentText() == "基于 box86 的 deepin-wine6-stable":
- wineUsingOption = "--disable-gpu"
+ wineUsingOption = ""
if o1.currentText() == "基于 box86 的 deepin-wine6-stable":
if not os.path.exists(f"{programPath}/dlls-arm"):
if os.system(f"7z x \"{programPath}/dlls-arm.7z\" -o\"{programPath}\""):
@@ -319,10 +364,23 @@ def make_desktop_on_desktop():
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={iconPath}
+Icon={iconPaths}
Type=Application
StartupNotify=true''') # 写入文本文档
if len(shellHistory) == 0 or shellHistory[-1] != combobox1.currentText():
@@ -418,7 +476,7 @@ class RunWineProgramThread(QtCore.QThread):
if o1.currentText() == "基于 exagear 的 deepin-wine6-stable":
os.system(f"'{programPath}/deepin-wine-runner-create-botton.py' '{wineBottonPath}'")
if o1.currentText() == "基于 exagear 的 deepin-wine6-stable" or o1.currentText() == "基于 box86 的 deepin-wine6-stable":
- wineUsingOption = "--disable-gpu"
+ wineUsingOption = ""
if o1.currentText() == "基于 box86 的 deepin-wine6-stable":
if not os.path.exists(f"{programPath}/dlls-arm"):
if os.system(f"7z x \"{programPath}/dlls-arm.7z\" -o\"{programPath}\""):
@@ -482,7 +540,7 @@ class RunWinetricksThread(QtCore.QThread):
option += "WINEDEBUG=-all "
wineUsingOption = ""
if o1.currentText() == "基于 exagear 的 deepin-wine6-stable" or o1.currentText() == "基于 box86 的 deepin-wine6-stable":
- wineUsingOption = "--disable-gpu"
+ wineUsingOption = ""
if o1.currentText() == "基于 box86 的 deepin-wine6-stable":
if not os.path.exists(f"{programPath}/dlls-arm"):
if os.system(f"7z x \"{programPath}/dlls-arm.7z\" -o\"{programPath}\""):
@@ -504,6 +562,8 @@ class RunWinetricksThread(QtCore.QThread):
text = ""
self.signal.emit(text)
print(text, end="")
+
+
DisableButton(False)
runWinetricks = None
@@ -808,6 +868,7 @@ class GetDllFromWindowsISO:
mount = False
mountButton = None
dllListModel = None
+ arch = 0
def ShowWindow():
#DisableButton(True)
GetDllFromWindowsISO.message = QtWidgets.QMainWindow()
@@ -816,8 +877,8 @@ class GetDllFromWindowsISO:
if not e1.currentText() == "":
GetDllFromWindowsISO.wineBottonPath = e1.currentText()
widgetLayout.addWidget(QtWidgets.QLabel(f"""提示:
- 目前本提取功能只支持 Windows XP 以及 Windows Server 2003 等老系统的官方安装镜像,只支持读取 i386 安装方法的安装镜像,不支持读取 wim、ghost 安装方式
- 以及不要拷贝/替换太多的 dll,否则可能会导致 wine 容器异常
+ 目前本提取功能暂只支持 NT 内核系统的官方安装镜像,不支持读取 ghost 等第三方封装方式的安装镜像
+ 以及不要拷贝/替换太多的 dll,否则可能会导致 wine 容器异常,以及不要替换 Wine 的核心 dll
最后,拷贝/替换 dll 后,建议点击下面“设置 wine 容器”按钮==》函数库 进行设置
当前选择的 Wine 容器:{GetDllFromWindowsISO.wineBottonPath}"""), 0, 0, 1, 5)
isoLabel = QtWidgets.QLabel(QtCore.QCoreApplication.translate("U", "ISO镜像:"))
@@ -903,16 +964,38 @@ class GetDllFromWindowsISO:
findList = []
try:
if found == "":
- for i in os.listdir("/tmp/wine-runner-getdll/i386"):
- if i[-3:] == "dl_":
- findList.append(i[:-1] + "l")
+ # 显示所有内容
+ # 下面内容需要分类讨论
+ 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
- for i in os.listdir("/tmp/wine-runner-getdll/i386"):
- if found in i[:-1] + "l":
- findList.append(i[:-1] + "l")
- if len(isoPath) == 0 or isoPathFound[-1] != found:
- isoPathFound.append(found) # 将记录写进数组
- write_txt(get_home() + "/.config/deepin-wine-runner/ISOPathFound.json", str(json.dumps(ListToDictionary(isoPathFound)))) # 将历史记录的数组转换为字典并写入
+ 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)
@@ -928,11 +1011,15 @@ class GetDllFromWindowsISO:
if os.path.exists("/tmp/wine-runner-getdll"):
try:
os.rmdir("/tmp/wine-runner-getdll")
+ os.rmdir("/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())
@@ -940,15 +1027,60 @@ class GetDllFromWindowsISO:
os.makedirs("/tmp/wine-runner-getdll")
os.system(f"pkexec mount '{GetDllFromWindowsISO.isoPath.currentText()}' /tmp/wine-runner-getdll")
findList = []
- try:
- for i in os.listdir("/tmp/wine-runner-getdll/i386"):
- if i[-3:] == "dl_":
- findList.append(i[:-1] + "l")
- except:
- traceback.print_exc()
- QtWidgets.QMessageBox.critical(GetDllFromWindowsISO.message, "错误", f"镜像内容读取/挂载失败,报错如下:\n{traceback.format_exc()}")
- return
- GetDllFromWindowsISO.dllListModel.setStringList(findList)
+ # 判断是新版的 Windows ISO(Windows Vista 及以上版本)
+ if os.path.exists("/tmp/wine-runner-getdll/sources/install.wim"):
+ # 是新版,挂载 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
@@ -960,9 +1092,11 @@ class GetDllFromWindowsISO:
#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()}")
@@ -975,11 +1109,23 @@ class GetDllFromWindowsISO:
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(widget, "提示", f"DLL {choose} 已经存在,是否覆盖?") == QtWidgets.QMessageBox.No:
+ if QtWidgets.QMessageBox.question(GetDllFromWindowsISO.message, "提示", f"DLL {choose} 已经存在,是否覆盖?") == QtWidgets.QMessageBox.No:
return
try:
- shutil.copy(f"/tmp/wine-runner-getdll/i386/{choose[:-1]}_", f"{GetDllFromWindowsISO.wineBottonPath}/drive_c/windows/system32/{choose}")
- 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")
+ # 要分类讨论
+ 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()
@@ -1111,13 +1257,14 @@ class ProgramRunStatusUpload():
try:
if ProgramRunStatusUpload.sha1Value == "":
ProgramRunStatusUpload.sha1Value = ProgramRunStatusUpload.GetSHA1(e2.currentText())
- QtWidgets.QMessageBox.information(None, QtCore.QCoreApplication.translate("U", "提示"), json.loads(requests.post(base64.b64decode("aHR0cDovL2dmZGdkeGkucWljcC52aXA6Mjc1MDI=").decode("utf-8"), {
+ 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):
@@ -1145,6 +1292,7 @@ class ProgramSetting():
monogeckoInstaller = None
autoWine = None
runtimeCache = None
+ buildByBottleName = None
def ShowWindow():
ProgramSetting.message = QtWidgets.QMainWindow()
widget = QtWidgets.QWidget()
@@ -1159,6 +1307,7 @@ class ProgramSetting():
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)
ProgramSetting.wineBottonA = QtWidgets.QComboBox()
ProgramSetting.wineDebug = QtWidgets.QCheckBox(QtCore.QCoreApplication.translate("U", "开启 DEBUG 输出"))
ProgramSetting.defultWine = QtWidgets.QComboBox()
@@ -1177,6 +1326,7 @@ class ProgramSetting():
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.wineBottonA.addItems(["Auto", "win32", "win64"])
ProgramSetting.wineBottonA.setCurrentText(setting["Architecture"])
ProgramSetting.wineDebug.setChecked(setting["Debug"])
@@ -1188,6 +1338,7 @@ class ProgramSetting():
ProgramSetting.monogeckoInstaller.setChecked(setting["MonoGeckoInstaller"])
ProgramSetting.autoWine.setChecked(setting["AutoWine"])
ProgramSetting.runtimeCache.setChecked(setting["RuntimeCache"])
+ ProgramSetting.buildByBottleName.setChecked(setting["BuildByBottleName"])
widgetLayout.addWidget(ProgramSetting.wineBottonA, 0, 1, 1, 1)
widgetLayout.addWidget(ProgramSetting.wineDebug, 1, 1, 1, 1)
widgetLayout.addWidget(ProgramSetting.defultWine, 2, 1, 1, 1)
@@ -1200,7 +1351,8 @@ class ProgramSetting():
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(save, 10, 2, 1, 1)
+ widgetLayout.addWidget(ProgramSetting.buildByBottleName, 10, 1, 1, 1)
+ widgetLayout.addWidget(save, 11, 2, 1, 1)
widget.setLayout(widgetLayout)
ProgramSetting.message.setCentralWidget(widget)
ProgramSetting.message.setWindowIcon(QtGui.QIcon(iconPath))
@@ -1228,6 +1380,7 @@ class ProgramSetting():
setting["MonoGeckoInstaller"] = ProgramSetting.monogeckoInstaller.isChecked()
setting["AutoWine"] = ProgramSetting.autoWine.isChecked()
setting["RuntimeCache"] = ProgramSetting.runtimeCache.isChecked()
+ setting["BuildByBottleName"] = ProgramSetting.buildByBottleName.isChecked()
try:
write_txt(get_home() + "/.config/deepin-wine-runner/WineSetting.json", json.dumps(setting))
except:
@@ -1236,7 +1389,103 @@ class ProgramSetting():
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:
+ QtWidgets.QInputDialog.getMultiLineText(window, "值", "计算得到的值", self.link[types](self, file))
+ except:
+ traceback.print_exc()
+ QtWidgets.QMessageBox.critical(window, "错误", traceback.format_exc())
###########################
# 加载配置
@@ -1254,7 +1503,8 @@ defultProgramList = {
"MonoGeckoInstaller": True,
"AutoWine": True,
"RuntimeCache": True,
- "MustRead": False
+ "MustRead": False,
+ "BuildByBottleName": False
}
if not os.path.exists(get_home() + "/.config/deepin-wine-runner"): # 如果没有配置文件夹
os.mkdir(get_home() + "/.config/deepin-wine-runner") # 创建配置文件夹
@@ -1285,7 +1535,7 @@ programPath = os.path.split(os.path.realpath(__file__))[0] # 返回 string
try:
wine = {
"基于 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 ",
- "基于 exagear 的 deepin-wine6-stable": f"/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 ",
+ "基于 exagear 的 deepin-wine6-stable": f"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 ",
"deepin-wine6 stable": "deepin-wine6-stable",
"deepin-wine5 stable": "deepin-wine5-stable",
"spark-wine7-devel": "spark-wine7-devel",
@@ -1388,30 +1638,23 @@ exe路径\' 参数 \'
千万不要中断后不删除源的情况下 apt upgrade !!!中断后只需重新打开脚本输入 repair 或者随意安装一个 Wine(会自动执行恢复操作)即可
以及此脚本安装的 Wine 无法保证 100% 能使用,以及副作用是会提示
N: 鉴于仓库 'https://community-packages.deepin.com/beige beige InRelease' 不支持 'i386' 体系结构,跳过配置文件 'main/binary-i386/Packages' 的获取。
'''
-updateThingsString = '''2.1.0-2 更新内容:
-※1、修复终端调用问题
-2.1.0-1 更新内容:
-※1、删除多余图标
-※2、修复将打包文件生成目录设置为 / 等重要目录导致删库的问题
-3、修复了打包器浏览按钮闪退、生成的 postrm 有误的问题
-4、支持在输入信息时自动生成 deb 保存路径
-2.1.0 更新内容:
-※1、新增新的 Wine 安装器,并支持将安装的 Wine 打包到 Wine 程序 deb 包中
-※2、Wine 打包器打包 Windows 应用支持将 Wine 打包入 deb 内,可以不依赖 Wine(一般不推荐把 Wine 打包入内,推荐用依赖的形式),并支持设置自定义依赖和生成模板
-※3、开始初步多语言支持
-※4、修复了在没有安装任何 Wine 的情况下使用高级功能导致程序闪退的问题
-※5、支持云端自动获取数据配置 Wine 容器
-※6、支持手动导入配置文件自动配置 Wine 容器
-※7、新增从云端下载 Dll 的功能
-※8、修复了 Dll 提取工具不会在 winecfg 中添加原装的问题
-9、修改错别字(图形话=>图形化)
-10、修复评分功能名称为空也可以上传评分的问题
-11、去除 toilet 依赖,使在 Deepin 23 Preview 上运行更佳
-12、支持删除所有由 Wine 创建的启动器快捷方式
+updateThingsString = '''※1、Dll 提取工具支持 NT 6.X 及以上版本的 Dll 提取并优化了提示文本
+※2、支持卸载后自动删除缓存/配置文件(删除配置文件只限 purge 参数删除)
+※3、DEBUG 模式输出更多信息以方便调试(原本只输出 pid、Err)
+※4、支持安装 msi 文件
+※5、修复无法正常评分的问题
+※6、修复 QQ、TIM 安装后无法正常生成快捷方式的问题
+※7、基于生态适配活动的打包器更换为 spark-wine-helper 以及添加自动删除残留脚本
+8、更新组件安装的离线列表
+9、不再强制依赖深度终端,只做推荐安装
+以下更新内容旧版本也适用(只限 2.1.0 及以上版本)
+※1、在“安装更多Wine”的Wine安装工具中上 wine-staging 7.17、wine-staging 6.7、spark-wine7-devel 7.17
+※2、云 Dll 工具上新 Dll
+※3、VCPP 运行库安装工具新增 VC6 运行库
'''
for i in information["Thank"]:
thankText += f"{i}\n"
-updateTime = "2022年09月03日"
+updateTime = "2022年09月11日"
about = f'''关于
一个能让Linux用户更加方便运行Windows应用的程序,内置了对wine图形化的支持和各种Wine工具和自制Wine程序打包器、运行库安装工具等等
同时也内置了基于VirtualBox制作的小白Windows虚拟机安装工具,可以做到只需要用户下载系统镜像并点击安装即可,无需顾及虚拟机安装、创建、虚拟机的分区等等
@@ -1445,8 +1688,21 @@ try:
threading.Thread(target=requests.get, args=[parse.unquote(base64.b64decode("aHR0cHM6Ly8zMDQ2MjZwOTI3LmdvaG8uY28vc3BhcmstZGVlcGluLXdpbmUtcnVubmVyL29wZW4vSW5zdGFsbC5waHA=").decode("utf-8")) + "?Version=" + version]).start()
except:
pass
-
-
+iconListUnBuild = [
+ ["QQ", "wineBottonPath/drive_c/Program Files/Tencent/QQ/Bin/QQ.exe"],
+ ["QQ", "wineBottonPath/drive_c/Program Files (x86)/Tencent/QQ/Bin/QQ.exe"],
+ ["TIM", "wineBottonPath/drive_c/Program Files/Tencent/TIM/Bin/TIM.exe"],
+ ["TIM", "wineBottonPath/drive_c/Program Files (x86)/Tencent/TIM/Bin/TIM.exe"]
+]
+iconList = [
+ ["微信", "wineBottonPath/drive_c/Program Files/Tencent/WeChat/WeChat.exe"],
+ ["微信", "wineBottonPath/drive_c/Program Files (x86)/Tencent/WeChat/WeChat.exe"],
+ ["UltraISO", "wineBottonPath/drive_c/Program Files/UltraISO/UltraISO.exe"],
+ ["UltraISO", "wineBottonPath/drive_c/Program Files (x86)/UltraISO/UltraISO.exe"]
+]
+for i in iconListUnBuild:
+ iconList.append(i)
+print(iconList)
###########################
# 窗口创建
@@ -1526,7 +1782,7 @@ 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' 'z:/{e2.currentText()}"))
+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", "窗口透明工具"))
@@ -1643,7 +1899,7 @@ cleanBottonUOS = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "清
w5 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "打包 wine 应用"))
w6 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "使用官方 Wine 适配活动的脚本进行打包"))
getDllOnInternet = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "从互联网获取DLL"))
-w7 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "从镜像获取DLL(只支持Windows XP、Windows Server 2003官方安装镜像)"))
+w7 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "从镜像获取DLL(只支持官方安装镜像,DOS内核如 Windows 95 暂不支持)"))
updateGeek = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "从 Geek Uninstaller 官网升级程序"))
deleteDesktopIcon = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "删除所有 Wine 程序在启动器的快捷方式"))
wineOption.addAction(w1)
@@ -1753,6 +2009,24 @@ v1 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "使用 Virtualbox
virtualMachine.addAction(v1)
v1.triggered.connect(RunVM)
+checkValue = menu.addMenu(QtCore.QCoreApplication.translate("U", "校验值计算(&S)"))
+md5Value = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "MD5(&M)"))
+sha1Value = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "SHA1(&M)"))
+base64Value = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "Base64(建议小文件)(&B)"))
+sha256Value = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "SHA256(&S)"))
+sha512Value = QtWidgets.QAction(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(QtCore.QCoreApplication.translate("U", "360 沙箱云"))
s2 = QtWidgets.QAction(QtCore.QCoreApplication.translate("U", "微步云沙箱"))
@@ -1876,4 +2150,6 @@ if o1.currentText() == "":
wine["没有识别到任何Wine,请在菜单栏“程序”安装Wine或安装任意Wine应用"] = "没有识别到任何Wine,请在菜单栏“程序”安装Wine或安装任意Wine应用"
canUseWine.append("没有识别到任何Wine,请在菜单栏“程序”安装Wine或安装任意Wine应用")
o1.addItem("没有识别到任何Wine,请在菜单栏“程序”安装Wine或安装任意Wine应用")
+
+
sys.exit(app.exec_())
diff --git a/deb/opt/apps/deepin-wine-runner/information.json b/deb/opt/apps/deepin-wine-runner/information.json
index 01232be..2b8d7b0 100755
--- a/deb/opt/apps/deepin-wine-runner/information.json
+++ b/deb/opt/apps/deepin-wine-runner/information.json
@@ -1,5 +1,5 @@
{
- "Version": "2.1.0-2",
+ "Version": "2.2.0-Alpha2",
"Thank": [
"感谢 @a2035274 @虚幻的早晨 https://bbs.deepin.org/post/238301",
"感谢 @zhangs https://bbs.deepin.org/post/227948",
@@ -7,7 +7,7 @@
"感谢 @统信UCARE服务 https://mp.weixin.qq.com/s/iOdfNv6phc8F4inackFFTw",
"感谢 @星火应用商店 提供部分安装包的源以及本程序的下载地址",
"感谢 @delsin 和 @神末shenmo 在 deepin 论坛提供打包器打包的 deb 包自动删除容器的建议",
- "感谢 @shenmo 反馈的 2.1.0 打包器问题和 2.1.0-1 终端调用问题",
+ "感谢 @shenmo 反馈的 2.1.0 打包器问题和 2.1.0-1 终端调用问题",
"感谢 @GershonWang 在 https://github.com/gfdgd-xi/deep-wine-runner/issues/1 提供窗口居中的建议",
"感谢 @134******28 和 @sgb76 提供的新程序 GUI 布局和实现代码",
"感谢 @sgb76 为 Wine 打包器(非生态适配脚本)打包的 i386 deb 提供建议",
@@ -22,6 +22,7 @@
"感谢 @五行缺钱 反馈的 2.0.0 在 Deepin 23 缺失依赖 toilet 的问题",
"感谢 @云的眼泪 @zhengjl 反馈的 2.0.0 发布忘记把安装包传蓝奏云的问题",
"感谢 @虚幻的早晨 提出的添加 DXVK、VKD3D 的功能(VKD3D 暂未实现)",
+ "感谢 @以勒 修改 Dll 提取工具提示文本的建议",
"感谢统信在 Wine 生态适配活动中提供的打包脚本",
"也感谢 DXVK 的开发者开发了 DXVK 这个程序,项目链接:https://github.com/doitsujin/dxvk",
"也感谢 WineHQ 开发团队开发的 WineHQ,项目网址:https://dl.winehq.org/",
diff --git a/deb/opt/apps/deepin-wine-runner/package-script.zip b/deb/opt/apps/deepin-wine-runner/package-script.zip
index 24e6c5fc326e3c8cf3b160bb9d1480ccfa87b66f..f3321454f9761c9f25d12c6c03fa7141cd082eca 100755
GIT binary patch
delta 8630
zcmZvC1yEeU(W55i9r#4>_!|&@
zyt))vyO**iZUPO=nZuT7jn0nBJW6TJ`b7T>;NqTOba+NM1Us<{o$;@2;sN@_zj+g*
z``=uKssDGb17l$#{u4lPzWozS<(wJ}sLI?jA&Jp2b=!$
z(rB&?oCgdl1Sacl1=iXSj8S1N5(9}-OW
zytcP#63cxgZ!Zo5T~}|*zwBhil)v)9EDJ!HE}3ROgzK;^_Yb(eA1$#d7;Q9WF(Y!cs;>^E;*N=^2|vF%RZdfJVq
z1vZOcBDRROwCo)aXHg5QZkU;kE%~C78da88bkVq?09Mi+LGM24b+Oq-jesDm_rb2Up_$}l{J@rKl$jWV`*G}hK@83U#v
zURgv%mhN9onF(D`+bWYMe_r_OHAb-rT`JhuoGco*M&a!CIg8w6@y0Kj55YvfxP3-b
zQ@6vM0*Ek&UmJDLZ0E4cR{7YW@D|}Q>3e_iZ5m%;J6}+&E2A+%d_5gY$*0zZQllps
zprV)1(;(CljLOf8-v_SaT~#Y}Yts!{Ks5B%FPQSp6g8j?I=LKLl|@%ZWsE1h&7&L}
z@L{c$r0@6^KJko%G_S6`geKie?#=bJ;MSlqMLRWu3KQyY8|eL(RoO*t0|GhSOz1LHze|5pEx=+0se7i&e22
z>grP)B6VMDJsU#%UCn9zj6#!?+u<9xJxTg!Z;Dx3qH9wP{6RVawNu$=n6iHgii}J3
zQ%gFu&`HJQ%9~1Uon|IX(CZ?3TgrXn{{VRg=^uW-*;{&0I1XK(aE39H8}lP7%AOA(Kc9ON6rPv
zXToaby>`(9k?YYi*HAM%KQQ(y8;S+$hkGv4D$wb{Nbx;fnzWs;w8cSar_h2g1uVtd
zS6kR~Y=9IA?{VvxMk{
z9xIU|!(D#?BbY$km7FvrMjG|VA*lSWb$8Gm^jxf_rpYO>z_P3d5jJCuJD$!sc?jbC
zgQH$>fwCl>GbVfu+$Y_VeThtn;`e^#al1I<;SNb0{9$-~N|E&-$_%|)!Z+z4xj<98VmuSnhcb`$IX
zf#k6zX6Gd&$}(QRyfDH$WBzWBqfIaMt;v=MNq8M-);$)+DRD^HLW1vgybqcMzO84zb=d@V!MO^Fe|`j~=Ww~M6buhL4R2`ivf)%sM6t|M70uPV
zs${&V{+uJoi2I1kE{yX5(|^%j`biv7tt*;<3-pGdPtciyO%{(CQ+=^DF3#Pj-e+2PV^X*t{<8bfsaBs2qk?R(!WW*}Akf^|ShbFS1&VV>3
z9uqBl5VWeln#zU@4kfXhS4wahdbW$4pVQ!8;XAM+YS;dDb7~^(Atlw
z!dw#N$N5V6sr_xxpQR!DIL%h3cVt-P>m+uvHAb*Zy-Vjhy#^w@7wlT%0MYI@Wk84D&kT&@&g$cU9QEk$rdw<((O-bA@RdR7w=hQ3*$z
zj7_t0@A+z8P(RS=4yvPfM#DN>kvrNgHT*A{UkeMQWgrtSn|5tchhU*Vcdd3GA1h%G
z)WOC(6OS{2h`VoZfA$x>P5<^lh7jpFx7nwr1oRX8`k#}9vUZsV>PB}lkt#X4o1@Vj
zs??^n;-bOW2(6jliD3)2zbKddfba_o(Jx=*DoqSij0;uRu?+pV|GPu!%lI`v$v=O{
zawoVyY;Y5uYOX^cl0PlhZex4X;eU=V%6&JU`&ga#6Hx*>1I4G;pCB_v17;t)ama_%{Fw-(N*oy)k)=V
zhtMNHKD?ru`^8^jXaW-7^duLlV6EFTd@~C%kpJq_!548d<1)IPP|n={2FK71bdxzR
z8{tpIGTxcww6UsL``*!FLsgHq+s#><43c7mpi#7C!bsu_^Wzp?Xs9u&gl$W_-D^d#EaH-HXPohP3X;5B^WrkU(wjm
zy_hw{5-t;QfvRO&Ub4W*#Z^A=)u;m{NzgazoKU<4*&X-VXp
z$OS?5(%AYoawH2{XOXDWSex<2M^@tMicios1aA$mTD&{ezWxB`eDc+};M<^l5og
zbQ7!Sh3PqGc=+o~dJcHum>nsah?dnen8vbQ(0jYZR$
zbIgAk8Zc86-r!n~p$WjK!FN*|w>ji`#i1(kf`jid?M5?l^5!^vk}(I84?705AN$+w
z?<3pn?+scfnsIBD`Lsz^`)ZMo5pV+@LGbl!5E&fJ5}b>Lmcynua&RK=g^Pf225+zg
zbD;bjp|pM?_`W5W3OK-&DzI8ej+IzU(77FpxxY(p`Fv)NYnUJeL%_yRsWoeZ3%I{-
z^!Xk;P28fv<^0_={q=JDT#JEd4AJy*Wz4~0SEd_*%7teBoFwDFD{UYP)gTQ2Po*tK(p_#<*{cn6+
zS?1z_4gTw!TT^8I8(3#&!>HO4%l5c6;e-)t8Q>FZclZq-%v`4$_1%VLQ#6oEf2C4H_L3)KhMrdRRAp8DdfLVEP_qAJv-l*uQ(3H
z;4Wa{8mVWr`qXC^D?3{2ZXE5W3|plX-$5s{zJ*@MlNo2LR~e_>Rc4C?z9I~7%Vmk3
z0cYx;GXi|0_57ZrOA^dz*9l1C?NmD78AX=!1T1M}mKn%0N@wlLDBKmE2{sP?cy4&@
zVRJoFX9WbLUC7*p%$(Z~$@Rf=%d-$(hrSs2HGpL;c%o_Fg*x-x8J#s<_5Cv^I}x|v
z3XKl8!UWIx(C|J^!GhhAHl-29lVm>^Wm;_=2A=6aIa%oxrs4$bd!)3~i4-mNSR6zA
zct8zQD3*0t?;U?sH*4TFCn>WQdcJ6=>S$@0-gy8nt1K?r=UhWOKmLv%QKREMvKIPy
zx~>dC99O>DN*(&G+Y0IXM0-w2+u1cwKb?)?^REBHvqDY$iiMbEtgnTs-*~v)v0i5h
zRD@8R;Zg8H8-QZ-aHtZt{la03Ur^DqMYFdSd&rs#jl|$|3_=
z+o6#fa*qj>Kj_JQ}tUHN&Z#VmE1U*|Ph-Ld)
zZsckUBBAH4C42tEzQj(h(oe5Mc!s-#@;eig=`rqdSTJn*I>n4QWUHaITKqG8xtJYf
z^SQLj!RPq({Bh*i;|~&F^#+c&2@f;?`_}2Ts5Lp`7GD<}>U)=+!M62VAT^GAnL0mjjT
z0W2$NdGN~s*UzWwSHol-kt+v4@6W(?cgJh$gOmJOq1&n*jahhR-%qx-LZ8ptlC|90
zT8b|Ax9i+BW}cNgT73`Rr-CaH69ysA3b8&uPkBK}*u<%&cD15E6p&X>d;TGmW;Q8@
zuzs481rp`MgBismb4SBSX$XNvyX&rt3t>y*1R@TrXyq>L?l(wA2qpFdnYuK1&ceYo
z(iuuZR3n$F*mXoSUdZi`6#|hL0|i^q$+1pNxBI009bbJ1KC=GFL0PYl%1hp)>+AR}
z3{^QM7wmnPpoA`sSbQfcIyP9FOLqN@MCO4~gFbE*rCdRzGBuY-bSB|1oOUExnw#1ql43?tY8MUN&rfW0$RiLba5t&tcbSje6Ar25z0DoXxi+qc{3N7DA+
z8S8URKniQoe7W@1!0?=aE53$*W}>WkJja9|tCuv1=sRII@T=lC-=f9xP%5cx
zQ33tE%?Kv8es$WKkpP1MXNCEQnr6w@1fm$_ewEKf$%V+*MB}KR_-t$mPe=JrXC|@r
zleV{ex>;|k==j-$LtQDJAx-AhdJ}{sSG(HU44X
zmE-vrYpJ|UnZ&NB3qWP>U1AvKd}o?
zUvBHu2amI8&-oc}7KiuLsA5nYbTh!g76$VUFT8UvRtvP`0y$jE-xg)ONy?DvPl_+M
zrQ$au@t{iZSplGWM7QpUM1jt`n1#^Im_89V#MH}O|A5?+T%Q$);q)ciG4ED~$9*wo
zoFcSk$Hv6qhX!E_^?Jp8z1vi?zNLHQ%Xq!s5;THNbP?p^aAEc_^#-%mvmOHaSSyu|
zf=e^o!5WC+e!u+&R<<`?E5%x(7{+Lk%|(^@nmTRH8{iV062tpC%+~aCKI0pQy~Ej|
z{nG8d-*8SrO>(&OD=r4Mv1zdk!kw?|Z`I`A$6VWaMNq8flC=
zUQVyN<3d<$SiN0J+#73q8--g#r&w5_c^H%C&HdbY!G82v`Oz
zy_tCne^&E>&jl*&p$kLk`y{wKGDCaE&AHWcHujFTI>R1u0t<^Gy)VtnKJG9YkTAqm
z_D2Du3Ha=Jm+HnGyC-C(KJ0xT6;GYzM8~t*w*ZD{wz?j)f!8}+*6({b6fKQX$7>ZU
z=-<1UNF#KAaW{;qtyIze6o=1F%0#KnwjDu=M9GZSq(!34I&JeDH;$^5E!Fe=I&BZ8
z5lCLvynYNdT#TmQjN~7*&Vky}pvODHhLn^?2R4=5EVcRk}#hQ&AR&Ma~zbnLvCK
zqc2dA-TE3Sde+6|wO>7}{x_w-PGt2dJVb8+46T*<;F#QfL`kc-IhH0Tx5Kp*c0)X3
zT+(S0#i3W6m6D!_rqU3myeJ_iTfPKtQ9HRW-P!@r{~Te!5;F&!Bub6Eo~%mC9^fX8gOl3sbt&rppQqF4VGHLYWz#xobWvyZ`xr@S=eSm+}ZuBVQhTO0lT0vs<{R4TOJd9gQk&2^n*RhuR}
zm#-~dS8DahyEE2*9%N;aLO&0qA7-(P3007kMP3ECo6gChGBAV(+dpCB$dY$nZnxdUI1*G#fjj{ZL04Cb
zEs_9t!0r0U+Q+mdR7kB(F)lLAaeC{S#6_C
zHX&PqYP8t_rYn-eQ~W~TN=+?1xkx|#f$@@?#ot`ov2aA=rNU-u6M#*%NmHA5pt7V=
zr&N0Ds6+qy)p?@Yj@|onOG_^tqA5!!{Hp8M59p|Gc8&(qyi=5h2GXmb&CT?>XjcsqeIT$=nPvL%gQK5l<&MAf1ayAAqt_1xl@*sc9#_i;@7UGLK|
zjFi(cuse*x72@W5wLA8dS7ac__oP#EjoQiX&sA*Lj^wKU8L&N;NZpw)gxuZuz<0CR
zVpYu00&XIXU6Di8$WkH)KjJCEB6)spxDml9CMbg*XV*@r*0Tch8?$kM$H}$9#L22h
z(fkbDHV)I_BUee3zSHcD@xSE~H}LFshS<0L<|pm1O`VBYr>}B-t9aeYj?uRD)K>wb
zdDEC{af%?|HE(JgZZq!8&jVF@RC#RVFu!D?Zs4h-`f@3J@P(htpX34%+SHlOUB@Z1
z5%)F@mC86-C6#QvtvvQr732LH(#AWGTT>H_DD2cLs>Ty^b46ai
zxVJx2hFXY6b&|N{S1DF>f3?_HmHA;*e&8j
zNxRs|mUJ3Ys$$CH4P7LAKJO(d)7_~^Au)GpWzb*DP+nEKc-o9s3g@>zwg$^tCBLd7
zGhl7DXjt_qA_=A;8`v%!0JE0ea;sU9Sev2DeXnnN_5i>oJ;2HT2fc-ZJi!eAy~O{E
zJxl(>V*yVvF6bYZ;012~FYbj8Sn?kSPxb}x|ATx({lJZ(evlY+LNJ8j3G78h@OkQk
z=vHyJEk3RM;98zwBKXN$2nyil>gna-tf%{g0arai-QY1wYi~ac1Q28wjDYZONY-k>
z21yef?yyyUdX+~M^@wY9+teazX(v!e^^ph(`cbBn$)13qXU;+|r1OY9bj-oUW2}v7
zCp##{$dr5dLy$}phIj5;p0})8Z(+Y^-y&loQ+v(pnGflUNT35U6Bi5&vd&mahu-QiXv_gBV<6JLOQVoKV((QPrmv^i@cZw-PCocU|S8y
z=U~|Iqi{UqJ51U86kk?PzrINKRs%y)3q+87+jtI-9nLvMrJs+fT{B{9oDuoF8Is!9
z;v7U~C(f{Zf}(}33PPj;|M#^3IAs`w_b(U@hs8iB;I3hik-xVA;1b~w5%AM>fWKmz
z#wQp%3k~%@U^-kX1|spFJ*)o%A$N{_^7j`Vf7(a{*NS`^#$zGah&L8+={N`#{5}>U
z1JZ&^#X%Hl|DRUXa|8rh1d^wpg@6EhqDNSnB^cgn38qIzLID5mUj4@*GW_Vt5y&5o
z6%R27k9dILRUTj}_=k9i6qwc%45#q{lfrl7Au?dk|Eyd+!N_p6geQY=um5fE#tV!J
zuYMAN#Nnq2kk??C@Bh{W`+~9I5s6R6fqr1PxgVGePV|%;rvFb_Jq1eff5m(VQwoD5
m!Z3;X{!?U6q5mzi|50FCsz}IxzmxsxRmVd>@DGPPt^OA~bQ9YE
delta 8258
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
Bf6@Q|
diff --git a/information.json b/information.json
index 5a10699..2b8d7b0 100755
--- a/information.json
+++ b/information.json
@@ -1,5 +1,5 @@
{
- "Version": "2.2.0",
+ "Version": "2.2.0-Alpha2",
"Thank": [
"感谢 @a2035274 @虚幻的早晨 https://bbs.deepin.org/post/238301",
"感谢 @zhangs https://bbs.deepin.org/post/227948",
diff --git a/mainwindow.py b/mainwindow.py
index 37504d8..f0e755e 100755
--- a/mainwindow.py
+++ b/mainwindow.py
@@ -165,7 +165,7 @@ class Runexebutton_threading(QtCore.QThread):
option += "WINEDEBUG=FIXME,ERR,WARN,TRACE,Message "
wineUsingOption = ""
if o1.currentText() == "基于 exagear 的 deepin-wine6-stable" or o1.currentText() == "基于 box86 的 deepin-wine6-stable":
- wineUsingOption = "--disable-gpu"
+ wineUsingOption = ""
if o1.currentText() == "基于 exagear 的 deepin-wine6-stable":
os.system(f"'{programPath}/deepin-wine-runner-create-botton.py' '{wineBottonPath}'")
if o1.currentText() == "基于 box86 的 deepin-wine6-stable":
@@ -295,18 +295,24 @@ def make_desktop_on_launcher():
return
os.remove(f"{programPath}/dlls-arm.7z")
if o1.currentText() == "基于 exagear 的 deepin-wine6-stable" or o1.currentText() == "基于 box86 的 deepin-wine6-stable":
- wineUsingOption = "--disable-gpu"
+ 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:
- if i[1].replace("wineBottonPath", wineBottonPath) == e2.currentText():
+ listValue = i[1].replace("wineBottonPath", wineBottonPath)
+ if listValue == e2.currentText() or listValue == value:
# 如果路径相同,即可以用程序对应的图标
- iconPath = f"{programPath}/Icon/{i[0]}.svg"
+ 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={iconPath}
+Icon={iconPaths}
Type=Application
StartupNotify=true''') # 写入文本文档
if len(shellHistory) == 0 or shellHistory[-1] != combobox1.currentText():
@@ -343,7 +349,7 @@ def make_desktop_on_desktop():
wineBottonPath = e1.currentText()
wineUsingOption = ""
if o1.currentText() == "基于 exagear 的 deepin-wine6-stable" or o1.currentText() == "基于 box86 的 deepin-wine6-stable":
- wineUsingOption = "--disable-gpu"
+ wineUsingOption = ""
if o1.currentText() == "基于 box86 的 deepin-wine6-stable":
if not os.path.exists(f"{programPath}/dlls-arm"):
if os.system(f"7z x \"{programPath}/dlls-arm.7z\" -o\"{programPath}\""):
@@ -358,17 +364,23 @@ def make_desktop_on_desktop():
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:
- if i[1].replace("wineBottonPath", wineBottonPath) == e2.currentText():
+ listValue = i[1].replace("wineBottonPath", wineBottonPath)
+ if listValue == e2.currentText() or listValue == value:
# 如果路径相同,即可以用程序对应的图标
- iconPath = f"{programPath}/Icon/{i[0]}.svg"
+ 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={iconPath}
+Icon={iconPaths}
Type=Application
StartupNotify=true''') # 写入文本文档
if len(shellHistory) == 0 or shellHistory[-1] != combobox1.currentText():
@@ -464,7 +476,7 @@ class RunWineProgramThread(QtCore.QThread):
if o1.currentText() == "基于 exagear 的 deepin-wine6-stable":
os.system(f"'{programPath}/deepin-wine-runner-create-botton.py' '{wineBottonPath}'")
if o1.currentText() == "基于 exagear 的 deepin-wine6-stable" or o1.currentText() == "基于 box86 的 deepin-wine6-stable":
- wineUsingOption = "--disable-gpu"
+ wineUsingOption = ""
if o1.currentText() == "基于 box86 的 deepin-wine6-stable":
if not os.path.exists(f"{programPath}/dlls-arm"):
if os.system(f"7z x \"{programPath}/dlls-arm.7z\" -o\"{programPath}\""):
@@ -528,7 +540,7 @@ class RunWinetricksThread(QtCore.QThread):
option += "WINEDEBUG=-all "
wineUsingOption = ""
if o1.currentText() == "基于 exagear 的 deepin-wine6-stable" or o1.currentText() == "基于 box86 的 deepin-wine6-stable":
- wineUsingOption = "--disable-gpu"
+ wineUsingOption = ""
if o1.currentText() == "基于 box86 的 deepin-wine6-stable":
if not os.path.exists(f"{programPath}/dlls-arm"):
if os.system(f"7z x \"{programPath}/dlls-arm.7z\" -o\"{programPath}\""):
@@ -1523,7 +1535,7 @@ programPath = os.path.split(os.path.realpath(__file__))[0] # 返回 string
try:
wine = {
"基于 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 ",
- "基于 exagear 的 deepin-wine6-stable": f"/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 ",
+ "基于 exagear 的 deepin-wine6-stable": f"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 ",
"deepin-wine6 stable": "deepin-wine6-stable",
"deepin-wine5 stable": "deepin-wine5-stable",
"spark-wine7-devel": "spark-wine7-devel",
@@ -1635,6 +1647,10 @@ updateThingsString = '''※1、Dll 提取工具支持 NT 6.X 及以上版本的
※7、基于生态适配活动的打包器更换为 spark-wine-helper 以及添加自动删除残留脚本
8、更新组件安装的离线列表
9、不再强制依赖深度终端,只做推荐安装
+以下更新内容旧版本也适用(只限 2.1.0 及以上版本)
+※1、在“安装更多Wine”的Wine安装工具中上 wine-staging 7.17、wine-staging 6.7、spark-wine7-devel 7.17
+※2、云 Dll 工具上新 Dll
+※3、VCPP 运行库安装工具新增 VC6 运行库
'''
for i in information["Thank"]:
thankText += f"{i}\n"
@@ -1682,7 +1698,11 @@ iconList = [
["微信", "wineBottonPath/drive_c/Program Files/Tencent/WeChat/WeChat.exe"],
["微信", "wineBottonPath/drive_c/Program Files (x86)/Tencent/WeChat/WeChat.exe"],
["UltraISO", "wineBottonPath/drive_c/Program Files/UltraISO/UltraISO.exe"],
- ["UltraISO", "wineBottonPath/drive_c/Program Files (x86)/UltraISO/UltraISO.exe"]
+ ["UltraISO", "wineBottonPath/drive_c/Program Files (x86)/UltraISO/UltraISO.exe"],
+ ["迅雷", "wineBottonPath/drive_c/Program Files/Thunder Network/MiniThunder/Bin/ThunderMini.exe"],
+ ["迅雷", "wineBottonPath/drive_c/Program Files (x86)/Thunder Network/MiniThunder/Bin/ThunderMini.exe"],
+ ["Microsoft Office Word", "wineBottonPath/drive_c/Program Files/Microsoft Office/Office12/WINWORD.EXE"],
+ ["Microsoft Office Word", "wineBottonPath/drive_c/Program Files (x86)/Microsoft Office/Office12/WINWORD.EXE"]
]
for i in iconListUnBuild:
iconList.append(i)
@@ -1766,7 +1786,7 @@ 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' 'z:/{e2.currentText()}"))
+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", "窗口透明工具"))
diff --git a/package-script.zip b/package-script.zip
index 52cf0af998dad70e13ade47105e3cc335017c994..f3321454f9761c9f25d12c6c03fa7141cd082eca 100755
GIT binary patch
delta 450
zcmcb$TIkMdA>IIQW)?065I8YWXCkjEdj*?(ay6U$^u%Ijsm9=~!Hj{AnGe601@Yy!
zAAQWI%?IaBf7!{xw_W}dqZ=DcOl11GB4)PfuYWQMv`_lMxP8(OrhOs2K%+w!g?#su
z1zICJ`2nBU^kQFTQLt4#K&$$Fnbo;;jg+`*xj@dDHi1QA`!!!?GgU06PPZ&(28*`?
z9ke~Mm_I9ZJ
zX0br#>4t&Kiqn@*U~yp93<2}Rr!!7uab^CM0Oci2Wbt4QNJQ}1rk|L|;>NgYI{ze=
zG{(y5Ws_Lq7|%?ZL=+d
usw|zt62RP84&^6g`OANC|Gt1;g9`WhRrn2at|-8zJ~a?K5-ISljO4D;SFFL~E<-X+dX0y=DFbg%d{(Ptmr
zYfknbddMk56P+bM*a=^T*<1mtNaNgr{I0-yrT;vA?4!iJpDZL;%|J#kGOibEZX#kP
z8km3gM@QWyO}FtXwa}xAE_GO7$*
zmGP?qO8#jtje}@jKq(EI>Gl8x{+z~pN3|-Qt2l(F+~1so>a*CvuF0Rp7&OfRttOzA
zjPosv_>C8p4ZjxqK?PddiID+8UZK|6&F3_{96
z7Y2r4cdgv(B6ki)V0gVUspN1Lwv`Iv3P{8a?4kV)ki@p~pUm{Vvq=L-7-b<+k8oU2
I(pX}D00-re4*&oF
diff --git a/package-script/information.json b/package-script/information.json
index 9823471..3c71ba4 100755
--- a/package-script/information.json
+++ b/package-script/information.json
@@ -1,3 +1,3 @@
{
- "Version": "2.2.0"
+ "Version": "2.2.0-2"
}