diff --git a/LunaTranslator/LunaTranslator/LunaTranslator.py b/LunaTranslator/LunaTranslator/LunaTranslator.py index ac654f32..2409a794 100644 --- a/LunaTranslator/LunaTranslator/LunaTranslator.py +++ b/LunaTranslator/LunaTranslator/LunaTranslator.py @@ -7,7 +7,7 @@ from myutils.config import ( _TR, savehook_new_list, uid2gamepath, - gamepath2uid, + findgameuidofpath, savehook_new_data, setlanguage, static_data, @@ -20,7 +20,6 @@ from myutils.utils import ( kanjitrans, checkifnewgame, checkpostusing, - getpostfile, stringfyerror, ) from myutils.wrapper import threader @@ -43,7 +42,7 @@ from gui.attachprocessdialog import AttachProcessDialog import windows import gobject import winsharedutils -from winsharedutils import pid_running +from winsharedutils import collect_running_pids from myutils.post import POSTSOLVE from myutils.utils import nowisdark @@ -105,9 +104,11 @@ class MAINUI: for item in static_data["transoptimi"]: name = item["name"] try: - mm = getpostfile(name) - if not mm: + checkpath = "./LunaTranslator/transoptimi/" + name + ".py" + if os.path.exists(checkpath) == False: continue + mm = "transoptimi." + name + Process = importlib.import_module(mm).Process def __(kls, _name): @@ -475,12 +476,17 @@ class MAINUI: use, self.settin_ui.voicelistsignal, self.settin_ui.mp3playsignal ) - def selectprocess(self, selectedp): + def selectprocess(self, selectedp, title): self.textsource = None pids, pexe, hwnd = selectedp - checkifnewgame(savehook_new_list, pexe, windows.GetWindowText(hwnd)) + if len(collect_running_pids(pids)) == 0: + return + if not title: + title = windows.GetWindowText(hwnd) + checkifnewgame(savehook_new_list, pexe, title) if globalconfig["sourcestatus2"]["texthook"]["use"]: - self.textsource = texthook(pids, hwnd, pexe, gamepath2uid[pexe]) + gameuid = findgameuidofpath(pexe, savehook_new_list) + self.textsource = texthook(pids, hwnd, pexe, gameuid) self.textsource.start() def starttextsource(self, use=None, checked=True): @@ -563,16 +569,9 @@ class MAINUI: def fanyiinitmethod(self, classname): try: - if classname == "selfbuild": - if not os.path.exists("./userconfig/selfbuild.py"): - return None - aclass = importlib.import_module("selfbuild").TS - else: - if not os.path.exists( - "./LunaTranslator/translator/" + classname + ".py" - ): - return None - aclass = importlib.import_module("translator." + classname).TS + if not os.path.exists("./LunaTranslator/translator/" + classname + ".py"): + return None + aclass = importlib.import_module("translator." + classname).TS except Exception as e: print_exc() self.textgetmethod( @@ -676,109 +675,101 @@ class MAINUI: except: print_exc() - def onwindowloadautohook(self): - textsourceusing = globalconfig["sourcestatus2"]["texthook"]["use"] - if not (globalconfig["autostarthook"] and textsourceusing): - return - elif self.AttachProcessDialog and self.AttachProcessDialog.isVisible(): - return - else: - try: - if self.textsource is None: - hwnd = windows.GetForegroundWindow() - pid = windows.GetWindowThreadProcessId(hwnd) - name_ = getpidexe(pid) - if ( - name_ - and name_ in gamepath2uid - and gamepath2uid[name_] in savehook_new_list - ): - lps = ListProcess(False) - for pids, _exe in lps: - if _exe == name_: - - # if any(map(testprivilege,pids)): - self.textsource = None - if globalconfig["sourcestatus2"]["texthook"]["use"]: - if globalconfig["startgamenototop"] == False: - idx = savehook_new_list.index( - gamepath2uid[name_] - ) - savehook_new_list.insert( - 0, savehook_new_list.pop(idx) - ) - needinserthookcode = savehook_new_data[ - gamepath2uid[name_] - ]["needinserthookcode"] - self.textsource = texthook( - pids, - hwnd, - name_, - gamepath2uid[name_], - autostarthookcode=savehook_new_data[ - gamepath2uid[name_] - ]["hook"], - needinserthookcode=needinserthookcode, - ) - self.textsource.start() - else: - pids = self.textsource.pids - if sum([int(pid_running(pid)) for pid in pids]) == 0: - self.textsource = None - self.translation_ui.thistimenotsetop = False - if globalconfig["keepontop"]: - self.translation_ui.settop() - - except: - - print_exc() - def autohookmonitorthread(self): + def onwindowloadautohook(): + textsourceusing = globalconfig["sourcestatus2"]["texthook"]["use"] + if not (globalconfig["autostarthook"] and textsourceusing): + return + elif self.AttachProcessDialog and self.AttachProcessDialog.isVisible(): + return + if self.textsource is None: + hwnd = windows.GetForegroundWindow() + pid = windows.GetWindowThreadProcessId(hwnd) + name_ = getpidexe(pid) + if not name_: + return + uid = findgameuidofpath(name_, savehook_new_list) + if not uid: + return + lps = ListProcess(False) + for pids, _exe in lps: + if _exe != name_: + continue + + if self.textsource is not None: + return + if not globalconfig["sourcestatus2"]["texthook"]["use"]: + return + if globalconfig["startgamenototop"] == False: + idx = savehook_new_list.index(uid) + savehook_new_list.insert(0, savehook_new_list.pop(idx)) + needinserthookcode = savehook_new_data[uid]["needinserthookcode"] + self.textsource = texthook( + pids, + hwnd, + name_, + uid, + autostarthookcode=savehook_new_data[uid]["hook"], + needinserthookcode=needinserthookcode, + ) + self.textsource.start() + + else: + pids = self.textsource.pids + if len(collect_running_pids(pids)) != 0: + return + self.textsource = None + self.translation_ui.thistimenotsetop = False + if globalconfig["keepontop"]: + self.translation_ui.settop() + while self.isrunning: - self.onwindowloadautohook() - time.sleep( - 0.5 - ) # 太短了的话,中间存在一瞬间,后台进程比前台窗口内存占用要大。。。 + try: + onwindowloadautohook() + except: + print_exc() + time.sleep(0.5) + # 太短了的话,中间存在一瞬间,后台进程比前台窗口内存占用要大。。。 def autocheckhwndexists(self): - def setandrefresh(bool): - if self.translation_ui.isbindedwindow != bool: - self.translation_ui.isbindedwindow = bool + def setandrefresh(b): + if self.translation_ui.isbindedwindow != b: + self.translation_ui.isbindedwindow = b self.translation_ui.refreshtooliconsignal.emit() - while self.isrunning: - if self.textsource: - - hwnd = self.textsource.hwnd - - if hwnd == 0: - if globalconfig["sourcestatus2"]["texthook"]["use"]: - fhwnd = windows.GetForegroundWindow() - pids = self.textsource.pids - if ( - hwnd == 0 - and windows.GetWindowThreadProcessId(fhwnd) in pids - ): - if "once" not in dir(self.textsource): - self.textsource.once = True - self.textsource.hwnd = fhwnd - setandrefresh(True) - else: - setandrefresh(False) - else: - if windows.GetWindowThreadProcessId(hwnd) == 0: - self.textsource.hwnd = 0 - setandrefresh(False) - elif "once" not in dir(self.textsource): - self.textsource.once = True - setandrefresh(True) - if len(self.textsource.pids): - _mute = winsharedutils.GetProcessMute(self.textsource.pids[0]) - if self.translation_ui.processismuteed != _mute: - self.translation_ui.processismuteed = _mute - self.translation_ui.refreshtooliconsignal.emit() - else: + def __do(): + if not self.textsource: setandrefresh(False) + return + hwnd = self.textsource.hwnd + + if hwnd == 0: + if not globalconfig["sourcestatus2"]["texthook"]["use"]: + setandrefresh(False) + else: + fhwnd = windows.GetForegroundWindow() + pids = self.textsource.pids + notdone = "once" not in dir(self.textsource) + isgoodproc = windows.GetWindowThreadProcessId(fhwnd) in pids + if isgoodproc and notdone: + self.textsource.once = True + self.textsource.hwnd = fhwnd + setandrefresh(True) + else: + if windows.GetWindowThreadProcessId(hwnd) == 0: + self.textsource.hwnd = 0 + setandrefresh(False) + elif "once" not in dir(self.textsource): + self.textsource.once = True + setandrefresh(True) + if len(self.textsource.pids): + _mute = winsharedutils.GetProcessMute(self.textsource.pids[0]) + if self.translation_ui.processismuteed != _mute: + self.translation_ui.processismuteed = _mute + self.translation_ui.refreshtooliconsignal.emit() + + while self.isrunning: + __do() time.sleep(0.5) @@ -925,29 +916,28 @@ class MAINUI: True, ) + _hwnd = windows.GetForegroundWindow() + _pid = windows.GetWindowThreadProcessId(_hwnd) try: - _hwnd = windows.GetForegroundWindow() - _pid = windows.GetWindowThreadProcessId(_hwnd) - + if len(self.textsource.pids) == 0: + raise Exception() + if _pid in self.textsource.pids or _pid == os.getpid(): + isok(self.textsource.gameuid) + else: + self.__currentexe = None + except: + name_ = getpidexe(_pid) + if not name_: + return + uids = findgameuidofpath(name_, findall=True) try: - if len(self.textsource.pids) == 0: - raise Exception() - if _pid in self.textsource.pids or _pid == os.getpid(): - isok(self.textsource.gameuid) + if len(uids): + for uid in uids: + isok(uid) else: self.__currentexe = None except: - name_ = getpidexe(_pid) - if ( - name_ - and name_ in gamepath2uid - and gamepath2uid[name_] in savehook_new_list - ): - isok(gamepath2uid[name_]) - else: - self.__currentexe = None - except: - print_exc() + print_exc() @threader def clickwordcallback(self, word, append): diff --git a/LunaTranslator/LunaTranslator/gobject.py b/LunaTranslator/LunaTranslator/gobject.py index c266f69b..e9906b79 100644 --- a/LunaTranslator/LunaTranslator/gobject.py +++ b/LunaTranslator/LunaTranslator/gobject.py @@ -34,8 +34,13 @@ def gettranslationrecorddir(name): return getcachedir(name, "translation_record") +def gettempdir_1(): + tgt = getcachedir("temp") + return tgt + + def gettempdir(filename): - tgt = getcachedir(os.path.join(f"temp{os.getpid()}", filename)) + tgt = getcachedir(os.path.join(f"temp/{os.getpid()}", filename)) return tgt diff --git a/LunaTranslator/LunaTranslator/gui/attachprocessdialog.py b/LunaTranslator/LunaTranslator/gui/attachprocessdialog.py index ae899f64..ccf36353 100644 --- a/LunaTranslator/LunaTranslator/gui/attachprocessdialog.py +++ b/LunaTranslator/LunaTranslator/gui/attachprocessdialog.py @@ -32,8 +32,10 @@ class AttachProcessDialog(saveposwindow): _pids = [pid] self.processEdit.setText(name) self.processIdEdit.setText(",".join([str(pid) for pid in _pids])) - [_.show() for _ in self.windowtextlayoutwidgets] self.windowtext.setText(windows.GetWindowText(hwnd)) + self.processEdit.setCursorPosition(0) + self.processIdEdit.setCursorPosition(0) + self.windowtext.setCursorPosition(0) self.selectedp = (_pids, name, hwnd) def closeEvent(self, e): @@ -80,10 +82,8 @@ class AttachProcessDialog(saveposwindow): self.layout3.addWidget(self.processEdit) self.windowtext = QLineEdit() - self.windowtextlayoutwidgets = [QLabel(_TR("窗口名")), self.windowtext] - [_.hide() for _ in self.windowtextlayoutwidgets] - self.layout2.addWidget(self.windowtextlayoutwidgets[0]) - self.layout2.addWidget(self.windowtextlayoutwidgets[1]) + self.layout2.addWidget(QLabel(_TR("标题"))) + self.layout2.addWidget(self.windowtext) self.processList = QListView() self.buttonBox = QDialogButtonBox() self.buttonBox.setStandardButtons( @@ -109,15 +109,25 @@ class AttachProcessDialog(saveposwindow): self.processList.clicked.connect(self.selectedfunc) self.processIdEdit.textEdited.connect(self.editpid) - self.processEdit.setReadOnly(True) - self.windowtext.setReadOnly(True) + # self.processEdit.setReadOnly(True) + self.processEdit.textEdited.connect(self.filterproc) + + def filterproc(self): + self.processIdEdit.clear() + self.windowtext.clear() + text = self.processEdit.text() + if len(text) == 0: + self.refreshfunction() + return + for row in range(self.model.rowCount()): + hide = not (text in self.model.item(row, 0).text()) + self.processList.setRowHidden(row, hide) def refreshfunction(self): self.windowtext.clear() self.processEdit.clear() self.processIdEdit.clear() - [_.hide() for _ in self.windowtextlayoutwidgets] self.selectedp = None ########################### @@ -151,15 +161,21 @@ class AttachProcessDialog(saveposwindow): def editpid(self, process): pids = self.safesplit(process) self.selectedp = (pids, getpidexe(pids[0]), self.guesshwnd(pids)) + self.windowtext.setText(windows.GetWindowText(self.selectedp[-1])) self.processEdit.setText(self.selectedp[1]) - [_.hide() for _ in self.windowtextlayoutwidgets] + self.windowtext.setCursorPosition(0) + self.processEdit.setCursorPosition(0) + def selectedfunc(self, index): pids, pexe = self.processlist[index.row()] self.processEdit.setText(pexe) self.processIdEdit.setText(",".join([str(pid) for pid in pids])) - [_.hide() for _ in self.windowtextlayoutwidgets] self.selectedp = pids, pexe, self.guesshwnd(pids) + self.windowtext.setText(windows.GetWindowText(self.selectedp[-1])) + self.processEdit.setCursorPosition(0) + self.processIdEdit.setCursorPosition(0) + self.windowtext.setCursorPosition(0) def guesshwnd(self, pids): for pid in pids: @@ -175,10 +191,5 @@ class AttachProcessDialog(saveposwindow): if self.selectedp[1] is None: getQMessageBox(self, "错误", "权限不足,请以管理员权限运行!") return - # for pid in self.selectedp[0]: - - # if(not testprivilege(pid)): - # getQMessageBox(self,"错误","权限不足,请使用管理员权限运行本程序!") - # return self.close() - self.callback(self.selectedp) + self.callback(self.selectedp, self.windowtext.text()) diff --git a/LunaTranslator/LunaTranslator/gui/dialog_savedgame.py b/LunaTranslator/LunaTranslator/gui/dialog_savedgame.py index 50487de0..f469804e 100644 --- a/LunaTranslator/LunaTranslator/gui/dialog_savedgame.py +++ b/LunaTranslator/LunaTranslator/gui/dialog_savedgame.py @@ -6,7 +6,6 @@ import windows, gobject, winsharedutils from myutils.config import ( savehook_new_list, savehook_new_data, - gamepath2uid, savegametaged, uid2gamepath, _TR, @@ -614,15 +613,14 @@ def maybehavebutton(self, gameuid, post): class dialog_setting_game_internal(QWidget): def selectexe(self): - f = QFileDialog.getOpenFileName(directory=uid2gamepath[self.gameuid]) + originpath = uid2gamepath[self.gameuid] + f = QFileDialog.getOpenFileName(directory=originpath) res = f[0] if res == "": return + # 修改路径允许路径重复 + # 添加路径实际上也允许重复,只不过会去重。 res = os.path.normpath(res) - if res in gamepath2uid: - return - originpath = uid2gamepath[self.gameuid] - gamepath2uid[res] = gamepath2uid.pop(originpath) uid2gamepath[self.gameuid] = res gobject.baseobject.resetgameinternal(originpath, res) _icon = getExeIcon(res, cache=True) @@ -715,13 +713,16 @@ class dialog_setting_game_internal(QWidget): internallist=list(globalconfig["metadata"].keys()), ), ) + formLayout.addRow(None, QLabel()) for key in globalconfig["metadata"]: try: idname = globalconfig["metadata"][key]["target"] vndbid = QLineEdit(str(savehook_new_data[gameuid][idname])) if globalconfig["metadata"][key].get("idtype", 1) == 0: vndbid.setValidator(QIntValidator()) - vndbid.setSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Fixed) + vndbid.setSizePolicy( + QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Fixed + ) vndbid.textEdited.connect( functools.partial(idtypecheck, key, idname, gameuid) @@ -730,6 +731,7 @@ class dialog_setting_game_internal(QWidget): functools.partial(gamdidchangedtask, key, idname, gameuid) ) _vbox_internal = [ + getsimpleswitch(globalconfig["metadata"][key], "auto"), vndbid, getIconButton( functools.partial(self.openrefmainpage, key, idname, gameuid), @@ -746,7 +748,7 @@ class dialog_setting_game_internal(QWidget): try: __settting = targetmod[key].querysettingwindow _vbox_internal.insert( - 1, + 2, getIconButton( functools.partial(__settting, self, gameuid), icon="fa.gear" ), @@ -1974,7 +1976,7 @@ class dialog_savedgame_new(QWidget): menu = QMenu(self) editname = QAction(_TR("修改列表名称")) - addlist = QAction(_TR("添加列表")) + addlist = QAction(_TR("创建列表")) dellist = QAction(_TR("删除列表")) startgame = QAction(_TR("开始游戏")) @@ -2028,7 +2030,7 @@ class dialog_savedgame_new(QWidget): elif action == editname or action == addlist: _dia = Prompt_dialog( self, - _TR("修改列表名称" if action == editname else "添加列表"), + _TR("修改列表名称" if action == editname else "创建列表"), "", [ [ @@ -2160,7 +2162,7 @@ class dialog_savedgame_new(QWidget): self.simplebutton("删除游戏", True, self.clicked2, False) self.simplebutton("打开目录", True, self.clicked4, True) - self.simplebutton("添加到列表", False, self.addtolist, 1) + self.simplebutton("添加到列表", True, self.addtolist, False) if globalconfig["startgamenototop"]: self.simplebutton("左移", True, functools.partial(self.moverank, -1), False) self.simplebutton("右移", True, functools.partial(self.moverank, 1), False) @@ -2770,9 +2772,9 @@ class dialog_savedgame_v3(QWidget): self.stack.directshow() def stack_showmenu(self, ispixmenu, p): - if not self.currentfocusuid: - return menu = QMenu(self) + + addlist = QAction(_TR("创建列表")) startgame = QAction(_TR("开始游戏")) delgame = QAction(_TR("删除游戏")) opendir = QAction(_TR("打开目录")) @@ -2780,24 +2782,57 @@ class dialog_savedgame_v3(QWidget): setimage = QAction(_TR("设为封面")) deleteimage = QAction(_TR("删除图片")) hualang = QAction(_TR("画廊")) - exists = os.path.exists(uid2gamepath[self.currentfocusuid]) - if exists: - menu.addAction(startgame) - menu.addAction(delgame) - if exists: - menu.addAction(opendir) + if not self.currentfocusuid: - menu.addSeparator() - menu.addAction(addtolist) + menu.addAction(addlist) + else: + exists = os.path.exists(uid2gamepath[self.currentfocusuid]) + if exists: + menu.addAction(startgame) + menu.addAction(delgame) + if exists: + menu.addAction(opendir) - if ispixmenu: menu.addSeparator() - menu.addAction(setimage) - menu.addAction(deleteimage) - menu.addAction(hualang) + menu.addAction(addtolist) + + if ispixmenu: + menu.addSeparator() + menu.addAction(setimage) + menu.addAction(deleteimage) + menu.addAction(hualang) action = menu.exec(QCursor.pos()) if action == startgame: startgamecheck(self, self.currentfocusuid) + elif addlist == action: + _dia = Prompt_dialog( + self, + _TR("创建列表"), + "", + [ + [ + _TR("名称"), + (""), + ], + ], + ) + + if _dia.exec(): + + title = _dia.text[0].text() + if title != "": + i = calculatetagidx(None) + if action == addlist: + tag = { + "title": title, + "games": [], + "uid": str(uuid.uuid4()), + "opened": True, + } + savegametaged.insert(i, tag) + group0 = self.createtaglist(self.stack, title, tag["uid"], True) + self.stack.insertw(i, group0) + elif action == delgame: self.shanchuyouxi() elif action == hualang: @@ -2885,7 +2920,7 @@ class dialog_savedgame_v3(QWidget): ) self.simplebutton("删除游戏", True, self.shanchuyouxi, False) self.simplebutton("打开目录", True, self.clicked4, True) - self.simplebutton("添加到列表", False, self.addtolist, 1) + self.simplebutton("添加到列表", True, self.addtolist, False) if globalconfig["startgamenototop"]: self.simplebutton("上移", True, functools.partial(self.moverank, -1), False) self.simplebutton("下移", True, functools.partial(self.moverank, 1), False) @@ -2945,7 +2980,7 @@ class dialog_savedgame_v3(QWidget): self.reftagid = tagid menu = QMenu(self) editname = QAction(_TR("修改列表名称")) - addlist = QAction(_TR("添加列表")) + addlist = QAction(_TR("创建列表")) dellist = QAction(_TR("删除列表")) Upaction = QAction(_TR("上移")) Downaction = QAction(_TR("下移")) @@ -2975,7 +3010,7 @@ class dialog_savedgame_v3(QWidget): elif action == editname or action == addlist: _dia = Prompt_dialog( self, - _TR("修改列表名称" if action == editname else "添加列表"), + _TR("修改列表名称" if action == editname else "创建列表"), "", [ [ diff --git a/LunaTranslator/LunaTranslator/gui/setting_proxy.py b/LunaTranslator/LunaTranslator/gui/setting_proxy.py index a620490d..24610b6a 100644 --- a/LunaTranslator/LunaTranslator/gui/setting_proxy.py +++ b/LunaTranslator/LunaTranslator/gui/setting_proxy.py @@ -22,7 +22,7 @@ def getall(l, item="fanyi", name=None): continue if name: _f = name % fanyi - if fanyi != "selfbuild" and os.path.exists(_f) == False: + if not os.path.exists(_f): continue i += 1 diff --git a/LunaTranslator/LunaTranslator/gui/setting_textinput.py b/LunaTranslator/LunaTranslator/gui/setting_textinput.py index 6b03f9eb..ed7d164e 100644 --- a/LunaTranslator/LunaTranslator/gui/setting_textinput.py +++ b/LunaTranslator/LunaTranslator/gui/setting_textinput.py @@ -34,14 +34,18 @@ from gui.usefulwidget import ( def __create(self): self.selectbutton = getIconButton( - gobject.baseobject.createattachprocess, icon="fa.gear" + gobject.baseobject.createattachprocess, + icon="fa.gear", + enable=globalconfig["sourcestatus2"]["texthook"]["use"], ) return self.selectbutton def __create2(self): self.selecthookbutton = getIconButton( - lambda: gobject.baseobject.hookselectdialog.showsignal.emit(), icon="fa.gear" + lambda: gobject.baseobject.hookselectdialog.showsignal.emit(), + icon="fa.gear", + enable=globalconfig["sourcestatus2"]["texthook"]["use"], ) return self.selecthookbutton diff --git a/LunaTranslator/LunaTranslator/gui/setting_translate.py b/LunaTranslator/LunaTranslator/gui/setting_translate.py index b44113ba..a645ff03 100644 --- a/LunaTranslator/LunaTranslator/gui/setting_translate.py +++ b/LunaTranslator/LunaTranslator/gui/setting_translate.py @@ -38,7 +38,7 @@ def initsome11(self, l, label=None): continue _f = "./Lunatranslator/translator/{}.py".format(fanyi) - if fanyi != "selfbuild" and os.path.exists(_f) == False: + if not os.path.exists(_f): continue i += 1 @@ -128,12 +128,9 @@ def checkconnected(self): for dev in develop: if not globalconfig["fanyi"][dev]["use"]: continue - if dev == "selfbuild": - if not os.path.exists("./userconfig/selfbuild.py"): - continue - else: - if not os.path.exists("./LunaTranslator/translator/" + dev + ".py"): - continue + + if not os.path.exists("./LunaTranslator/translator/" + dev + ".py"): + continue needstart = True break try: @@ -218,7 +215,7 @@ def setTabTwo_lazy(self, basel): "", "模糊匹配_相似度_%", D_getspinbox(0, 100, globalconfig, "premtsimi2"), - "" + "", ], [ (functools.partial(createbtnexport, self), 0), @@ -229,7 +226,7 @@ def setTabTwo_lazy(self, basel): "group", ) ], - [] + [], ] _items = [ { diff --git a/LunaTranslator/LunaTranslator/gui/showword.py b/LunaTranslator/LunaTranslator/gui/showword.py index d3e63cc5..c868989c 100644 --- a/LunaTranslator/LunaTranslator/gui/showword.py +++ b/LunaTranslator/LunaTranslator/gui/showword.py @@ -489,6 +489,11 @@ class AnkiWindow(QWidget): cropbutton = QPushButton(qtawesome.icon("fa.crop"), "") cropbutton.clicked.connect(self.crop) + grabwindowbtn = QPushButton(qtawesome.icon("fa.camera"), "") + grabwindowbtn.clicked.connect( + lambda: grabwindow(getimageformat(), self.editpath.setText) + ) + self.audiopath = QLineEdit() self.audiopath.setReadOnly(True) self.audiopath_sentence = QLineEdit() @@ -566,6 +571,7 @@ class AnkiWindow(QWidget): QLabel(_TR("截图")), self.editpath, cropbutton, + grabwindowbtn, getIconButton( functools.partial( self.selecfile, self.editpath diff --git a/LunaTranslator/LunaTranslator/gui/translatorUI.py b/LunaTranslator/LunaTranslator/gui/translatorUI.py index f570a72e..96d86de1 100644 --- a/LunaTranslator/LunaTranslator/gui/translatorUI.py +++ b/LunaTranslator/LunaTranslator/gui/translatorUI.py @@ -3,7 +3,14 @@ import time, functools, threading, os, sys, importlib, shutil from traceback import print_exc import windows, qtawesome, gobject, winsharedutils from myutils.wrapper import threader, trypass -from myutils.config import globalconfig, saveallconfig, _TR, static_data, gamepath2uid +from myutils.config import ( + globalconfig, + saveallconfig, + _TR, + static_data, + findgameuidofpath, + savehook_new_list, +) from myutils.subproc import endsubprocs from myutils.ocrutil import ocr_run, imageCut from myutils.utils import loadpostsettingwindowmethod, str2rgba @@ -12,13 +19,14 @@ from gui.setting_about import doupdate from gui.dialog_memory import dialog_memory from gui.textbrowser import Textbrowser from gui.rangeselect import rangeselct_function -from gui.usefulwidget import resizableframeless, isinrect +from gui.usefulwidget import resizableframeless, isinrect, getQMessageBox from gui.edittext import edittrans from gui.dialog_savedgame import browserdialog, dialog_savedgame_integrated class QUnFrameWindow(resizableframeless): displayglobaltooltip = pyqtSignal(str) + displaymessagebox = pyqtSignal(str, str) displayres = pyqtSignal(dict) displayraw1 = pyqtSignal(dict) displaystatus = pyqtSignal(str, str, bool, bool) @@ -522,9 +530,13 @@ class QUnFrameWindow(resizableframeless): def displayglobaltooltip_f(self, string): QToolTip.showText(QCursor.pos(), string, self) + def displaymessagebox_f(self, string1, string2): + getQMessageBox(self, string1, string2) + def initsignals(self): self.hidesignal.connect(self.hide_) self.displayglobaltooltip.connect(self.displayglobaltooltip_f) + self.displaymessagebox.connect(self.displaymessagebox_f) self.ocr_once_signal.connect(self.ocr_once_function) self.displaystatus.connect(self.showstatus) self.showhideuisignal.connect(self.showhideui) @@ -797,7 +809,7 @@ class QUnFrameWindow(resizableframeless): gobject.baseobject.textsource.hwnd = hwnd if pid != _pid else None if not globalconfig["sourcestatus2"]["texthook"]["use"]: gobject.baseobject.textsource.pids = [pid] if pid != _pid else None - gameuid = gamepath2uid.get(getpidexe(pid), None) + gameuid = findgameuidofpath(getpidexe(pid), savehook_new_list) if gameuid: gobject.baseobject.textsource.gameuid = gameuid self.isbindedwindow = pid != _pid @@ -1008,13 +1020,31 @@ class QUnFrameWindow(resizableframeless): self.buttons[name] = button def tryremoveuseless(self): + try: + allisremoved = True + tmpbase = gobject.gettempdir_1() + for f in os.listdir(tmpbase): + try: + pid = int(f) + except: + continue + if (pid != os.getpid()) and (winsharedutils.pid_running(pid)): + allisremoved = False + continue - try: - shutil.rmtree(gobject.gettempdir('')) - except: - pass - try: - os.remove("./cache/Updater.exe") + try: + shutil.rmtree(os.path.join(tmpbase, f)) + except: + pass + if allisremoved: + try: + shutil.rmtree(tmpbase) + except: + pass + try: + os.remove("./cache/Updater.exe") + except: + pass except: pass diff --git a/LunaTranslator/LunaTranslator/metadata/bangumi.py b/LunaTranslator/LunaTranslator/metadata/bangumi.py index 282d52b6..936faa49 100644 --- a/LunaTranslator/LunaTranslator/metadata/bangumi.py +++ b/LunaTranslator/LunaTranslator/metadata/bangumi.py @@ -71,7 +71,7 @@ class bgmsettings(QDialog): if vid in collect: gameuid = collect[vid] else: - gameuid = initanewitem(f"bgm_{vid}_{time.time()}", title) + gameuid = initanewitem(title) savehook_new_data[gameuid][self._ref.idname] = vid gamdidchangedtask(self._ref.typename, self._ref.idname, gameuid) reflist.insert(0, gameuid) @@ -203,9 +203,8 @@ class searcher(common): vndbtags = [_["name"] for _ in response["tags"]] developers = [] for _ in response["infobox"]: - if _["key"] == "游戏开发商": - developers = [_["value"]] - break + if _["key"] in ["游戏开发商", "开发", "发行"]: + developers += [_["value"]] return { # "namemap": namemap, "title": response["name"], diff --git a/LunaTranslator/LunaTranslator/metadata/steam.py b/LunaTranslator/LunaTranslator/metadata/steam.py index 17885c45..6c063ae1 100644 --- a/LunaTranslator/LunaTranslator/metadata/steam.py +++ b/LunaTranslator/LunaTranslator/metadata/steam.py @@ -72,7 +72,7 @@ class steamsettings(QDialog): if vid in collect: gameuid = collect[vid] else: - gameuid = initanewitem(f"steam_{vid}_{time.time()}", title) + gameuid = initanewitem(title) savehook_new_data[gameuid][self._ref.idname] = vid gamdidchangedtask(self._ref.typename, self._ref.idname, gameuid) reflist.insert(0, gameuid) diff --git a/LunaTranslator/LunaTranslator/metadata/vndb.py b/LunaTranslator/LunaTranslator/metadata/vndb.py index 052211c5..cc0f18ad 100644 --- a/LunaTranslator/LunaTranslator/metadata/vndb.py +++ b/LunaTranslator/LunaTranslator/metadata/vndb.py @@ -232,7 +232,7 @@ class vndbsettings(QDialog): if vid in collect: gameuid = collect[vid] else: - gameuid = initanewitem(f"vndb_{vid}_{time.time()}", title) + gameuid = initanewitem(title) savehook_new_data[gameuid][self._ref.idname] = vid gamdidchangedtask(self._ref.typename, self._ref.idname, gameuid) reflist.insert(0, gameuid) diff --git a/LunaTranslator/LunaTranslator/myutils/config.py b/LunaTranslator/LunaTranslator/myutils/config.py index e5a62582..cf2c27c9 100644 --- a/LunaTranslator/LunaTranslator/myutils/config.py +++ b/LunaTranslator/LunaTranslator/myutils/config.py @@ -52,11 +52,11 @@ if _savehook: savehook_new_list = _savehook[0] savehook_new_data = _savehook[1] savegametaged = _savehook[2] - gamepath2uid = _savehook[3] + # gamepath2uid = _savehook[3] 不再使用,允许重复的path else: _savehook = tryreadconfig("savehook_new_1.39.4.json", default=[[], {}]) - + # savehook_new_list: [gamepath,...] # savehook_new_data:{gamepath:dict,...} # savegametaged: 可能没有该项 [ None, {'games':[gamepath,...],'title':str,'opened':bool,'uid':str},...] @@ -73,23 +73,23 @@ else: savegametaged = [None] # 将savehook_new_data转换为新的格式 - gamepath2uid = {} + __gamepath2uid = {} __savehook_new_data = {} for k in savehook_new_data: uid = f"{time.time()}_{uuid.uuid4()}" __savehook_new_data[uid] = savehook_new_data[k] __savehook_new_data[uid].update(gamepath=k) - gamepath2uid[k] = uid + __gamepath2uid[k] = uid savehook_new_data = __savehook_new_data # 将global游戏表和自定义子列表都转换成新格式 def parselist(ls): for i in range(len(ls)): ori = ls[i] - if ori not in gamepath2uid: + if ori not in __gamepath2uid: continue - ls[i] = gamepath2uid[ori] + ls[i] = __gamepath2uid[ori] parselist(savehook_new_list) for sub in savegametaged: @@ -100,9 +100,9 @@ translatorsetting = tryreadconfig("translatorsetting.json") ocrsetting = tryreadconfig("ocrsetting.json") -def getdefaultsavehook(gamepath, title=None): +def getdefaultsavehook(title=None): default = { - # "gamepath": gamepath, + "gamepath": "", # 不要直接访问,要通过uid2gamepath来间接访问 "hooksetting_follow_default": True, "hooksetting_private": {}, # 显示时再加载,缺省用global中的键 "textproc_follow_default": True, @@ -167,12 +167,6 @@ def getdefaultsavehook(gamepath, title=None): } if title and len(title): default["title"] = title # metadata - else: - default["title"] = ( - os.path.basename(os.path.dirname(gamepath)) - + "/" - + os.path.basename(gamepath) - ) return default @@ -205,6 +199,34 @@ class __uid2gamepath: uid2gamepath = __uid2gamepath() +def findgameuidofpath(gamepath, targetlist=None, findall=False): + # 一般只在save_game_list里查找,用于从getpidexe获取uid + # 因为有可能有过去的不再使用的uid,发生碰撞。 + # 只在添加游戏时,全面查找。 + if not gamepath: + if findall: + return [] + else: + return None + # 遍历的速度非常快,1w条的速度也就0.001x秒 + # 但1w条数据时,load/dump的速度就有点慢了,能2秒多 + + checkin = targetlist + if checkin is None: + checkin = savehook_new_data.keys() + collect = [] + for uid in checkin: + if savehook_new_data[uid]["gamepath"] == gamepath: + if findall: + collect.append(uid) + else: + return uid + if findall: + return collect + else: + return None + + def syncconfig(config1, default, drop=False, deep=0, skipdict=False): for key in default: @@ -404,11 +426,15 @@ def _TRL(kk): return x -def safesave(fname, js): +def safesave(fname, js, beatiful=True): # 有时保存时意外退出,会导致config文件被清空 os.makedirs("./userconfig", exist_ok=True) with open(fname + ".tmp", "w", encoding="utf-8") as ff: - ff.write(json.dumps(js, ensure_ascii=False, sort_keys=False, indent=4)) + if beatiful: + ff.write(json.dumps(js, ensure_ascii=False, sort_keys=False, indent=4)) + else: + # savegamedata 1w条时,indent=4要2秒,不indent 0.37秒,不ensure_ascii 0.27秒,用不着数据库了 + ff.write(json.dumps(js, sort_keys=False)) if os.path.exists(fname): os.remove(fname) os.rename(fname + ".tmp", fname) @@ -426,7 +452,8 @@ def saveallconfig(): safesave("./userconfig/ocrsetting.json", ocrsetting) safesave( "./userconfig/savegamedata_5.3.1.json", - [savehook_new_list, savehook_new_data, savegametaged, gamepath2uid], + [savehook_new_list, savehook_new_data, savegametaged, None], + beatiful=False, ) safesave( "./files/lang/{}.json".format(getlanguse()), diff --git a/LunaTranslator/LunaTranslator/myutils/hwnd.py b/LunaTranslator/LunaTranslator/myutils/hwnd.py index d3d39d1f..600a0a99 100644 --- a/LunaTranslator/LunaTranslator/myutils/hwnd.py +++ b/LunaTranslator/LunaTranslator/myutils/hwnd.py @@ -84,25 +84,33 @@ def getprocesslist(): def getpidexe(pid): hwnd1 = windows.AutoHandle( - windows.OpenProcess(windows.PROCESS_ALL_ACCESS, False, (pid)) + windows.OpenProcess(windows.PROCESS_ALL_ACCESS, False, pid) ) - if hwnd1 == 0: + if not hwnd1: hwnd1 = windows.OpenProcess( - windows.PROCESS_QUERY_LIMITED_INFORMATION, False, (pid) + windows.PROCESS_QUERY_LIMITED_INFORMATION, False, pid ) - if hwnd1 == 0: + if not hwnd1: name_ = None else: name_ = windows.GetProcessFileName(hwnd1) return name_ -def testprivilege(pid): - hwnd1 = windows.AutoHandle( - windows.OpenProcess(windows.PROCESS_INJECT_ACCESS, False, (pid)) +def test_injectable_1(pid): + return bool( + windows.AutoHandle( + windows.OpenProcess(windows.PROCESS_INJECT_ACCESS, False, pid) + ) ) - return hwnd1 != 0 + + +def test_injectable(pids): + for pid in pids: + if not test_injectable_1(pid): + return False + return True def ListProcess(filt=True): @@ -128,18 +136,13 @@ def ListProcess(filt=True): pass kv = {} for pid, exe in ret: - if exe in kv: - kv[exe]["pid"].append(pid) - else: - kv[exe] = {"pid": [pid]} - # for exe in kv: - # if len(kv[exe]['pid'])>1: - # mems=[getprocessmem(_) for _ in kv[exe]['pid']] - # _i=argsort(mems) - # kv[exe]['pid']=[kv[exe]['pid'][_i[-1]]] + if exe not in kv: + kv[exe] = [] + + kv[exe].append(pid) xxx = [] for exe in kv: - xxx.append([kv[exe]["pid"], exe]) + xxx.append([kv[exe], exe]) return xxx @@ -184,28 +187,26 @@ def getExeIcon(name, icon=True, cache=False): def injectdll(injectpids, injecter, dll): pid = " ".join([str(_) for _ in injectpids]) - if any(map(testprivilege, injectpids)) == False: - windows.ShellExecute( - 0, - "runas", - injecter, - 'dllinject {} "{}"'.format(pid, dll), - None, - windows.SW_HIDE, - ) - else: + for _ in (0,): + if not test_injectable(injectpids): + break + ret = subprocess.run( '"{}" dllinject {} "{}"'.format(injecter, pid, dll) ).returncode - if ret == 0: - windows.ShellExecute( - 0, - "runas", - injecter, - 'dllinject {} "{}"'.format(pid, dll), - None, - windows.SW_HIDE, - ) + if ret: + return + pids = winsharedutils.collect_running_pids(injectpids) + pid = " ".join([str(_) for _ in pids]) + + windows.ShellExecute( + 0, + "runas", + injecter, + 'dllinject {} "{}"'.format(pid, dll), + None, + windows.SW_HIDE, + ) def mouseselectwindow(callback): diff --git a/LunaTranslator/LunaTranslator/myutils/post.py b/LunaTranslator/LunaTranslator/myutils/post.py index 7b0c25b4..9ab33210 100644 --- a/LunaTranslator/LunaTranslator/myutils/post.py +++ b/LunaTranslator/LunaTranslator/myutils/post.py @@ -1,8 +1,8 @@ import re, codecs, inspect from traceback import print_exc from collections import Counter -import importlib, gobject -from myutils.utils import getfilemd5, LRUCache, getlangsrc +import gobject +from myutils.utils import checkchaos, checkmd5reloadmodule, LRUCache, getlangsrc from myutils.config import ( postprocessconfig, globalconfig, @@ -322,9 +322,6 @@ def lines_threshold(line, args): return line -from myutils.utils import checkchaos - - def _remove_chaos(line): newline = "" for c in line: @@ -334,12 +331,16 @@ def _remove_chaos(line): return newline -_selfdefpost = None -_selfdefpostmd5 = None +def _mypostloader(line, file, module): + + isnew, _ = checkmd5reloadmodule(file, module) + # 这个是单独函数的模块,不需要用isnew来判断是否需要重新初始化 + if not _: + return line + return _.POSTSOLVE(line) def POSTSOLVE(line): - global _selfdefpostmd5, _selfdefpost if line == "": return "" functions = { @@ -367,6 +368,7 @@ def POSTSOLVE(line): "dedump": dedump, "length_threshold": length_threshold, "lines_threshold": lines_threshold, + "_11": _mypostloader, } useranklist = globalconfig["postprocess_rank"] usedpostprocessconfig = postprocessconfig @@ -394,22 +396,6 @@ def POSTSOLVE(line): ) except: print_exc() - try: - md5 = getfilemd5(usemypostpath) - if md5 != _selfdefpostmd5: - _ = importlib.import_module(usemodule) - _ = importlib.reload(_) - _selfdefpostmd5 = md5 - _selfdefpost = _ - else: - _ = _selfdefpost - functions.update({"_11": _.POSTSOLVE}) - except ModuleNotFoundError: - pass - except: - print_exc() - pass - for postitem in useranklist: if postitem not in functions: continue @@ -418,20 +404,20 @@ def POSTSOLVE(line): if usedpostprocessconfig[postitem]["use"]: try: _f = functions[postitem] - - sig = inspect.signature(_f) - np = len(sig.parameters) - if np == 1: - line = functions[postitem](line) - elif np == 2: - line = functions[postitem]( - line, usedpostprocessconfig[postitem].get("args", {}) - ) - else: - raise Exception("unsupported parameters num") - - except Exception as e: - print_exc() if postitem == "_11": - raise e + line = functions[postitem](line, usemypostpath, usemodule) + else: + sig = inspect.signature(_f) + np = len(sig.parameters) + if np == 1: + line = functions[postitem](line) + elif np == 2: + line = functions[postitem]( + line, usedpostprocessconfig[postitem].get("args", {}) + ) + else: + raise Exception("unsupported parameters num") + + except: + print_exc() return line diff --git a/LunaTranslator/LunaTranslator/myutils/utils.py b/LunaTranslator/LunaTranslator/myutils/utils.py index 915e748f..27d010a7 100644 --- a/LunaTranslator/LunaTranslator/myutils/utils.py +++ b/LunaTranslator/LunaTranslator/myutils/utils.py @@ -13,9 +13,9 @@ from myutils.config import ( globalconfig, static_data, getlanguse, - savehook_new_data, uid2gamepath, - gamepath2uid, + savehook_new_data, + findgameuidofpath, getdefaultsavehook, ) from ctypes import c_float, pointer, c_void_p @@ -127,9 +127,6 @@ class PriorityQueue: return bool(len(self._heap) == 0) -searchvndbqueue = PriorityQueue() - - def guessmaybetitle(gamepath, title): __t = [] @@ -167,14 +164,20 @@ def guessmaybetitle(gamepath, title): targetmod = {} -def trysearchforid(gameuid, searchargs: list): +def dispatchsearchfordata(gameuid, target, vid): + targetmod[target].dispatchsearchfordata(gameuid, vid) + + +def trysearchforid_1(gameuid, searchargs: list): infoid = None primitivtemetaorigin = globalconfig["primitivtemetaorigin"] - __ = list(targetmod.keys()) - if primitivtemetaorigin not in __: - primitivtemetaorigin = __[0] - __.remove(primitivtemetaorigin) - __.insert(0, primitivtemetaorigin) + __ = [primitivtemetaorigin] + for k in targetmod: + if k == primitivtemetaorigin: + continue + if not globalconfig["metadata"][k]["auto"]: + continue + __.append(k) for key in __: vid = None @@ -195,28 +198,15 @@ def trysearchforid(gameuid, searchargs: list): if key == primitivtemetaorigin: break if infoid: - searchvndbqueue.put((1, gameuid, infoid)) - return infoid + key, vid = infoid + dispatchsearchfordata(gameuid, key, vid) + gobject.baseobject.translation_ui.displayglobaltooltip.emit( + f"{key}: found {vid}" + ) -def everymethodsthread(): - while True: - _ = searchvndbqueue.get() - _type, gameuid, arg = _ - try: - if _type == 0: - infoid = trysearchforid(gameuid, arg) - key, vid = infoid - gobject.baseobject.translation_ui.displayglobaltooltip.emit( - f"{key}: found {vid}" - ) - - elif _type == 1: - key, vid = arg - targetmod[key].dispatchsearchfordata(gameuid, vid) - - except: - print_exc() +def trysearchforid(gameuid, searchargs: list): + threading.Thread(target=trysearchforid_1, args=(gameuid, searchargs)).start() def idtypecheck(key, idname, gameuid, vid): @@ -237,30 +227,43 @@ def idtypecheck(key, idname, gameuid, vid): def gamdidchangedtask(key, idname, gameuid): vid = savehook_new_data[gameuid][idname] - searchvndbqueue.put((1, gameuid, (key, vid)), 1) + dispatchsearchfordata(gameuid, key, vid) def titlechangedtask(gameuid, title): savehook_new_data[gameuid]["title"] = title savehook_new_data[gameuid]["istitlesetted"] = True - searchvndbqueue.put((0, gameuid, [title]), 1) + trysearchforid(gameuid, [title]) -def initanewitem(gamepath, title): +def initanewitem(title): uid = f"{time.time()}_{uuid.uuid4()}" - gamepath2uid[gamepath] = uid - savehook_new_data[uid] = getdefaultsavehook(gamepath, title) - uid2gamepath[uid] = gamepath + savehook_new_data[uid] = getdefaultsavehook(title) return uid def checkifnewgame(targetlist, gamepath, title=None): - if gamepath not in gamepath2uid: - uid = initanewitem(gamepath, title) - searchvndbqueue.put((0, uid, [title] + guessmaybetitle(gamepath, title))) + # 用于添加游戏时,全局查找是否有过历史记录 + uids = findgameuidofpath(gamepath, findall=True) + print(uids) + if len(uids) == 0: + uid = initanewitem(title) + if title is None: + savehook_new_data[uid]["title"] = ( + os.path.basename(os.path.dirname(gamepath)) + + "/" + + os.path.basename(gamepath) + ) + uid2gamepath[uid] = gamepath + trysearchforid(uid, [title] + guessmaybetitle(gamepath, title)) + isnew = True else: - uid = gamepath2uid[gamepath] - isnew = uid not in targetlist + isnew = True + for uid in uids: + if uid in targetlist: + isnew = False + break + if isnew: targetlist.insert(0, uid) return uid @@ -414,7 +417,10 @@ class Process: pass """ ) - os.startfile(p) + # os.startfile(p) + threading.Thread( + target=os.system, args=(f'notepad "{os.path.normpath(p)}"',) + ).start() return p @@ -619,24 +625,11 @@ def checkpostusing(name): return use and checkpostlangmatch(name) -def getpostfile(name): - if name == "myprocess": - mm = "myprocess" - checkpath = "./userconfig/myprocess.py" - else: - mm = "transoptimi." + name - checkpath = "./LunaTranslator/transoptimi/" + name + ".py" +def loadpostsettingwindowmethod(name): + checkpath = "./LunaTranslator/transoptimi/" + name + ".py" if os.path.exists(checkpath) == False: return None - return mm - - -def loadpostsettingwindowmethod(name): - if name == "myprocess": - return lambda _: selectdebugfile("./userconfig/myprocess.py") - mm = getpostfile(name) - if not mm: - return None + mm = "transoptimi." + name try: Process = importlib.import_module(mm).Process @@ -739,5 +732,29 @@ for k in globalconfig["metadata"]: except: print_exc() +globalcachedmodule = {} -threading.Thread(target=everymethodsthread).start() + +def checkmd5reloadmodule(filename, module): + if not os.path.exists(filename): + # reload重新加载不存在的文件时不会报错。 + return True, None + key = (filename, module) + md5 = getfilemd5(filename) + cachedmd5 = globalcachedmodule.get(key, {}).get("md5", None) + if md5 != cachedmd5: + try: + _ = importlib.import_module(module) + _ = importlib.reload(_) + except ModuleNotFoundError: + return True, None + # 不要捕获其他错误,缺少模块时直接跳过,只报实现错误 + # except: + # print_exc() + # return True, None + globalcachedmodule[key] = {"md5": md5, "module": _} + + return True, _ + else: + + return False, globalcachedmodule.get(key, {}).get("module", None) diff --git a/LunaTranslator/LunaTranslator/textsource/texthook.py b/LunaTranslator/LunaTranslator/textsource/texthook.py index cb05095f..c8cbd813 100644 --- a/LunaTranslator/LunaTranslator/textsource/texthook.py +++ b/LunaTranslator/LunaTranslator/textsource/texthook.py @@ -8,9 +8,10 @@ from winsharedutils import Is64bit from myutils.config import globalconfig, savehook_new_data, static_data from textsource.textsourcebase import basetext from myutils.utils import checkchaos -from myutils.hwnd import injectdll +from myutils.hwnd import injectdll, test_injectable from myutils.wrapper import threader from myutils.utils import getfilemd5 +from traceback import print_exc from ctypes import ( CDLL, @@ -151,6 +152,7 @@ class texthook(basetext): gobject.baseobject.hookselectdialog.realshowhide.emit(True) self.delaycollectallselectedoutput() self.declare() + self.prepares() def checkmd5prefix(self, gamepath): md5 = getfilemd5(gamepath) @@ -229,7 +231,7 @@ class texthook(basetext): self.Luna_FreePtr(ws) return string - def Luna_Startup(self): + def prepares(self): procs = [ ProcessEvent(self.onprocconnect), ProcessEvent(self.connectedpids.remove), @@ -243,15 +245,14 @@ class texthook(basetext): self.keepref += procs ptrs = [cast(_, c_void_p).value for _ in procs] self.Luna_Start(*ptrs) - - def start(self): - - self.Luna_Startup() self.setsettings() + def start_unsafe(self): + + caninject = test_injectable(self.pids) injectpids = [] for pid in self.pids: - if self.config["use_yapi"]: + if caninject and self.config["use_yapi"]: self.Luna_Inject(pid, os.path.abspath("./files/plugins/LunaHook")) else: if self.Luna_CreatePipeAndCheck(pid): @@ -264,9 +265,17 @@ class texthook(basetext): dll = os.path.abspath( "./files/plugins/LunaHook/LunaHook{}.dll".format(arch) ) - # subprocess.Popen('"{}" dllinject {} "{}"'.format(injecter,pid,dll)) injectdll(injectpids, injecter, dll) + def start(self): + try: + self.start_unsafe() + except: + print_exc() + gobject.baseobject.translation_ui.displaymessagebox.emit( + "错误", "权限不足,请以管理员权限运行!" + ) + def onprocconnect(self, pid): self.connectedpids.append(pid) time.sleep(savehook_new_data[self.gameuid]["inserthooktimeout"] / 1000) diff --git a/LunaTranslator/LunaTranslator/translator/selfbuild.py b/LunaTranslator/LunaTranslator/translator/selfbuild.py new file mode 100644 index 00000000..96dfbc79 --- /dev/null +++ b/LunaTranslator/LunaTranslator/translator/selfbuild.py @@ -0,0 +1,27 @@ +from translator.basetranslator import basetrans +from myutils.utils import checkmd5reloadmodule + + +class TS(basetrans): + def mayreinit(self): + isnew, module = checkmd5reloadmodule("./userconfig/selfbuild.py", "selfbuild") + if not isnew: + return + if module: + self.internal = module.TS("selfbuild") + + def inittranslator(self): + self.internal = None + self.mayreinit() + + def langmap(self): + self.mayreinit() + if not self.internal: + return {} + return self.internal.langmap() + + def translate(self, content): + self.mayreinit() + if not self.internal: + return "" + return self.internal.translate(content) diff --git a/LunaTranslator/LunaTranslator/transoptimi/myprocess.py b/LunaTranslator/LunaTranslator/transoptimi/myprocess.py new file mode 100644 index 00000000..615cb231 --- /dev/null +++ b/LunaTranslator/LunaTranslator/transoptimi/myprocess.py @@ -0,0 +1,31 @@ +from myutils.utils import selectdebugfile, checkmd5reloadmodule + + +class Process: + @staticmethod + def get_setting_window(parent_window): + return selectdebugfile("./userconfig/myprocess.py") + + def process_after(self, res, contenxt): + self.mayreinit() + if not self.internal: + return res + return self.internal.process_after(res, contenxt) + + def process_before(self, s): + + self.mayreinit() + if not self.internal: + return s, None + return self.internal.process_before(s) + + def __init__(self) -> None: + self.internal = None + self.mayreinit() + + def mayreinit(self): + isnew, module = checkmd5reloadmodule("./userconfig/myprocess.py", "myprocess") + if not isnew: + return + if module: + self.internal = module.Process() diff --git a/LunaTranslator/LunaTranslator/windows.py b/LunaTranslator/LunaTranslator/windows.py index acb3ac55..d0f1693e 100644 --- a/LunaTranslator/LunaTranslator/windows.py +++ b/LunaTranslator/LunaTranslator/windows.py @@ -900,6 +900,9 @@ def ScreenToClient(hwnd, x, y): return (P.x, P.y) +INVALID_HANDLE_VALUE = -1 + + class AutoHandle(HANDLE): def __new__(cls, value) -> None: instance = super().__new__(cls, value) @@ -909,6 +912,9 @@ class AutoHandle(HANDLE): if self: CloseHandle(self) + def __bool__(self): + return (self.value != INVALID_HANDLE_VALUE) and (self.value != None) + _MapVirtualKey = _user32.MapVirtualKeyW _MapVirtualKey.argtypes = UINT, UINT diff --git a/LunaTranslator/LunaTranslator/winsharedutils.py b/LunaTranslator/LunaTranslator/winsharedutils.py index 2560bf0e..58f62a7b 100644 --- a/LunaTranslator/LunaTranslator/winsharedutils.py +++ b/LunaTranslator/LunaTranslator/winsharedutils.py @@ -339,6 +339,16 @@ pid_running = utilsdll.pid_running pid_running.argtypes = (DWORD,) pid_running.restype = c_bool + +def collect_running_pids(pids): + _ = [] + for __ in pids: + if not pid_running(__): + continue + _.append(__) + return _ + + getpidhwndfirst = utilsdll.getpidhwndfirst getpidhwndfirst.argtypes = (DWORD,) getpidhwndfirst.restype = HWND diff --git a/LunaTranslator/files/defaultconfig/config.json b/LunaTranslator/files/defaultconfig/config.json index 8194f42f..770129ab 100644 --- a/LunaTranslator/files/defaultconfig/config.json +++ b/LunaTranslator/files/defaultconfig/config.json @@ -232,6 +232,7 @@ }, "metadata": { "vndb": { + "auto": true, "name": "vndb", "downloadtasks": [], "searchfordatatasks": [], @@ -243,6 +244,7 @@ } }, "dlsite": { + "auto": false, "name": "dlsite", "downloadtasks": [], "searchfordatatasks": [], @@ -250,6 +252,7 @@ "target": "dlsiteid" }, "bangumi": { + "auto": true, "name": "bangumi", "downloadtasks": [], "searchfordatatasks": [], @@ -261,6 +264,7 @@ } }, "fanza": { + "auto": false, "name": "FanzaGames", "downloadtasks": [], "searchfordatatasks": [], @@ -268,6 +272,7 @@ "target": "fanzaid" }, "steam": { + "auto": false, "name": "steam", "downloadtasks": [], "searchfordatatasks": [], diff --git a/LunaTranslator/files/lang/ar.json b/LunaTranslator/files/lang/ar.json index bc723e32..565ad063 100644 --- a/LunaTranslator/files/lang/ar.json +++ b/LunaTranslator/files/lang/ar.json @@ -485,7 +485,6 @@ "进程号": "رقم العملية", "最长翻译字数": "أقصى عدد من الكلمات المترجمة", "过滤控制字符": "تصفية السيطرة الشخصية", - "窗口名": "اسم النافذة", "法语": "الفرنسية .", "分词": "اسم الفاعل", "用户词典1": "قاموس المستخدم", @@ -716,7 +715,6 @@ "过滤历史重复": "تصفية التاريخ تكرار", "缓存条数": "عدد شرائط التخزين المؤقت", "腾讯OCR": "تينسنت التعرف الضوئي على الحروف", - "添加列表": "إضافة قائمة", "删除列表": "حذف قائمة", "上移": "رفع", "下移": "نزولا", @@ -813,5 +811,6 @@ "上传游戏": "تحميل العاب", "以当前md5复制选中行": "حدد صف مع نسخة MD5 الحالي", "修改列表名称": "تعديل اسم القائمة", - "滚动到最后": "انتقل إلى آخر" + "滚动到最后": "انتقل إلى آخر", + "创建列表": "إنشاء قائمة" } \ No newline at end of file diff --git a/LunaTranslator/files/lang/cht.json b/LunaTranslator/files/lang/cht.json index ce9ed9eb..f286b870 100644 --- a/LunaTranslator/files/lang/cht.json +++ b/LunaTranslator/files/lang/cht.json @@ -388,7 +388,6 @@ "错误": "錯誤", "所选文件格式错误!": "所選檔案格式錯誤!", "进程号": "行程號", - "窗口名": "視窗名", "无法识别的路径!": "無法識別的路徑!", "进程": "行程", "到进程": "到行程", @@ -716,7 +715,6 @@ "过滤历史重复": "過濾歷史重複", "缓存条数": "緩存條數", "腾讯OCR": "騰訊OCR", - "添加列表": "添加清單", "删除列表": "删除清單", "上移": "上移", "下移": "下移", @@ -813,5 +811,6 @@ "上传游戏": "上傳遊戲", "以当前md5复制选中行": "以當前md5複製選中行", "修改列表名称": "修改清單名稱", - "滚动到最后": "滾動到最後" + "滚动到最后": "滾動到最後", + "创建列表": "創建清單" } \ No newline at end of file diff --git a/LunaTranslator/files/lang/en.json b/LunaTranslator/files/lang/en.json index 436b01db..fecc507f 100644 --- a/LunaTranslator/files/lang/en.json +++ b/LunaTranslator/files/lang/en.json @@ -388,7 +388,6 @@ "错误": "Error", "所选文件格式错误!": "Invalid File Format Selected!", "进程号": "Process ID", - "窗口名": "Window name", "无法识别的路径!": "Unrecognizable Path!", "进程": "Process", "到进程": "Select Process", @@ -558,7 +557,6 @@ "点击单词复制": "Copy On Click", "窗口背景透明": "Window Background Transparency", "背景窗口透明": "Background Window Transparency", - "指定模式": "Specify Mode", "搜索范围": "Search Range", "搜索方式": "Search Method", "使用翻译缓存": "Use Translation Cache", @@ -716,7 +714,6 @@ "过滤历史重复": "Filter Historical Duplicates", "缓存条数": "Number of Cached Items", "腾讯OCR": "Tencent OCR", - "添加列表": "Add List", "删除列表": "Delete List", "上移": "Move Up", "下移": "Move Down", @@ -813,5 +810,7 @@ "上传游戏": "Upload Game", "以当前md5复制选中行": "Copy Selected Row with Current MD5", "修改列表名称": "Modify List Name", - "滚动到最后": "Scroll to End" -} + "滚动到最后": "Scroll to End", + "指定模块": "Specify modules", + "创建列表": "Create List" +} \ No newline at end of file diff --git a/LunaTranslator/files/lang/es.json b/LunaTranslator/files/lang/es.json index 7d9e828f..cb5127a4 100644 --- a/LunaTranslator/files/lang/es.json +++ b/LunaTranslator/files/lang/es.json @@ -388,7 +388,6 @@ "错误": "Error", "所选文件格式错误!": "¡¡ el archivo seleccionado tiene un formato incorrecto!", "进程号": "Número de proceso", - "窗口名": "Nombre de la ventana", "无法识别的路径!": "¡Caminos no reconocibles!", "进程": "Proceso", "到进程": "Al proceso", @@ -716,7 +715,6 @@ "过滤历史重复": "Filtrar repetición histórica", "缓存条数": "Número de barras de caché", "腾讯OCR": "Tencent OCR", - "添加列表": "Añadir lista", "删除列表": "Eliminar lista", "上移": "Subir", "下移": "Bajar", @@ -813,5 +811,6 @@ "上传游戏": "Sube el juego", "以当前md5复制选中行": "Copiar la línea seleccionada con el MD5 actual", "修改列表名称": "Modificar el nombre de la lista", - "滚动到最后": "Rodar hasta el final" + "滚动到最后": "Rodar hasta el final", + "创建列表": "Crear lista" } \ No newline at end of file diff --git a/LunaTranslator/files/lang/fr.json b/LunaTranslator/files/lang/fr.json index 0de47099..47ca8d2b 100644 --- a/LunaTranslator/files/lang/fr.json +++ b/LunaTranslator/files/lang/fr.json @@ -388,7 +388,6 @@ "错误": "Erreur", "所选文件格式错误!": "Mauvais format de fichier sélectionné!", "进程号": "Numéro de processus", - "窗口名": "Nom de la fenêtre", "无法识别的路径!": "Un chemin méconnaissable!", "进程": "Processus", "到进程": "Au processus", @@ -716,7 +715,6 @@ "过滤历史重复": "Filtrer historique répétition", "缓存条数": "Nombre de barres de cache", "腾讯OCR": "OCR Tencent", - "添加列表": "Ajouter une liste", "删除列表": "Supprimer une liste", "上移": "Déplacement vers le Haut", "下移": "Descendre", @@ -813,5 +811,6 @@ "上传游戏": "Télécharger un jeu", "以当前md5复制选中行": "Copier la ligne sélectionnée avec le MD5 actuel", "修改列表名称": "Modifier le nom de la Liste", - "滚动到最后": "Rouler jusqu'à la fin" + "滚动到最后": "Rouler jusqu'à la fin", + "创建列表": "Créer une liste" } \ No newline at end of file diff --git a/LunaTranslator/files/lang/it.json b/LunaTranslator/files/lang/it.json index 257e762f..2ca9d9a8 100644 --- a/LunaTranslator/files/lang/it.json +++ b/LunaTranslator/files/lang/it.json @@ -376,7 +376,6 @@ "错误": "errore", "所选文件格式错误!": "Il formato del file selezionato non è corretto!", "进程号": "Numero del processo", - "窗口名": "Nome finestra", "无法识别的路径!": "Percorso sconosciuto!", "进程": "processo", "到进程": "Da elaborare", @@ -716,7 +715,6 @@ "过滤历史重复": "Filtra duplicati storici", "缓存条数": "Numero di voci della cache", "腾讯OCR": "Tencent OCR", - "添加列表": "Aggiungi elenco", "删除列表": "Elimina elenco", "上移": "Sposta su", "下移": "Sposta giù", @@ -813,5 +811,6 @@ "上传游戏": "Carica gioco", "以当前md5复制选中行": "Copia la riga selezionata con l'MD5 corrente", "修改列表名称": "Modifica nome elenco", - "滚动到最后": "Scorri fino alla fine" + "滚动到最后": "Scorri fino alla fine", + "创建列表": "Crea elenco" } \ No newline at end of file diff --git a/LunaTranslator/files/lang/ja.json b/LunaTranslator/files/lang/ja.json index d4f02b69..46dccb07 100644 --- a/LunaTranslator/files/lang/ja.json +++ b/LunaTranslator/files/lang/ja.json @@ -388,7 +388,6 @@ "错误": "エラー", "所选文件格式错误!": "選択したファイルフォーマットが間違っています!", "进程号": "プロセス番号", - "窗口名": "ウィンドウ名", "无法识别的路径!": "認識できないパス!", "进程": "プロセス", "到进程": "プロセスへ", @@ -716,7 +715,6 @@ "过滤历史重复": "フィルタ履歴の繰り返し", "缓存条数": "キャッシュ・エントリ数", "腾讯OCR": "テンセントOCR", - "添加列表": "リストの追加", "删除列表": "リストの削除", "上移": "上へ移動", "下移": "下へ移動", @@ -813,5 +811,6 @@ "上传游戏": "ゲームをアップロード", "以当前md5复制选中行": "選択した行を現在のmd 5でコピー", "修改列表名称": "リスト名の変更", - "滚动到最后": "最後までスクロール" + "滚动到最后": "最後までスクロール", + "创建列表": "リストの作成" } \ No newline at end of file diff --git a/LunaTranslator/files/lang/ko.json b/LunaTranslator/files/lang/ko.json index 925bccf3..0acd12a1 100644 --- a/LunaTranslator/files/lang/ko.json +++ b/LunaTranslator/files/lang/ko.json @@ -388,7 +388,6 @@ "错误": "오류", "所选文件格式错误!": "선택한 파일의 형식이 잘못되었습니다!", "进程号": "프로세스 번호", - "窗口名": "창 이름", "无法识别的路径!": "인식할 수 없는 경로!", "进程": "프로세스", "到进程": "프로세스로", @@ -716,7 +715,6 @@ "过滤历史重复": "반복된 기록 필터링", "缓存条数": "캐시 바 수", "腾讯OCR": "텐센트 OCR", - "添加列表": "목록 추가", "删除列表": "목록 삭제", "上移": "위로 이동", "下移": "아래로 이동", @@ -813,5 +811,6 @@ "上传游戏": "게임 업로드", "以当前md5复制选中行": "선택된 행을 현재 md5로 복사", "修改列表名称": "목록 이름 수정", - "滚动到最后": "끝까지 스크롤" + "滚动到最后": "끝까지 스크롤", + "创建列表": "목록 만들기" } \ No newline at end of file diff --git a/LunaTranslator/files/lang/pl.json b/LunaTranslator/files/lang/pl.json index 2a9d9cde..568059f7 100644 --- a/LunaTranslator/files/lang/pl.json +++ b/LunaTranslator/files/lang/pl.json @@ -388,7 +388,6 @@ "错误": "błąd", "所选文件格式错误!": "Wybrany format pliku jest niepoprawny!", "进程号": "Numer procesu", - "窗口名": "Nazwa okna", "无法识别的路径!": "Nierozpoznana ścieżka!", "进程": "proces", "到进程": "Do przetwarzania", @@ -716,7 +715,6 @@ "过滤历史重复": "Filtruj duplikaty historyczne", "缓存条数": "Liczba wpisów pamięci podręcznej", "腾讯OCR": "Dziesięć OCR", - "添加列表": "Dodaj listę", "删除列表": "Usuń listę", "上移": "Przesuń się w górę", "下移": "Przesuń w dół", @@ -813,5 +811,6 @@ "上传游戏": "Przesyłaj grę", "以当前md5复制选中行": "Kopiuj zaznaczony wiersz z bieżącym MD5", "修改列表名称": "Zmień nazwę listy", - "滚动到最后": "Przewiń do końca" + "滚动到最后": "Przewiń do końca", + "创建列表": "Utwórz listę" } \ No newline at end of file diff --git a/LunaTranslator/files/lang/ru.json b/LunaTranslator/files/lang/ru.json index 83a94b4d..330df0a3 100644 --- a/LunaTranslator/files/lang/ru.json +++ b/LunaTranslator/files/lang/ru.json @@ -388,7 +388,6 @@ "错误": "Ошибка", "所选文件格式错误!": "Ошибка формата выбранного файла!", "进程号": "Номер процесса", - "窗口名": "Имя окна", "无法识别的路径!": "Невозможно определить путь!", "进程": "Процесс", "到进程": "К процессу", @@ -716,7 +715,6 @@ "过滤历史重复": "Фильтровать повторение истории", "缓存条数": "Количество кэшированных записей", "腾讯OCR": "Скачать OCR", - "添加列表": "Добавить список", "删除列表": "Удалить список", "上移": "Переместить вверх", "下移": "Переместить вниз", @@ -813,5 +811,6 @@ "上传游戏": "Загрузить игру", "以当前md5复制选中行": "Копировать выделенную строку в текущем MD5", "修改列表名称": "Изменить имя списка", - "滚动到最后": "Прокрутить до конца" + "滚动到最后": "Прокрутить до конца", + "创建列表": "Создать список" } \ No newline at end of file diff --git a/LunaTranslator/files/lang/th.json b/LunaTranslator/files/lang/th.json index d4ed7f68..ef88b270 100644 --- a/LunaTranslator/files/lang/th.json +++ b/LunaTranslator/files/lang/th.json @@ -59,7 +59,6 @@ "插值算法": "อัลกอริทึมการแทรก", "显示帧率": "แสดงอัตราเฟรม", "最新版本": "รุ่นล่าสุด", - "窗口名": "ชื่อหน้าต่าง", "搜索": "ค้นหา", "游戏信息": "ข้อมูลเกม", "特殊码": "รหัสพิเศษ", @@ -716,7 +715,6 @@ "过滤历史重复": "ประวัติการกรอง ทำซ้ำ", "缓存条数": "จำนวนแถบแคช", "腾讯OCR": "Tencent โอซีอาร์", - "添加列表": "เพิ่มรายการ", "删除列表": "ลบรายการ", "上移": "เลื่อนขึ้น", "下移": "เลื่อนลง", @@ -813,5 +811,6 @@ "上传游戏": "อัปโหลดเกม", "以当前md5复制选中行": "คัดลอกแถวที่เลือกด้วย md5 ปัจจุบัน", "修改列表名称": "แก้ไขชื่อรายการ", - "滚动到最后": "เลื่อนไปจนสุด" + "滚动到最后": "เลื่อนไปจนสุด", + "创建列表": "สร้างรายการ" } \ No newline at end of file diff --git a/LunaTranslator/files/lang/tr.json b/LunaTranslator/files/lang/tr.json index 72636bdd..a7fae22f 100644 --- a/LunaTranslator/files/lang/tr.json +++ b/LunaTranslator/files/lang/tr.json @@ -388,7 +388,6 @@ "错误": "hata", "所选文件格式错误!": "Seçili dosya format ı yanlış!", "进程号": "İşlem numarası", - "窗口名": "Pencere İsmi", "无法识别的路径!": "Bilinmeyen yol!", "进程": "işlem", "到进程": "İşleme", @@ -716,7 +715,6 @@ "过滤历史重复": "Tarihi çizgileri sil", "缓存条数": "Cache girişlerinin sayısı", "腾讯OCR": "Tencent OCR", - "添加列表": "Liste Ekle", "删除列表": "Listeyi sil", "上移": "Yukarı Taşı", "下移": "Aşağı taşın", @@ -813,5 +811,6 @@ "上传游戏": "Oyunu yükle", "以当前md5复制选中行": "Seçili satırı mevcut MD5 ile kopyalayın", "修改列表名称": "Liste ismini değiştir", - "滚动到最后": "Sonuna doğru yürüt" + "滚动到最后": "Sonuna doğru yürüt", + "创建列表": "Liste oluştur" } \ No newline at end of file diff --git a/LunaTranslator/files/lang/uk.json b/LunaTranslator/files/lang/uk.json index bb16d207..e64978a8 100644 --- a/LunaTranslator/files/lang/uk.json +++ b/LunaTranslator/files/lang/uk.json @@ -376,7 +376,6 @@ "错误": "помилка", "所选文件格式错误!": "Вибраний формат файла неправильний!", "进程号": "Номер процесу", - "窗口名": "Назва вікна", "无法识别的路径!": "Нерозпізнаний шлях!", "进程": "процес", "到进程": "Процес", @@ -716,7 +715,6 @@ "过滤历史重复": "Фільтрувати історичні дублікати", "缓存条数": "Кількість записів кешу", "腾讯OCR": "Похильний OCR", - "添加列表": "Додати список", "删除列表": "Вилучити список", "上移": "Пересунути вгору", "下移": "Пересунути вниз", @@ -813,5 +811,6 @@ "上传游戏": "Вивантажити гру", "以当前md5复制选中行": "Копіювати вибраний рядок поточним MD5", "修改列表名称": "Змінити назву списку", - "滚动到最后": "Пересунутися до кінця" + "滚动到最后": "Пересунутися до кінця", + "创建列表": "Створити список" } \ No newline at end of file diff --git a/LunaTranslator/files/lang/vi.json b/LunaTranslator/files/lang/vi.json index b79af6c7..86cf87d5 100644 --- a/LunaTranslator/files/lang/vi.json +++ b/LunaTranslator/files/lang/vi.json @@ -388,7 +388,6 @@ "错误": "Lỗi", "所选文件格式错误!": "Lỗi định dạng tập tin đã chọn!", "进程号": "Số tiến trình", - "窗口名": "Tên cửa sổ", "无法识别的路径!": "Đường không nhận ra!", "进程": "Quy trình", "到进程": "Tiến trình", @@ -716,7 +715,6 @@ "过滤历史重复": "Lọc lịch sử lặp lại", "缓存条数": "Số thanh bộ nhớ cache", "腾讯OCR": "Thông tin OCR", - "添加列表": "Thêm danh sách", "删除列表": "Xoá danh sách", "上移": "Di chuyển lên", "下移": "Di chuyển xuống", @@ -813,5 +811,6 @@ "上传游戏": "Tải lên trò chơi", "以当前md5复制选中行": "Dòng đã chọn sao chép md5 hiện tại", "修改列表名称": "Thay đổi tên danh sách", - "滚动到最后": "Cuộn đến cuối" + "滚动到最后": "Cuộn đến cuối", + "创建列表": "Tạo danh sách" } \ No newline at end of file diff --git a/LunaTranslator/files/lang/zh.json b/LunaTranslator/files/lang/zh.json index 51ff193c..a39f67db 100644 --- a/LunaTranslator/files/lang/zh.json +++ b/LunaTranslator/files/lang/zh.json @@ -60,7 +60,6 @@ "插值算法": "", "显示帧率": "", "最新版本": "", - "窗口名": "", "搜索": "", "游戏信息": "", "特殊码": "", @@ -724,7 +723,7 @@ "过滤历史重复": "", "缓存条数": "", "腾讯OCR": "", - "添加列表": "", + "创建列表": "", "删除列表": "", "上移": "", "下移": "", diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 9c8fda08..06cfa5af 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -28,7 +28,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/version) include(generate_product_version) set(VERSION_MAJOR 5) -set(VERSION_MINOR 5) +set(VERSION_MINOR 6) set(VERSION_PATCH 0) add_library(pch pch.cpp) diff --git a/plugins/winsharedutils/hwnd.cpp b/plugins/winsharedutils/hwnd.cpp index d11ed58a..f710f530 100644 --- a/plugins/winsharedutils/hwnd.cpp +++ b/plugins/winsharedutils/hwnd.cpp @@ -55,7 +55,9 @@ DECLARE void recoverwindow(HWND hwnd, windowstatus status) DECLARE bool pid_running(DWORD pid) { DWORD code; - GetExitCodeProcess(AutoHandle(OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid)), &code); + GetExitCodeProcess(AutoHandle(OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid)), &code); + // 句柄必須具有 PROCESS_QUERY_INFORMATION 或 PROCESS_QUERY_LIMITED_INFORMATION 訪問許可權。 如需詳細資訊,請參閱 處理安全性和訪問許可權。 + // Windows Server 2003 和 Windows XP: 句柄必須具有 PROCESS_QUERY_INFORMATION 訪問許可權。 return code == STILL_ACTIVE; // auto process = AutoHandle(OpenProcess(SYNCHRONIZE, FALSE, pid)); // DWORD ret = WaitForSingleObject(process, 0); @@ -95,7 +97,9 @@ DECLARE bool Is64bit(DWORD pid) GetNativeSystemInfo(&sysinfo); if (sysinfo.wProcessorArchitecture == 9 || sysinfo.wProcessorArchitecture == 6) { - auto hprocess = AutoHandle(OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid)); + auto hprocess = AutoHandle(OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid)); + // 進程的控制碼。 控制碼必須具有PROCESS_QUERY_INFORMATION或PROCESS_QUERY_LIMITED_INFORMATION存取權限。 如需詳細資訊,請參閱 處理安全性和存取權限。 + // Windows Server 2003 和 Windows XP: 控制碼必須具有PROCESS_QUERY_INFORMATION存取權限。 BOOL b; IsWow64Process(hprocess, &b); return !b;