This commit is contained in:
恍兮惚兮 2025-01-13 09:24:09 +08:00
parent 58019754fd
commit c0b800111b
20 changed files with 126 additions and 182 deletions

View File

@ -1,7 +1,7 @@
set(VERSION_MAJOR 6)
set(VERSION_MINOR 20)
set(VERSION_PATCH 1)
set(VERSION_PATCH 2)
set(VERSION_REVISION 0)
set(LUNA_VERSION "{${VERSION_MAJOR},${VERSION_MINOR},${VERSION_PATCH},${VERSION_REVISION}}")
add_library(VERSION_DEF ${CMAKE_CURRENT_LIST_DIR}/version_def.cpp)

View File

@ -190,4 +190,29 @@ DECLARE_API void GetSelectedText(void (*cb)(const wchar_t *))
DECLARE_API void *get_allAccess_ptr()
{
return &allAccess;
}
DECLARE_API HANDLE createprocess(LPCWSTR command, LPCWSTR path, DWORD *pid)
{
// 防止进程意外退出时,子进程僵死
std::wstring _ = command;
STARTUPINFO si = {sizeof(si)};
si.dwFlags |= STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
PROCESS_INFORMATION pi;
HANDLE hJob = CreateJobObject(NULL, NULL);
if (!hJob)
return NULL;
if (!CreateProcessW(NULL, _.data(), NULL, NULL, FALSE, 0, NULL, path, &si, &pi))
return NULL;
CHandle _1{pi.hProcess}, _2{pi.hThread};
*pid = pi.dwProcessId;
if (!AssignProcessToJobObject(hJob, pi.hProcess))
return NULL;
// 设置Job Object选项使父进程退出时子进程自动终止
JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = {0};
jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
if (!SetInformationJobObject(hJob, JobObjectExtendedLimitInformation, &jeli, sizeof(jeli)))
return NULL;
// closehandle会关闭子进程
return hJob;
}

View File

@ -11,7 +11,6 @@ from myutils.config import (
savehook_new_list,
)
from gui.dialog_savedgame import dialog_setting_game
from myutils.subproc import endsubprocs
from myutils.ocrutil import ocr_run, imageCut
from myutils.utils import (
loadpostsettingwindowmethod,
@ -1439,7 +1438,6 @@ class TranslatorWindow(resizableframeless):
self.hide()
gobject.baseobject.textsource = None
endsubprocs()
gobject.baseobject.destroytray()
handle = windows.CreateMutex(False, "LUNASAVECONFIGUPDATE")
if windows.GetLastError() != windows.ERROR_ALREADY_EXISTS:

View File

@ -271,3 +271,21 @@ def gdi_screenshot(x1, y1, x2, y2, hwnd=None):
def winrt_capture_window(hwnd):
bs = winrtutils.winrt_capture_window(hwnd)
return safepixmap(bs)
def subprochiderun(cmd, cwd=None, encoding='utf8') -> subprocess.CompletedProcess:
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
startupinfo.wShowWindow = subprocess.SW_HIDE
ss = subprocess.run(
cmd,
cwd=cwd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
startupinfo=startupinfo,
encoding=encoding,
)
return ss

View File

@ -1,61 +0,0 @@
from traceback import print_exc
import subprocess
allsubprocess2 = {}
class autoproc:
def __init__(self, proc: subprocess.Popen) -> None:
self.proc = proc
def __del__(self):
try:
self.proc.kill()
except:
pass
def subproc_w(
cmd, cwd=None, needstdio=False, name=None, encoding=None, run=False
) -> subprocess.Popen:
_pipe = subprocess.PIPE if needstdio else None
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
startupinfo.wShowWindow = subprocess.SW_HIDE
if name and name in allsubprocess2:
try:
allsubprocess2[name].kill()
except:
print_exc()
try:
if run:
_f = subprocess.run
else:
_f = subprocess.Popen
ss = _f(
cmd,
cwd=cwd,
stdin=_pipe,
stdout=_pipe,
stderr=_pipe,
startupinfo=startupinfo,
encoding=encoding,
)
if name:
allsubprocess2[name] = ss
return ss
except:
print_exc()
return None
def endsubprocs():
for _ in allsubprocess2:
try:
allsubprocess2[_].kill()
except:
pass

View File

@ -1,7 +1,7 @@
import windows
import os, time
import codecs, hashlib, shutil
import socket, gobject, uuid, subprocess, functools
import socket, gobject, uuid, functools
import importlib, json, requests
from qtsymbols import *
from string import Formatter
@ -436,9 +436,7 @@ def selectdebugfile(path: str, ismypost=False):
"LunaTranslator/myutils/template/" + tgt,
p,
)
threading.Thread(
target=subprocess.run, args=("notepad " + os.path.normpath(p),)
).start()
windows.ShellExecute(None, "open", "notepad", os.path.normpath(p), None, windows.SW_SHOW)
return p

View File

@ -1,7 +1,7 @@
import os, uuid, gobject, winreg
from myutils.hwnd import subprochiderun
from myutils.config import _TR, globalconfig
from ocrengines.baseocrclass import baseocr
from myutils.subproc import subproc_w
from language import Languages
@ -29,12 +29,7 @@ class OCR(baseocr):
def list_langs(self):
if not (self.path and os.path.exists(self.path)):
raise Exception(_TR("not installed"))
res = subproc_w(
'"{}" --list-langs'.format(self.path),
needstdio=True,
run=True,
encoding="utf8",
).stdout
res = subprochiderun('"{}" --list-langs'.format(self.path)).stdout
return res.split("\n")[1:-1]
def langmap(self):
@ -86,12 +81,7 @@ class OCR(baseocr):
with open(fname, "wb") as ff:
ff.write(imagebinary)
imgfile = os.path.abspath(fname)
_ = subproc_w(
'"{}" "{}" stdout -l osd --psm 0'.format(self.path, imgfile),
needstdio=True,
encoding="utf8",
run=True,
)
_ = subprochiderun('"{}" "{}" stdout -l osd --psm 0'.format(self.path, imgfile))
err = _.stderr
if len(err):
pass
@ -103,11 +93,8 @@ class OCR(baseocr):
with open(fname, "wb") as ff:
ff.write(imagebinary)
imgfile = os.path.abspath(fname)
_ = subproc_w(
'"{}" "{}" - -l {} --psm {}'.format(self.path, imgfile, lang, psm),
needstdio=True,
encoding="utf8",
run=True,
_ = subprochiderun(
'"{}" "{}" - -l {} --psm {}'.format(self.path, imgfile, lang, psm)
)
os.remove(imgfile)
res = _.stdout

View File

@ -1,6 +1,6 @@
import gobject
import winrtutils, windows, re
import subprocess
from myutils.hwnd import subprochiderun
from myutils.config import _TR
from myutils.utils import dynamiclink
from ocrengines.baseocrclass import baseocr
@ -8,21 +8,14 @@ from qtsymbols import *
from gui.dynalang import LPushButton, LLabel
from gui.dynalang import LPushButton, LFormLayout, LLabel
from gui.usefulwidget import SuperCombo, getboxlayout, IconButton
import threading, qtawesome
import threading, subprocess
from language import Languages
from myutils.subproc import subproc_w
def getallsupports():
_ = (
subproc_w(
"powershell Get-WindowsCapability -Online | Where-Object { $_.Name -Like 'Language.OCR*' }",
needstdio=True,
run=True,
)
.stdout.decode()
.splitlines()
)
_ = subprochiderun(
"powershell Get-WindowsCapability -Online | Where-Object { $_.Name -Like 'Language.OCR*' }",
).stdout.splitlines()
langs = []
langsinter = []
for i in range(len(_)):

View File

@ -2,7 +2,6 @@ from scalemethod.base import scalebase
import os, json
import windows, winsharedutils
from myutils.config import globalconfig
from myutils.subproc import subproc_w
import time
from myutils.wrapper import threader
@ -11,10 +10,9 @@ class Method(scalebase):
def runmagpie(self):
if not windows.FindWindow("Magpie_Hotkey", None):
subproc_w(
self.engine = winsharedutils.AutoKillProcess(
os.path.join(globalconfig["magpiepath"], "Magpie.exe"),
cwd=globalconfig["magpiepath"],
name="magpie",
globalconfig["magpiepath"],
)
while not windows.FindWindow("Magpie_Hotkey", None):
time.sleep(0.5)

View File

@ -2,7 +2,6 @@ from scalemethod.base import scalebase
import json
import windows, gobject
from myutils.config import globalconfig, magpie_config
from myutils.subproc import subproc_w
import winsharedutils
@ -23,9 +22,9 @@ class Method(scalebase):
)
winsharedutils.globalmessagelistener(self.messagecallback__)
self.jspath = gobject.gettempdir("magpie.config.json")
self.engine = subproc_w(
self.engine = winsharedutils.AutoKillProcess(
'./files/plugins/Magpie/Magpie.Core.exe "{}"'.format(self.jspath),
cwd="./files/plugins/Magpie/",
"./files/plugins/Magpie/",
)
waitsignal = "Magpie_notify_prepared_ok_" + str(self.engine.pid)
windows.WaitForSingleObject(

View File

@ -1,7 +1,6 @@
from myutils.subproc import subproc_w, autoproc
from translator.basetranslator import basetrans
import ctypes, time
import windows
import windows, winsharedutils
class TS(basetrans):
@ -16,13 +15,10 @@ class TS(basetrans):
t = str(t)
pipename = "\\\\.\\Pipe\\dreye_" + t
waitsignal = "dreyewaitload_" + t
self.engine = autoproc(
subproc_w(
"./files/plugins/shareddllproxy32.exe atlaswmain {} {} ".format(
pipename, waitsignal
),
name="atlaswmain",
)
self.engine = winsharedutils.AutoKillProcess(
"./files/plugins/shareddllproxy32.exe atlaswmain {} {}".format(
pipename, waitsignal
),
)
windows.WaitForSingleObject(

View File

@ -3,8 +3,7 @@ import json, requests, threading, hashlib
from myutils.config import _TR
from myutils.wrapper import threader
from myutils.utils import checkportavailable
from myutils.subproc import subproc_w
import websocket, time, queue, os
import websocket, time, queue, os, subprocess
class Commonloadchromium:
@ -40,7 +39,7 @@ class Commonloadchromium:
if checkportavailable(port):
print("连接失败")
call = self.gencmd(_path, port)
self.engine = subproc_w(call)
subprocess.Popen(call)
else:
print("端口冲突")

View File

@ -1,8 +1,7 @@
from myutils.subproc import subproc_w, autoproc
from translator.basetranslator import basetrans
from myutils.config import _TR
import os, time
import windows
import windows, winsharedutils
from language import Languages
@ -36,13 +35,10 @@ class TS(basetrans):
else:
path2 = os.path.join(path, "TransCOMEC.dll")
self.engine = autoproc(
subproc_w(
'./files/plugins/shareddllproxy32.exe dreye "{}" "{}" {} {} {} '.format(
path, path2, str(mp[pairs]), pipename, waitsignal
),
name="dreye",
)
self.engine = winsharedutils.AutoKillProcess(
'./files/plugins/shareddllproxy32.exe dreye "{}" "{}" {} {} {}'.format(
path, path2, str(mp[pairs]), pipename, waitsignal
),
)
windows.WaitForSingleObject(
@ -67,7 +63,11 @@ class TS(basetrans):
if self.checkpath() == False:
raise Exception(_TR("翻译器加载失败"))
codes = {Languages.Chinese: "gbk", Languages.Japanese: "shift-jis", Languages.English: "utf8"}
codes = {
Languages.Chinese: "gbk",
Languages.Japanese: "shift-jis",
Languages.English: "utf8",
}
ress = []
for line in content.split("\n"):
if len(line) == 0:

View File

@ -1,8 +1,7 @@
from translator.basetranslator import basetrans
from myutils.config import _TR
import os, time
import windows, ctypes
from myutils.subproc import subproc_w, autoproc
import windows, ctypes, winsharedutils
class TS(basetrans):
@ -25,15 +24,12 @@ class TS(basetrans):
pipename = "\\\\.\\Pipe\\xxx_" + t
waitsignal = "waitload_" + t
self.engine = autoproc(
subproc_w(
'./files/plugins/shareddllproxy32.exe eztrans "{}" {} {} '.format(
os.path.normpath(os.path.dirname(self.path)),
pipename,
waitsignal,
),
name="eztrans",
)
self.engine = winsharedutils.AutoKillProcess(
'./files/plugins/shareddllproxy32.exe eztrans "{}" {} {}'.format(
os.path.normpath(os.path.dirname(self.path)),
pipename,
waitsignal,
),
)
windows.WaitForSingleObject(

View File

@ -1,9 +1,8 @@
from translator.basetranslator import basetrans
import ctypes
import os, time
import windows
import windows, winsharedutils
from myutils.config import _TR
from myutils.subproc import subproc_w, autoproc
from language import Languages
@ -41,14 +40,11 @@ class TS(basetrans):
pipename = "\\\\.\\Pipe\\jbj7_" + t
waitsignal = "jbjwaitload_" + t
self.engine = autoproc(
subproc_w(
'./files/plugins/shareddllproxy32.exe jbj7 "{}" {} {} '.format(
self.dllpath, pipename, waitsignal
)
+ dictpath,
name="jbj7",
self.engine = winsharedutils.AutoKillProcess(
'./files/plugins/shareddllproxy32.exe jbj7 "{}" {} {}'.format(
self.dllpath, pipename, waitsignal
)
+ dictpath,
)
windows.WaitForSingleObject(
windows.AutoHandle(windows.CreateEvent(False, False, waitsignal)),

View File

@ -1,8 +1,7 @@
from myutils.subproc import subproc_w, autoproc
from translator.basetranslator import basetrans
from myutils.config import _TR
import os, time
import windows
import windows, winsharedutils
from language import Languages
@ -38,13 +37,10 @@ class TS(basetrans):
t = str(t)
pipename = "\\\\.\\Pipe\\ks_" + t
waitsignal = "kswaitload_" + t
self.engine = autoproc(
subproc_w(
'./files/plugins/shareddllproxy32.exe kingsoft "{}" "{}" {} {} '.format(
self.path, self.path2, pipename, waitsignal
),
name="ks",
)
self.engine = winsharedutils.AutoKillProcess(
'./files/plugins/shareddllproxy32.exe kingsoft "{}" "{}" {} {}'.format(
self.path, self.path2, pipename, waitsignal
),
)
windows.WaitForSingleObject(

View File

@ -1,7 +1,6 @@
from myutils.subproc import subproc_w, autoproc
from translator.basetranslator import basetrans
import ctypes, time
import windows
import windows, winsharedutils
from language import Languages
@ -24,12 +23,9 @@ class TS(basetrans):
t = str(t)
pipename = "\\\\.\\Pipe\\dreye_" + t
waitsignal = "dreyewaitload_" + t
self.engine = autoproc(
subproc_w(
"./files/plugins/shareddllproxy32.exe lec {} {} {} {}".format(
pipename, waitsignal, self.srclang, self.tgtlang
),
name="lec",
self.engine = winsharedutils.AutoKillProcess(
"./files/plugins/shareddllproxy32.exe lec {} {} {} {}".format(
pipename, waitsignal, self.srclang, self.tgtlang
)
)

View File

@ -1,9 +1,8 @@
import time
import os
import windows
import windows, winsharedutils
from tts.basettsclass import TTSbase, SpeechParam
import ctypes, subprocess, gobject
from myutils.subproc import subproc_w, autoproc
from ctypes import cast, POINTER, c_char, c_int32
@ -16,9 +15,9 @@ class TTS(TTSbase):
waitsignal = "voiceroid2waitload_" + t
mapname = "voiceroid2filemap" + t
cmd = '"{}" neospeech {} {} {}'.format(exepath, pipename, waitsignal, mapname)
cmd = '"{}" neospeech {} {} {}'.format(exepath, pipename, waitsignal, mapname)
self.engine = autoproc(subproc_w(cmd, name=str(time.time())))
self.engine = winsharedutils.AutoKillProcess(cmd)
windows.WaitForSingleObject(
windows.AutoHandle(windows.CreateEvent(False, False, waitsignal)),
@ -67,7 +66,7 @@ class TTS(TTSbase):
vis.append(datas[i * 3])
return internal, vis
def speak(self, content, voice, param:SpeechParam):
def speak(self, content, voice, param: SpeechParam):
hkey, idx = voice
windows.WriteFile(self.hPipe, bytes(ctypes.c_uint(param.speed)))
windows.WriteFile(self.hPipe, content.encode("utf-16-le"))

View File

@ -1,9 +1,8 @@
import time
import os
import windows
import windows, winsharedutils
from tts.basettsclass import TTSbase, SpeechParam
from ctypes import cast, POINTER, c_char, c_int32, c_float
from myutils.subproc import subproc_w, autoproc
class TTS(TTSbase):
@ -59,17 +58,14 @@ class TTS(TTSbase):
waitsignal = "voiceroid2waitload_" + t
mapname = "voiceroid2filemap" + t
self.engine = autoproc(
subproc_w(
'"{}" voiceroid2 "{}" "{}" {} {} {}'.format(
exepath,
self.config["path"],
dllpath,
pipename,
waitsignal,
mapname,
),
name=str(time.time()),
self.engine = winsharedutils.AutoKillProcess(
'"{}" voiceroid2 "{}" "{}" {} {} {}'.format(
exepath,
self.config["path"],
dllpath,
pipename,
waitsignal,
mapname,
)
)
windows.WaitForSingleObject(

View File

@ -350,3 +350,18 @@ get_allAccess_ptr = utilsdll.get_allAccess_ptr
get_allAccess_ptr.restype = c_void_p
windows.CreateEvent = functools.partial(windows.CreateEvent, psecu=get_allAccess_ptr())
windows.CreateMutex = functools.partial(windows.CreateMutex, psecu=get_allAccess_ptr())
createprocess = utilsdll.createprocess
createprocess.argtypes = c_wchar_p, c_wchar_p, POINTER(DWORD)
createprocess.restype = HANDLE
class AutoKillProcess_:
def __init__(self, handle, pid):
self.handle = windows.AutoHandle(handle)
self.pid = pid
def AutoKillProcess(command, path=None):
pid = DWORD()
return AutoKillProcess_(createprocess(command, path, pointer(pid)), pid.value)