diff --git a/.github/workflows/build_launcher_exe.yml b/.github/workflows/build_launcher_exe.yml new file mode 100644 index 0000000..ed7b253 --- /dev/null +++ b/.github/workflows/build_launcher_exe.yml @@ -0,0 +1,31 @@ +name: Build VSCode Solution + +on: + push: + branches: + - test_build_exe + +jobs: + build: + runs-on: windows-latest + + steps: + - name: Checkout Code + uses: actions/checkout@v4 + with: + submodules: true + + - name: Set up MSBuild + uses: microsoft/setup-msbuild@v2 + + - name: Build Solution + run: | + cp icon.ico src-win-launcher\icon.ico + cd src-win-launcher + msbuild ok-launcher.sln /p:Configuration=Release + + - name: Upload Artifact + uses: actions/upload-artifact@v4 + with: + name: ok-ww-executable + path: src-win-launcher/x64/Release/ok-ww.exe diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..e69de29 diff --git a/icon.ico b/icon.ico new file mode 100644 index 0000000..6fccfe7 Binary files /dev/null and b/icon.ico differ diff --git a/src-win-launcher/.gitignore b/src-win-launcher/.gitignore new file mode 100644 index 0000000..6692832 --- /dev/null +++ b/src-win-launcher/.gitignore @@ -0,0 +1,5 @@ +.vs/ +ok-launcher/x64/ +x64/ +ok-launcher/Release/ +logs/ diff --git a/src-win-launcher/app.manifest b/src-win-launcher/app.manifest new file mode 100644 index 0000000..7508bf7 --- /dev/null +++ b/src-win-launcher/app.manifest @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src-win-launcher/configs/launcher.json b/src-win-launcher/configs/launcher.json new file mode 100644 index 0000000..697e574 --- /dev/null +++ b/src-win-launcher/configs/launcher.json @@ -0,0 +1,7 @@ +{ + "profile_name": "", + "source": "Global", + "app_dependencies_installed": false, + "app_version": "v0.0.113", + "launcher_version": "v0.0.113" +} \ No newline at end of file diff --git a/src-win-launcher/icon.ico b/src-win-launcher/icon.ico new file mode 100644 index 0000000..6fccfe7 Binary files /dev/null and b/src-win-launcher/icon.ico differ diff --git a/src-win-launcher/ok-launcher.cpp b/src-win-launcher/ok-launcher.cpp new file mode 100644 index 0000000..18d0944 --- /dev/null +++ b/src-win-launcher/ok-launcher.cpp @@ -0,0 +1,185 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#pragma comment(linker, "/SUBSYSTEM:WINDOWS") +#pragma comment(linker, "/ENTRY:mainCRTStartup") + +std::wstring getAbsolutePath(const std::wstring& relativePath) { + wchar_t fullPath[MAX_PATH]; + if (_wfullpath(fullPath, relativePath.c_str(), MAX_PATH) != NULL) { + return std::wstring(fullPath); + } + else { + MessageBoxW(NULL, L"Failed to get absolute path", L"Error", MB_OK); + return relativePath; // Return the original path if conversion fails + } +} + + +std::string WideStringToUTF8(const std::wstring& wstr) { + if (wstr.empty()) return std::string(); + std::wstring_convert> conv; + return conv.to_bytes(wstr); +} + +std::wstring UTF8ToWideString(const std::string& str) { + if (str.empty()) return std::wstring(); + std::wstring_convert> conv; + return conv.from_bytes(str); +} + +bool modifyVenvCfg(const std::wstring& envDir, const std::wstring& relativPythonDir) { + std::wstring absEnvDir = getAbsolutePath(envDir); + std::wstring pythonDir = getAbsolutePath(relativPythonDir); + std::wstring filePath = absEnvDir + L"\\pyvenv.cfg"; + + // Open the file in UTF-8 mode + std::ifstream file(filePath, std::ios::in | std::ios::binary); + if (!file.is_open()) { + return false; + } + + std::ostringstream contentStream; + contentStream << file.rdbuf(); + std::string contentUTF8 = contentStream.str(); + file.close(); + + std::wstring content = UTF8ToWideString(contentUTF8); + + // Modify the content using regex + std::wregex homeRegex(LR"((\s*home\s*=\s*).*)"); + std::wregex executableRegex(LR"((\s*executable\s*=\s*).*)"); + std::wregex commandRegex(LR"((\s*command\s*=\s*).*)"); + + content = std::regex_replace(content, homeRegex, L"$1" + pythonDir); + content = std::regex_replace(content, executableRegex, L"$1" + pythonDir + L"\\python.exe"); + content = std::regex_replace(content, commandRegex, L"$1" + pythonDir + L"\\python.exe -m venv " + absEnvDir); + + // Convert the modified wide string back to UTF-8 + std::string contentModifiedUTF8 = WideStringToUTF8(content); + + // Compare the original and modified content + if (contentUTF8 != contentModifiedUTF8) { + // Write the modified content back to the file in UTF-8 + std::ofstream outFile(filePath, std::ios::out | std::ios::binary); + if (!outFile.is_open()) { + MessageBoxW(NULL, L"Failed to open pyvenv.cfg file for writing", L"Error", MB_OK); + return false; + } + + outFile.write(contentModifiedUTF8.c_str(), contentModifiedUTF8.size()); + outFile.close(); + } + return true; +} + +std::wstring readAppVersion(const std::wstring& filePath) { + std::wifstream file(filePath); + if (!file.is_open()) { + MessageBoxW(NULL, L"Failed to open JSON file", L"Error", MB_OK); + return L"0.0.1"; // Default version if file read fails + } + + std::wstring content((std::istreambuf_iterator(file)), std::istreambuf_iterator()); + file.close(); + + std::wregex versionRegex(LR"(\"app_version\"\s*:\s*"([^"]+)\")"); + std::wsmatch match; + if (std::regex_search(content, match, versionRegex)) { + return match[1].str(); + } + else { + MessageBoxW(NULL, L"Failed to find launcher_version in JSON file", L"Error", MB_OK); + return L"0.0.1"; // Default version if regex search fails + } +} + +int main(int argc, char* argv[]) { + STARTUPINFO si = { sizeof(STARTUPINFO) }; + PROCESS_INFORMATION pi; + ZeroMemory(&pi, sizeof(pi)); + + si.dwFlags = STARTF_USESHOWWINDOW; + si.wShowWindow = SW_HIDE; + + std::wstring appVersion = readAppVersion(L".\\configs\\launcher.json"); + + std::wstring command; + + if (modifyVenvCfg(L".\\repo\\" + appVersion + L"\\.venv", L".\\python\\")) { + command = L".\\repo\\" + appVersion + L"\\.venv\\Scripts\\python.exe .\\repo\\" + appVersion + L"\\main.py"; + } + else { + //check if the .venv\Scripts\python.exe exists if exists, use it instead + std::wstring pythonPath = L".\\.venv\\Scripts\\python.exe"; + if (GetFileAttributesW(pythonPath.c_str()) != INVALID_FILE_ATTRIBUTES && !(GetFileAttributesW(pythonPath.c_str()) & FILE_ATTRIBUTE_DIRECTORY)) { + command = pythonPath + L" main.py"; + } + else { + MessageBoxW(NULL, L"Failed to open pyvenv.cfg file or python env does not exist", L"Error", MB_OK); + } + } + + // Append command-line arguments + for (int i = 1; i < argc; ++i) { + command += L" \""; + std::string argStr(argv[i]); + std::wstring wargStr(argStr.begin(), argStr.end()); + command += wargStr; + command += L"\""; + } + + SetEnvironmentVariableW(L"PYTHONHOME", NULL); + SetEnvironmentVariableW(L"PYTHONPATH", NULL); + SetEnvironmentVariableW(L"PYTHONIOENCODING", L"utf-8"); + + HANDLE hStdOutRead, hStdOutWrite; + SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE }; + CreatePipe(&hStdOutRead, &hStdOutWrite, &sa, 0); + SetHandleInformation(hStdOutRead, HANDLE_FLAG_INHERIT, 0); + + si.dwFlags |= STARTF_USESTDHANDLES; + si.hStdOutput = hStdOutWrite; + si.hStdError = hStdOutWrite; + + if (CreateProcessW(NULL, &command[0], NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) { + DWORD waitResult = WaitForSingleObject(pi.hProcess, 1000); + DWORD exitCode = 0; + GetExitCodeProcess(pi.hProcess, &exitCode); + + DWORD bytesRead; + CHAR buffer[4096]; + std::vector output; + while (true) { + DWORD bytesAvailable = 0; + PeekNamedPipe(hStdOutRead, NULL, 0, NULL, &bytesAvailable, NULL); + if (bytesAvailable == 0) break; + if (ReadFile(hStdOutRead, buffer, sizeof(buffer), &bytesRead, NULL) && bytesRead > 0) { + output.insert(output.end(), buffer, buffer + bytesRead); + } + } + std::string stdoutStr(output.begin(), output.end()); + std::wstring wstdoutStr(stdoutStr.begin(), stdoutStr.end()); + + if (exitCode != 0 && exitCode != 259) { + MessageBoxW(NULL, wstdoutStr.c_str(), L"Process Output (Error)", MB_OK); + } + + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + } + else { + MessageBoxW(NULL, L"Failed to create process", L"Error", MB_OK); + } + + CloseHandle(hStdOutRead); + CloseHandle(hStdOutWrite); + + return 0; +} diff --git a/src-win-launcher/ok-launcher.sln b/src-win-launcher/ok-launcher.sln new file mode 100644 index 0000000..1e3bde2 --- /dev/null +++ b/src-win-launcher/ok-launcher.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.11.35222.181 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ok-launcher", "ok-launcher.vcxproj", "{6D6F3863-5153-400E-97CF-DD6DE795E5B6}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6D6F3863-5153-400E-97CF-DD6DE795E5B6}.Debug|x64.ActiveCfg = Debug|x64 + {6D6F3863-5153-400E-97CF-DD6DE795E5B6}.Debug|x64.Build.0 = Debug|x64 + {6D6F3863-5153-400E-97CF-DD6DE795E5B6}.Debug|x86.ActiveCfg = Debug|Win32 + {6D6F3863-5153-400E-97CF-DD6DE795E5B6}.Debug|x86.Build.0 = Debug|Win32 + {6D6F3863-5153-400E-97CF-DD6DE795E5B6}.Release|x64.ActiveCfg = Release|x64 + {6D6F3863-5153-400E-97CF-DD6DE795E5B6}.Release|x64.Build.0 = Release|x64 + {6D6F3863-5153-400E-97CF-DD6DE795E5B6}.Release|x86.ActiveCfg = Release|Win32 + {6D6F3863-5153-400E-97CF-DD6DE795E5B6}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {B3B30BE3-86E8-4579-A151-FF27A46F0A2F} + EndGlobalSection +EndGlobal diff --git a/src-win-launcher/ok-launcher.vcxproj b/src-win-launcher/ok-launcher.vcxproj new file mode 100644 index 0000000..2debac1 --- /dev/null +++ b/src-win-launcher/ok-launcher.vcxproj @@ -0,0 +1,164 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + Win32Proj + {6d6f3863-5153-400e-97cf-dd6de795e5b6} + oklauncher + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + ok-ww + + + ok-ww + true + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdcpp17 + + + Windows + true + + + RequireAdministrator + false + + + + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + + + Windows + true + true + true + + + RequireAdministrator + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src-win-launcher/ok-launcher.vcxproj.filters b/src-win-launcher/ok-launcher.vcxproj.filters new file mode 100644 index 0000000..6577fef --- /dev/null +++ b/src-win-launcher/ok-launcher.vcxproj.filters @@ -0,0 +1,32 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + + + Header Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/src-win-launcher/ok-launcher.vcxproj.user b/src-win-launcher/ok-launcher.vcxproj.user new file mode 100644 index 0000000..892b7b6 --- /dev/null +++ b/src-win-launcher/ok-launcher.vcxproj.user @@ -0,0 +1,20 @@ + + + + C:\Users\ok\Downloads\ok-ww中文 + WindowsLocalDebugger + + + F:\projects\ok-gi + WindowsLocalDebugger + -t 1 + + + C:\Users\ok\Downloads\ok-ww中文 + WindowsLocalDebugger + + + C:\Users\ok\Downloads\ok-ww中文 + WindowsLocalDebugger + + \ No newline at end of file diff --git a/src-win-launcher/re.aps b/src-win-launcher/re.aps new file mode 100644 index 0000000..0b67474 Binary files /dev/null and b/src-win-launcher/re.aps differ diff --git a/src-win-launcher/re.rc b/src-win-launcher/re.rc new file mode 100644 index 0000000..4c4255c Binary files /dev/null and b/src-win-launcher/re.rc differ diff --git a/src-win-launcher/resource.h b/src-win-launcher/resource.h new file mode 100644 index 0000000..681cb9a --- /dev/null +++ b/src-win-launcher/resource.h @@ -0,0 +1,16 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by re.rc +// +#define IDI_ICON1 101 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif