From 286bd74835d3fb85f4483d5a21c90e0cdffed575 Mon Sep 17 00:00:00 2001 From: JiXieShi Date: Fri, 12 Sep 2025 17:51:05 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20=E6=96=B0=E5=A2=9E:=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E5=B7=A5=E4=BD=9C=E7=9B=AE=E5=BD=95=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E5=87=BD=E6=95=B0=20=F0=9F=93=9D=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9:=20=E5=AE=9E=E7=8E=B0=E5=B7=A5=E4=BD=9C=E7=9B=AE?= =?UTF-8?q?=E5=BD=95=E8=AE=BE=E7=BD=AE=E5=8F=8A=E8=87=AA=E5=8A=A8=E5=B7=A5?= =?UTF-8?q?=E4=BD=9C=E7=9B=AE=E5=BD=95=E7=9A=84=E9=80=BB=E8=BE=91=20?= =?UTF-8?q?=F0=9F=93=9D=20=E4=BF=AE=E6=94=B9:=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E8=8F=9C=E5=8D=95=E5=92=8C=E5=91=BD=E4=BB=A4=E8=A1=8C=E8=BE=93?= =?UTF-8?q?=E5=85=A5=E8=AE=BE=E7=BD=AE=E6=B6=89=E5=8F=8A=E7=9A=84=E9=80=BB?= =?UTF-8?q?=E8=BE=91=20=F0=9F=94=A7=20=E4=BF=AE=E5=A4=8D:=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E8=87=AA=E5=90=AF=E5=8A=A8=E7=9B=B8=E5=85=B3=E7=9A=84?= =?UTF-8?q?=E6=B3=A8=E5=86=8C=E8=A1=A8=E9=94=AE=E5=90=8D=E7=94=9F=E6=88=90?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/inc/CLIProcess.h | 3 ++- app/src/CLIProcess.cpp | 18 ++++++++++-------- app/src/Manager.cpp | 26 +++++++++++++++++++++----- app/src/Units.cpp | 29 ++++++++++++++++++++++++++--- 4 files changed, 59 insertions(+), 17 deletions(-) diff --git a/app/inc/CLIProcess.h b/app/inc/CLIProcess.h index d7e5ae8..9337924 100644 --- a/app/inc/CLIProcess.h +++ b/app/inc/CLIProcess.h @@ -44,8 +44,9 @@ public: void SetStopCommand(const std::string& command, int timeout_ms = 5000); void SetEnvironmentVariables(const std::map& env_vars); void SetOutputEncoding(OutputEncoding encoding); + void SetAutoWorkingDir(bool auto_dir); - // 新增:工作目录设置 + // 工作目录设置 void SetWorkingDirectory(const std::string& working_dir); std::string GetWorkingDirectory() const; diff --git a/app/src/CLIProcess.cpp b/app/src/CLIProcess.cpp index 7741d52..90abb12 100644 --- a/app/src/CLIProcess.cpp +++ b/app/src/CLIProcess.cpp @@ -26,38 +26,40 @@ CLIProcess::CLIProcess() { max_log_lines_ = 1000; stop_timeout_ms_ = 5000; output_encoding_ = OutputEncoding::AUTO_DETECT; - use_auto_working_dir_ = false; // 自动工作目录 + use_auto_working_dir_ = true; // 自动工作目录 } CLIProcess::~CLIProcess() { Stop(); CleanupResources(); } - -// 新增:设置工作目录 +void CLIProcess::SetAutoWorkingDir(const bool auto_dir) { + use_auto_working_dir_ = auto_dir; +} +// 设置工作目录 void CLIProcess::SetWorkingDirectory(const std::string& working_dir) { std::lock_guard lock(working_dir_mutex_); if (working_dir.empty()) { - use_auto_working_dir_ = true; + // use_auto_working_dir_ = true; working_directory_.clear(); } else { if (DirectoryExists(working_dir)) { working_directory_ = GetAbsolutePath(working_dir); use_auto_working_dir_ = false; - AddLog("工作目录已设置为: " + working_directory_); + // AddLog("工作目录已设置为: " + working_directory_); } else { AddLog("警告: 指定的工作目录不存在: " + working_dir); } } } -// 新增:获取当前工作目录设置 +// 获取当前工作目录设置 std::string CLIProcess::GetWorkingDirectory() const { std::lock_guard lock(working_dir_mutex_); return working_directory_; } -// 新增:从命令中提取目录路径 +// 从命令中提取目录路径 std::string CLIProcess::ExtractDirectoryFromCommand(const std::string& command) { if (command.empty()) return ""; @@ -470,7 +472,7 @@ void CLIProcess::Start(const std::string& command) { // AddLog("环境变量设置完成,数量: " + std::to_string(environment_variables_.size())); } else { - AddLog("未设置自定义环境变量,使用默认环境 PWD:" + WideToString(working_dir)); + // AddLog("未设置自定义环境变量,使用默认环境 PWD:" + WideToString(working_dir)); } BOOL result = CreateProcess( diff --git a/app/src/Manager.cpp b/app/src/Manager.cpp index 806dce1..51c9bf6 100644 --- a/app/src/Manager.cpp +++ b/app/src/Manager.cpp @@ -111,6 +111,7 @@ bool Manager::Initialize() { m_app_state.LoadSettings(); m_app_state.auto_start = IsAutoStartEnabled(); m_app_state.ApplySettings(); + m_app_state.SaveSettings(); #ifdef _WIN32 m_tray->UpdateWebUrl(StringToWide(m_app_state.web_url)); @@ -122,6 +123,8 @@ bool Manager::Initialize() { // 如果开启了开机自启动且有启动命令,则自动启动子进程 if (m_app_state.auto_start && strlen(m_app_state.command_input) > 0) { m_app_state.cli_process.Start(m_app_state.command_input); + m_app_state.show_main_window = false; + HideMainWindow(); } m_tray->UpdateStatus(m_app_state.cli_process.IsRunning() ? L"运行中" : L"已停止", m_app_state.cli_process.GetPid()); m_initialized = true; @@ -235,9 +238,11 @@ void Manager::RenderUI() { // 设置默认布局(仅在第一次运行时) SetupDefaultDockingLayout(m_dockspace_id); + ImGuiWindowClass window_class; window_class.DockNodeFlagsOverrideSet = ImGuiDockNodeFlags_NoWindowMenuButton; ImGui::SetNextWindowClass(&window_class); + RenderMainContent(); ImGui::End(); @@ -541,7 +546,11 @@ void Manager::RenderSettingsMenu() { SetAutoStart(m_app_state.auto_start); m_app_state.settings_dirty = true; } - + if (ImGui::MenuItem("自动工作路径", nullptr, m_app_state.auto_working_dir)) { + m_app_state.auto_working_dir = !m_app_state.auto_working_dir; + m_app_state.cli_process.SetAutoWorkingDir(m_app_state.auto_working_dir); + m_app_state.settings_dirty = true; + } ImGui::Separator(); ImGui::Text("日志设置"); if (ImGui::InputInt("最大日志行数", &m_app_state.max_log_lines, 100, 500)) { @@ -732,7 +741,7 @@ void Manager::RenderOutputEncodingSettings() { void Manager::RenderControlPanel(float buttonWidth, float buttonHeight, float inputWidth) { // 启动命令输入区域 - ImGui::SeparatorText("启动命令"); + ImGui::SeparatorText("CLI程序"); // 命令输入框和历史记录按钮 ImGui::SetNextItemWidth(inputWidth); @@ -749,7 +758,11 @@ void Manager::RenderControlPanel(float buttonWidth, float buttonHeight, float in if (show_command_history_) { RenderCommandHistory(); } - + ImGui::SeparatorText("工作路径(留空且开启自动路径为文件父路径、不然为管理器路径)"); + if (ImGui::InputText("##工作路径", m_app_state.working_directory, IM_ARRAYSIZE(m_app_state.working_directory))) { + m_app_state.cli_process.SetWorkingDirectory(m_app_state.working_directory); + m_app_state.settings_dirty = true; + } ImGui::Spacing(); // 控制按钮组 @@ -758,6 +771,11 @@ void Manager::RenderControlPanel(float buttonWidth, float buttonHeight, float in if (strlen(m_app_state.command_input) > 0) { m_app_state.cli_process.Start(m_app_state.command_input); m_app_state.AddCommandToHistory(m_app_state.command_input); + if (strlen(m_app_state.working_directory) > 0) { + m_app_state.cli_process.SetWorkingDirectory(m_app_state.working_directory); + }else { + strncpy_s(m_app_state.working_directory,m_app_state.cli_process.GetWorkingDirectory().c_str(),sizeof(m_app_state.working_directory)-1); + } m_tray->UpdateStatus(m_app_state.cli_process.IsRunning() ? L"运行中" : L"已停止", m_app_state.cli_process.GetPid()); } @@ -1133,7 +1151,6 @@ void Manager::ContentScaleCallback(GLFWwindow *window, float xscale, float yscal } } - #ifdef USE_WIN32_BACKEND bool Manager::InitializeWin32() { m_wc = {}; @@ -1478,7 +1495,6 @@ void Manager::ReloadFonts() const { #endif } - #ifdef __APPLE__ // macOS 特定的辅助函数声明 extern "C" { diff --git a/app/src/Units.cpp b/app/src/Units.cpp index 2dd653b..ac678e5 100644 --- a/app/src/Units.cpp +++ b/app/src/Units.cpp @@ -32,12 +32,22 @@ void SetAutoStart(bool enable) { WCHAR exePath[MAX_PATH]; GetModuleFileName(NULL, exePath, MAX_PATH); + // 计算路径的简单哈希值 + size_t hash = 0; + for (size_t i = 0; i < wcslen(exePath); i++) { + hash = (hash * 31) + exePath[i]; + } + + // 创建包含哈希的键名 + WCHAR keyName[32]; + swprintf(keyName, 32, L"CLIManager_%08X", static_cast(hash)); + if (enable) { - RegSetValueEx(hKey, L"CLIManager", 0, REG_SZ, + RegSetValueEx(hKey, keyName, 0, REG_SZ, (BYTE*)exePath, (wcslen(exePath) + 1) * sizeof(WCHAR)); } else { - RegDeleteValue(hKey, L"CLIManager"); + RegDeleteValue(hKey, keyName); } RegCloseKey(hKey); } @@ -49,8 +59,21 @@ bool IsAutoStartEnabled() { if (RegOpenKeyEx(HKEY_CURRENT_USER, path, 0, KEY_READ, &hKey) != ERROR_SUCCESS) return false; + WCHAR exePath[MAX_PATH]; + GetModuleFileName(NULL, exePath, MAX_PATH); + + // 计算相同的哈希值 + size_t hash = 0; + for (size_t i = 0; i < wcslen(exePath); i++) { + hash = (hash * 31) + exePath[i]; + } + + // 创建相同的键名用于查询 + WCHAR keyName[32]; + swprintf(keyName, 32, L"CLIManager_%08X", static_cast(hash)); + DWORD type, size = 0; - bool exists = (RegQueryValueEx(hKey, L"CLIManager", NULL, &type, NULL, &size) == ERROR_SUCCESS); + bool exists = (RegQueryValueEx(hKey, keyName, NULL, &type, NULL, &size) == ERROR_SUCCESS); RegCloseKey(hKey); return exists;