| 29 | FILE* GetManagerLogFile() { return g_log_file; } |
| 30 | |
| 31 | static void InitLogFile() { |
| 32 | wchar_t path[MAX_PATH]{}; |
| 33 | if (FAILED(SHGetFolderPathW(nullptr, CSIDL_LOCAL_APPDATA, nullptr, 0, path))) |
| 34 | return; |
| 35 | |
| 36 | std::filesystem::path log_dir = path; |
| 37 | log_dir /= L"TenBox"; |
| 38 | std::error_code ec; |
| 39 | std::filesystem::create_directories(log_dir, ec); |
| 40 | |
| 41 | std::filesystem::path log_path = log_dir / L"manager.log"; |
| 42 | g_log_file = _wfsopen(log_path.c_str(), L"a", _SH_DENYWR); |
| 43 | if (g_log_file) { |
| 44 | setvbuf(g_log_file, nullptr, _IOLBF, BUFSIZ); |
| 45 | |
| 46 | // Write startup marker |
| 47 | time_t now = time(nullptr); |
| 48 | struct tm local_tm; |
| 49 | localtime_s(&local_tm, &now); |
| 50 | char time_buf[64]; |
| 51 | strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M:%S", &local_tm); |
| 52 | fprintf(g_log_file, "\n=== TenBox Manager started at %s ===\n", time_buf); |
| 53 | |
| 54 | // Redirect stderr to log file (best-effort; may be no-op on GUI apps). |
| 55 | _dup2(_fileno(g_log_file), _fileno(stderr)); |
| 56 | } |
| 57 | } |
| 58 | |
| 59 | static void CloseLogFile() { |
| 60 | if (g_log_file) { |