From 69d4695e233938ebe5de2862d16b8c9289328c06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=81=8D=E5=85=AE=E6=83=9A=E5=85=AE?= <101191390+HIllya51@users.noreply.github.com> Date: Wed, 1 May 2024 17:28:43 +0800 Subject: [PATCH] Update PyStand.cpp --- plugins/exec/PyStand.cpp | 207 +++++++++++++++++++++------------------ 1 file changed, 111 insertions(+), 96 deletions(-) diff --git a/plugins/exec/PyStand.cpp b/plugins/exec/PyStand.cpp index 7bc80bde..97a09e84 100644 --- a/plugins/exec/PyStand.cpp +++ b/plugins/exec/PyStand.cpp @@ -1,6 +1,6 @@ //===================================================================== // -// PyStand.cpp - +// PyStand.cpp - // // Created by skywind on 2022/02/03 // Last Modified: 2023/03/17 20:06 @@ -22,7 +22,6 @@ #pragma comment(lib, "shlwapi.lib") #endif - //--------------------------------------------------------------------- // dtor //--------------------------------------------------------------------- @@ -31,7 +30,6 @@ PyStand::~PyStand() FreeLibrary(_hDLL); } - //--------------------------------------------------------------------- // ctor //--------------------------------------------------------------------- @@ -39,16 +37,18 @@ PyStand::PyStand(const wchar_t *runtime) { _hDLL = NULL; _Py_Main = NULL; - if (CheckEnviron(runtime) == false) { + if (CheckEnviron(runtime) == false) + { exit(1); } - if (LoadPython() == false) { + if (LoadPython() == false) + { exit(2); } } //--------------------------------------------------------------------- -// init: _args, _argv, _cwd, _pystand, _home, _runtime, +// init: _args, _argv, _cwd, _pystand, _home, _runtime, //--------------------------------------------------------------------- bool PyStand::CheckEnviron(const wchar_t *rtp) { @@ -57,12 +57,14 @@ bool PyStand::CheckEnviron(const wchar_t *rtp) int argc; _args = GetCommandLineW(); argvw = CommandLineToArgvW(_args.c_str(), &argc); - if (argvw == NULL) { + if (argvw == NULL) + { MessageBoxA(NULL, "Error in CommandLineToArgvW()", "ERROR", MB_OK); return false; } _argv.resize(argc); - for (int i = 0; i < argc; i++) { + for (int i = 0; i < argc; i++) + { _argv[i] = argvw[i]; } LocalFree(argvw); @@ -81,9 +83,12 @@ bool PyStand::CheckEnviron(const wchar_t *rtp) // init: _home int size = (int)wcslen(path); - for (; size > 0; size--) { - if (path[size - 1] == L'/') break; - if (path[size - 1] == L'\\') break; + for (; size > 0; size--) + { + if (path[size - 1] == L'/') + break; + if (path[size - 1] == L'\\') + break; } path[size] = 0; SetCurrentDirectoryW(path); @@ -93,16 +98,20 @@ bool PyStand::CheckEnviron(const wchar_t *rtp) // init: _runtime (embedded python directory) bool abspath = false; - if (wcslen(rtp) >= 3) { - if (rtp[1] == L':') { + if (wcslen(rtp) >= 3) + { + if (rtp[1] == L':') + { if (rtp[2] == L'/' || rtp[2] == L'\\') abspath = true; } } - if (abspath == false) { + if (abspath == false) + { _runtime = _home + L"\\" + rtp; } - else { + else + { _runtime = rtp; } GetFullPathNameW(_runtime.c_str(), MAX_PATH + 1, path, NULL); @@ -110,7 +119,8 @@ bool PyStand::CheckEnviron(const wchar_t *rtp) // check home std::wstring check = _runtime; - if (!PathFileExistsW(check.c_str())) { + if (!PathFileExistsW(check.c_str())) + { std::wstring msg = L"Missing embedded Python3 in:\n" + check; MessageBoxW(NULL, msg.c_str(), L"ERROR", MB_OK); return false; @@ -118,7 +128,8 @@ bool PyStand::CheckEnviron(const wchar_t *rtp) // check python3.dll std::wstring check2 = _runtime + L"\\python3.dll"; - if (!PathFileExistsW(check2.c_str())) { + if (!PathFileExistsW(check2.c_str())) + { std::wstring msg = L"Missing python3.dll in:\r\n" + check; MessageBoxW(NULL, msg.c_str(), L"ERROR", MB_OK); return false; @@ -142,7 +153,6 @@ bool PyStand::CheckEnviron(const wchar_t *rtp) return true; } - //--------------------------------------------------------------------- // load python //--------------------------------------------------------------------- @@ -160,19 +170,22 @@ bool PyStand::LoadPython() SetCurrentDirectoryW(runtime.c_str()); // LoadLibrary _hDLL = (HINSTANCE)LoadLibraryA("python3.dll"); - if (_hDLL) { + if (_hDLL) + { _Py_Main = (t_Py_Main)GetProcAddress(_hDLL, "Py_Main"); - } + } // restore director SetCurrentDirectoryW(previous.c_str()); - if (_hDLL == NULL) { + if (_hDLL == NULL) + { std::wstring msg = L"Cannot load python3.dll from:\r\n" + runtime; MessageBoxW(NULL, msg.c_str(), L"ERROR", MB_OK); return false; } - else if (_Py_Main == NULL) { + else if (_Py_Main == NULL) + { std::wstring msg = L"Cannot find Py_Main() in:\r\n"; msg += runtime + L"\\python3.dll"; MessageBoxW(NULL, msg.c_str(), L"ERROR", MB_OK); @@ -181,13 +194,13 @@ bool PyStand::LoadPython() return true; } - //--------------------------------------------------------------------- // run string //--------------------------------------------------------------------- int PyStand::RunString(const wchar_t *script) { - if (_Py_Main == NULL) { + if (_Py_Main == NULL) + { return -1; } int hr = 0; @@ -200,19 +213,20 @@ int PyStand::RunString(const wchar_t *script) _py_argv.push_back(L"-S"); _py_argv.push_back(L"-c"); _py_argv.push_back(script); - for (i = 1; i < (int)_argv.size(); i++) { + for (i = 1; i < (int)_argv.size(); i++) + { _py_argv.push_back(_argv[i]); } // finalize arguments _py_args.resize(0); - for (i = 0; i < (int)_py_argv.size(); i++) { - _py_args.push_back((wchar_t*)_py_argv[i].c_str()); + for (i = 0; i < (int)_py_argv.size(); i++) + { + _py_args.push_back((wchar_t *)_py_argv[i].c_str()); } hr = _Py_Main((int)_py_args.size(), &_py_args[0]); return hr; } - //--------------------------------------------------------------------- // LoadScript() //--------------------------------------------------------------------- @@ -220,94 +234,93 @@ int PyStand::DetectScript() { // init: _script (init script like PyStand.int or PyStand.py) int size = (int)_pystand.size() - 1; - for (; size >= 0; size--) { - if (_pystand[size] == L'.') break; + for (; size >= 0; size--) + { + if (_pystand[size] == L'.') + break; } - if (size < 0) size = (int)_pystand.size(); + if (size < 0) + size = (int)_pystand.size(); std::wstring main = _pystand.substr(0, size); - std::vector exts; + std::vector exts; std::vector scripts; _script.clear(); std::wstring test; - test = _home + L"LunaTranslator\\LunaTranslator_main.py"; - if (PathFileExistsW(test.c_str())) { + test = _home + L"\\LunaTranslator\\LunaTranslator_main.py"; + if (PathFileExistsW(test.c_str())) + { _script = test; } - - if (_script.empty()) { - std::wstring msg = L"Can't find either of:\r\n"; - for (int j = 0; j < (int)scripts.size(); j++) { - msg += scripts[j] + L"\r\n"; - } - MessageBoxW(NULL, msg.c_str(), L"ERROR", MB_OK); - return -1; + if (_script.empty()) + { + std::wstring msg = L"Can't find :\r\n" + test; + MessageBoxW(NULL, msg.c_str(), L"ERROR", MB_OK); + return -1; } SetEnvironmentVariableW(L"PYSTAND_SCRIPT", _script.c_str()); return 0; } - //--------------------------------------------------------------------- // init script //--------------------------------------------------------------------- -const auto init_script = -L"import sys\n" -L"import os\n" -L"PYSTAND = os.environ['PYSTAND']\n" -L"PYSTAND_HOME = os.environ['PYSTAND_HOME']\n" -L"PYSTAND_RUNTIME = os.environ['PYSTAND_RUNTIME']\n" -L"PYSTAND_SCRIPT = os.environ['PYSTAND_SCRIPT']\n" -L"sys.path_origin = [n for n in sys.path]\n" -L"sys.PYSTAND = PYSTAND\n" -L"sys.PYSTAND_HOME = PYSTAND_HOME\n" -L"sys.PYSTAND_SCRIPT = PYSTAND_SCRIPT\n" -L"def MessageBox(msg, info = 'Message'):\n" -L" import ctypes\n" -L" ctypes.windll.user32.MessageBoxW(None, str(msg), str(info), 0)\n" -L" return 0\n" -L"os.MessageBox = MessageBox\n" +const auto init_script = + L"import sys\n" + L"import os\n" + L"PYSTAND = os.environ['PYSTAND']\n" + L"PYSTAND_HOME = os.environ['PYSTAND_HOME']\n" + L"PYSTAND_RUNTIME = os.environ['PYSTAND_RUNTIME']\n" + L"PYSTAND_SCRIPT = os.environ['PYSTAND_SCRIPT']\n" + L"sys.path_origin = [n for n in sys.path]\n" + L"sys.PYSTAND = PYSTAND\n" + L"sys.PYSTAND_HOME = PYSTAND_HOME\n" + L"sys.PYSTAND_SCRIPT = PYSTAND_SCRIPT\n" + L"def MessageBox(msg, info = 'Message'):\n" + L" import ctypes\n" + L" ctypes.windll.user32.MessageBoxW(None, str(msg), str(info), 0)\n" + L" return 0\n" + L"os.MessageBox = MessageBox\n" #ifndef PYSTAND_CONSOLE -L"try:\n" -L" fd = os.open('CONOUT$', os.O_RDWR | os.O_BINARY)\n" -L" fp = os.fdopen(fd, 'w')\n" -L" sys.stdout = fp\n" -L" sys.stderr = fp\n" -L" attached = True\n" -L"except Exception as e:\n" -L" fp = open(os.devnull, 'w')\n" -L" sys.stdout = fp\n" -L" sys.stderr = fp\n" -L" attached = False\n" + L"try:\n" + L" fd = os.open('CONOUT$', os.O_RDWR | os.O_BINARY)\n" + L" fp = os.fdopen(fd, 'w')\n" + L" sys.stdout = fp\n" + L" sys.stderr = fp\n" + L" attached = True\n" + L"except Exception as e:\n" + L" fp = open(os.devnull, 'w')\n" + L" sys.stdout = fp\n" + L" sys.stderr = fp\n" + L" attached = False\n" #endif -L"sys.argv = [PYSTAND_SCRIPT] + sys.argv[1:]\n" -L"text = open(PYSTAND_SCRIPT, 'rb').read()\n" -L"environ = {'__file__': PYSTAND_SCRIPT, '__name__': '__main__'}\n" -L"environ['__package__'] = None\n" + L"sys.argv = [PYSTAND_SCRIPT] + sys.argv[1:]\n" + L"text = open(PYSTAND_SCRIPT, 'rb').read()\n" + L"environ = {'__file__': PYSTAND_SCRIPT, '__name__': '__main__'}\n" + L"environ['__package__'] = None\n" #ifndef PYSTAND_CONSOLE -L"try:\n" -L" code = compile(text, PYSTAND_SCRIPT, 'exec')\n" -L" exec(code, environ)\n" -L"except Exception:\n" -L" if attached:\n" -L" raise\n" -L" import traceback, io\n" -L" sio = io.StringIO()\n" -L" traceback.print_exc(file = sio)\n" -L" os.MessageBox(sio.getvalue(), 'Error')\n" + L"try:\n" + L" code = compile(text, PYSTAND_SCRIPT, 'exec')\n" + L" exec(code, environ)\n" + L"except Exception:\n" + L" if attached:\n" + L" raise\n" + L" import traceback, io\n" + L" sio = io.StringIO()\n" + L" traceback.print_exc(file = sio)\n" + L" os.MessageBox(sio.getvalue(), 'Error')\n" #else -L"code = compile(text, PYSTAND_SCRIPT, 'exec')\n" -L"exec(code, environ)\n" + L"code = compile(text, PYSTAND_SCRIPT, 'exec')\n" + L"exec(code, environ)\n" #endif -""; - + ""; //--------------------------------------------------------------------- // main //--------------------------------------------------------------------- //! flag: -static -//! src: +//! src: //! link: stdc++, shlwapi, resource.o //! prebuild: windres resource.rc -o resource.o //! mode: win @@ -316,25 +329,29 @@ L"exec(code, environ)\n" #ifdef PYSTAND_CONSOLE int main() #else -int WINAPI +int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR args, int show) #endif { PyStand ps(L"LunaTranslator\\runtime"); - if (ps.DetectScript() != 0) { + if (ps.DetectScript() != 0) + { return 3; } #ifndef PYSTAND_CONSOLE - if (AttachConsole(ATTACH_PARENT_PROCESS)) { + if (AttachConsole(ATTACH_PARENT_PROCESS)) + { freopen("CONOUT$", "w", stdout); freopen("CONOUT$", "w", stderr); int fd = _fileno(stdout); - if (fd >= 0) { + if (fd >= 0) + { std::string fn = std::to_string(fd); SetEnvironmentVariableA("PYSTAND_STDOUT", fn.c_str()); } fd = _fileno(stdin); - if (fd >= 0) { + if (fd >= 0) + { std::string fn = std::to_string(fd); SetEnvironmentVariableA("PYSTAND_STDIN", fn.c_str()); } @@ -344,5 +361,3 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR args, int show) // printf("finalize\n"); return hr; } - -