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