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