#include #include #include "embedded.h" // 简化路径拼接宏 #define APPEND_PATH(base, file) (lstrcpyA(lstrcatA(lstrcpyA((base), (base)), "\\"), (file))) // 检查文件是否存在 static BOOL file_exists(const char* filename) { DWORD attrs = GetFileAttributesA(filename); return (attrs != INVALID_FILE_ATTRIBUTES && !(attrs & FILE_ATTRIBUTE_DIRECTORY)); } // 仅当文件不存在时保存资源 static BOOL save_resource_if_missing(const unsigned char* data, int len, const char* filepath) { if (file_exists(filepath)) return TRUE; HANDLE hFile = CreateFileA(filepath, GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) return FALSE; DWORD written; BOOL result = WriteFile(hFile, data, len, &written, NULL); CloseHandle(hFile); return result && (written == len); } // 检测 Python 是否可用 static BOOL CheckPythonAvailable() { char python_path[MAX_PATH]; if (SearchPathA(NULL, "python.exe", NULL, MAX_PATH, python_path, NULL) == 0) { return FALSE; } CHAR cmd[MAX_PATH + 32]; sprintf_s(cmd, sizeof(cmd), "\"%s\" --version", python_path); STARTUPINFOA si = { sizeof(si) }; PROCESS_INFORMATION pi = { 0 }; if (!CreateProcessA(NULL, cmd, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) { return FALSE; } WaitForSingleObject(pi.hProcess, 5000); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); return TRUE; } // 安全地从完整路径中提取目录部分(不包含最后的反斜杠) void GetDirectoryFromPath(char* path) { char* last_slash = strrchr(path, '\\'); if (last_slash != NULL) { *last_slash = '\0'; // 截断文件名 } else { // 如果没有反斜杠,说明只有文件名,保留原路径或设为 "." lstrcpyA(path, "."); } } int WINAPI WinMain(HINSTANCE hInst, HINSTANCE h0, LPSTR cmd, int nShow) { // 检查 Python if (!CheckPythonAvailable()) { MessageBoxA(NULL, "Python is not available. Please install Python first.", "Error", MB_OK | MB_ICONERROR); return 1; } CHAR exe_dir[MAX_PATH] = { 0 }; CHAR cash_dir[MAX_PATH] = { 0 }; CHAR command[MAX_PATH * 2] = { 0 }; // 获取当前目录 GetModuleFileNameA(NULL, exe_dir, MAX_PATH); GetDirectoryFromPath(exe_dir); lstrcpyA(cash_dir, exe_dir); lstrcatA(cash_dir, "\\cash"); // 创建 cash 目录 if (!CreateDirectoryA(cash_dir, NULL) && GetLastError() != ERROR_ALREADY_EXISTS) { MessageBoxA(NULL, "Failed to create 'cash' directory.", "Error", MB_OK | MB_ICONERROR); return 1; } // 定义资源项结构 struct { const unsigned char* data; int len; const char* filename; } resources[] = { { script_main, script_main_len, "\\init.py" }, { data_zip, data_zip_len, "\\data.db.zip" }, { cyzg_zip, cyzg_zip_len, "\\cyzg.zip" } }; // 提取所有嵌入资源(如果不存在) for (int i = 0; i < _countof(resources); ++i) { CHAR filepath[MAX_PATH]; lstrcpyA(filepath, cash_dir); lstrcatA(filepath, resources[i].filename); if (!save_resource_if_missing(resources[i].data, resources[i].len, filepath)) { MessageBoxA(NULL, "Failed to extract embedded resource.", "Error", MB_OK | MB_ICONERROR); return 1; } } // 判断是否已完成初始化 CHAR main_py[MAX_PATH], data_db[MAX_PATH]; lstrcpyA(main_py, cash_dir); lstrcatA(main_py, "\\main.py"); lstrcpyA(data_db, cash_dir); lstrcatA(data_db, "\\data.db"); const char* script_to_run = file_exists(main_py) && file_exists(data_db) ? "main.py" : "init.py"; // 构造并执行命令 snprintf(command, sizeof(command), "cmd /c \"cd /d \"%s\" && python \"%s\"", cash_dir, script_to_run); WinExec(command, nShow); return 0; }