代码拉取完成,页面将自动刷新
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;
using Path = System.IO.Path;
using Newtonsoft.Json;
using System.Globalization;
using System.Reflection;
using Newtonsoft.Json.Linq;
using TalonUI;
using Microsoft.Win32;
using System.Text.RegularExpressions;
using System.Net;
using Talon;
using System.Windows.Interop;
using System.ComponentModel;
using Hardcodet.Wpf.TaskbarNotification;
using ScriptBox.Services;
namespace ScriptBox
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public string assemblyVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString();
string currSoftwareVersion;
TalonsWorkSpace talonsWorkSpace;
ScriptProject scriptProject;
TalonsUpdate talonsUpdate;
// 添加热键相关常量
private const int HOTKEY_ID = 9000;
private const int WM_HOTKEY = 0x0312;
// 添加窗口句柄字段
private IntPtr _windowHandle;
// 添加托盘图标字段
private TaskbarIcon _wpfTrayIcon;
private AppConfig _appConfig = new AppConfig();
private bool _isSettingsWindowOpen = false;
public MainWindow()
{
InitializeComponent();
InitializeTrayIcon();
// 初始化窗口行为
this.SourceInitialized += OnSourceInitialized;
this.Deactivated += Window_Deactivated;
// 添加快捷键绑定(放在构造函数中InitializeComponent()之后)
this.InputBindings.Add(new KeyBinding(
new RelayCommand(() => Menu_Tool_DbcBalance_Click(null, null)),
Key.D1,
ModifierKeys.Alt));
this.InputBindings.Add(new KeyBinding(
new RelayCommand(() => Menu_Tool_CRC_Click(null, null)),
Key.D2,
ModifierKeys.Alt));
//加载工作区
talonsWorkSpace = new TalonsWorkSpace("ScriptboxWS");
talonsWorkSpace.ReloadMenuEvent += ReloadMenuEventHandlerMethod;
string tempPath = talonsWorkSpace.Load();
if (tempPath != null)
{
ProjectConfig_Load(tempPath);//打开上一次的项目
}
//实例化检查更新
talonsUpdate = new TalonsUpdate("talonshaw", "ScriptBox");
talonsUpdate.UpdateChecked += TalonsUpdate_UpdateChecked;
}
// 添加窗口初始化处理
private void OnSourceInitialized(object sender, EventArgs e)
{
_appConfig = AppConfig.Load();
RegisterHotkeys(); // 统一调用热键注册方法
}
private void RegisterHotkeys()
{
if (_windowHandle == IntPtr.Zero)
{
_windowHandle = new WindowInteropHelper(this).Handle;
HwndSource.FromHwnd(_windowHandle)?.AddHook(HwndHook);
}
// 清理旧热键后注册新热键
UnregisterHotKey(_windowHandle, HOTKEY_ID);
if (!RegisterHotKey(_windowHandle, HOTKEY_ID, _appConfig.HotkeyModifiers, _appConfig.HotkeyKey))
{
MessageBox.Show($"热键注册失败 (Alt+{_appConfig.HotkeyKey:X}) 可能被占用",
"热键冲突",
MessageBoxButton.OK,
MessageBoxImage.Warning);
}
}
// 初始化托盘图标
private void InitializeTrayIcon()
{
_wpfTrayIcon = new TaskbarIcon
{
IconSource = new BitmapImage(new Uri("pack://application:,,,/Resources/Ta_Palatino_Linotype_20.ico")),
ToolTipText = "ScriptBox",
ContextMenu = CreateWpfContextMenu()
};
// 双击事件
_wpfTrayIcon.TrayMouseDoubleClick += (s, e) => ShowWindow();
}
// 创建WPF风格的右键菜单
private ContextMenu CreateWpfContextMenu()
{
var menu = new ContextMenu();
var openItem = new MenuItem { Header = "打开主界面" };
openItem.Click += (s, e) => ShowWindow();
var exitItem = new MenuItem { Header = "退出" };
exitItem.Click += (s, e) => Application.Current.Shutdown();
menu.Items.Add(openItem);
menu.Items.Add(exitItem);
return menu;
}
// 添加窗口消息钩子
private IntPtr HwndHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (msg == WM_HOTKEY && wParam.ToInt32() == HOTKEY_ID)
{
ShowWindow();
handled = true;
}
return IntPtr.Zero;
}
// 添加窗口显示逻辑
private void ShowWindow()
{
if (Visibility != Visibility.Visible)
{
Show();
ShowInTaskbar = true;
}
if (WindowState == WindowState.Minimized)
{
WindowState = WindowState.Normal;
}
Activate();
Topmost = true;
Topmost = false;
}
// 添加失去焦点处理
private void Window_Deactivated(object sender, EventArgs e)
{
if (IsActive) return;
if (_isSettingsWindowOpen) return; // 设置窗口打开时不隐藏
// 添加配置检查
if (!_appConfig.AutoHideEnabled) return;
// 添加最大化状态判断
//if (WindowState == WindowState.Maximized) return;
Hide();
ShowInTaskbar = false;
}
// 添加热键注册API
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vk);
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
// 修改关闭逻辑
protected override void OnClosing(CancelEventArgs e)
{
UnregisterHotKey(_windowHandle, HOTKEY_ID);
base.OnClosing(e);
}
// 添加OnClosed事件处理
protected override void OnClosed(EventArgs e)
{
_wpfTrayIcon.Dispose(); // 释放托盘图标资源
base.OnClosed(e); // 调用基类实现
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
currSoftwareVersion = assemblyVersion.Substring(0,assemblyVersion.LastIndexOf('.'));
talonsUpdate.CheckUpdate(currSoftwareVersion);
}
private void TalonsUpdate_UpdateChecked(object sender, string newVersion)
{
//检查到更新,增加更新菜单
Dispatcher.Invoke(() =>
{
MenuItem updateMenuItem = new MenuItem()
{
Header = "更新",
// 修改样式查找方式,使用TryFindResource确保能正确找到资源
Style = this.TryFindResource("UpdateMenuItemStyle") as Style ?? new MenuItem().Style,
Margin = new Thickness(10,2,0,2),
ToolTip = String.Format("新版本:{0}", newVersion)
};
updateMenuItem.Click += Menu_Update_Click;
Menu_Main.Items.Add(updateMenuItem);
});
}
private void ProjectConfig_Load(string scriptsPrjPath)
{
if (!File.Exists(scriptsPrjPath)) return;
try
{
OutputTextBox.Clear();
StackPanel_btnGroup.Children.Clear();
var json = File.ReadAllText(scriptsPrjPath);
scriptProject = JsonConvert.DeserializeObject<ScriptProject>(json);
// 规范化工作目录路径
scriptProject.workDir = Path.GetFullPath(
Path.Combine(Path.GetDirectoryName(scriptsPrjPath), scriptProject.workDir));
this.Title = $"ScriptBox-{scriptProject.projectName}";
talonsWorkSpace.SetCurrentProject(scriptProject.projectName, scriptsPrjPath);
// 处理按钮组
foreach (var group in scriptProject.buttonGroups.Where(g => g.buttons?.Count > 0))
{
var wrapPanel = new WrapPanel();
foreach (var btnConfig in group.buttons)
{
var iconButton = CreateIconButton(btnConfig, scriptsPrjPath);
wrapPanel.Children.Add(iconButton);
}
StackPanel_btnGroup.Children.Add(new Label
{
Content = group.groupName,
Foreground = Brushes.Blue
});
StackPanel_btnGroup.Children.Add(wrapPanel);
}
}
catch (JsonException ex)
{
OutputTextBox.Text = $"JSON解析错误:{ex.Message}";
}
catch (Exception ex)
{
OutputTextBox.Text = $"加载项目失败:{ex.Message}";
}
}
private IconButton CreateIconButton(ScriptButton config, string projectPath)
{
var iconButton = new IconButton
{
Title = config.Title,
Icon = GetButtonIcon(config, projectPath),
Tag = config,
Margin = new Thickness(5),
Width = 64
};
// 添加缺失的点击事件绑定
iconButton.Click += Button_Click;
return iconButton;
}
private static readonly Dictionary<string, Uri> _defaultIcons = new Dictionary<string, Uri>(StringComparer.OrdinalIgnoreCase)
{
["exe"] = new Uri("pack://application:,,,/Resources/application.png"),
["bat"] = new Uri("pack://application:,,,/Resources/cmd.png"),
["simpleBat"] = new Uri("pack://application:,,,/Resources/cmd.png"),
["cmd"] = new Uri("pack://application:,,,/Resources/cmd.png"),
["file"] = new Uri("pack://application:,,,/Resources/file.png"),
["dir"] = new Uri("pack://application:,,,/Resources/folder.png"),
["url"] = new Uri("pack://application:,,,/Resources/link.png"),
["python"] = new Uri("pack://application:,,,/Resources/python.png"),
["ps1"] = new Uri("pack://application:,,,/Resources/powershell.png")
};
private ImageSource GetButtonIcon(ScriptButton config, string projectPath)
{
// 处理自定义图标
if (!string.IsNullOrEmpty(config.ImgPath) && config.ImgPath != "default")
{
try
{
var fullPath = Path.Combine(Path.GetDirectoryName(projectPath), config.ImgPath);
if (File.Exists(fullPath))
{
return new BitmapImage(new Uri(fullPath));
}
OutputTextBox.Text = $"图标文件缺失:{config.ImgPath},使用默认图标";
}
catch (Exception ex)
{
OutputTextBox.Text = $"图标加载失败:{ex.Message}";
}
}
// 获取提取的EXE图标
if (config.ScriptType == "exe")
{
var exePath = GetAbsoluteScriptPath(config.ScriptContent);
return File.Exists(exePath) ?
ExeIcon.GetIconImage(exePath) :
new BitmapImage(_defaultIcons["exe"]);
}
// 获取默认图标
if (_defaultIcons.TryGetValue(config.ScriptType, out var uri))
{
return new BitmapImage(uri);
}
return new BitmapImage(new Uri("pack://application:,,,/Resources/script.png"));
}
/// <summary>
/// 菜单中加载最近项目
/// </summary>
/// <returns></returns>
private void ReloadMenuEventHandlerMethod(object sender, EventArgs e)
{
if (talonsWorkSpace.Config.recentProjects.Count() > 0)
{
for (int i = Menu_Prj_Recent.Items.Count - 1; i >= 2; i--)
{
Menu_Prj_Recent.Items.RemoveAt(i);
}
// 添加最近项目子菜单
foreach (var project in talonsWorkSpace.Config.recentProjects)
{
MenuItem menuItem = new MenuItem();
menuItem.Header = project.name;
menuItem.Click += (sender1, e1) =>
{
// 打开对应的工程文件
ProjectConfig_Load(project.path);
};
Menu_Prj_Recent.Items.Add(menuItem);
}
}
}
void TextBox_Msg_AddLine(string msg)
{
string fullMsg = $"[{DateTime.Now}] {msg}\n";
// 使用 Dispatcher 来确保在 UI 线程上执行操作
Dispatcher.Invoke(() =>
{
if(msg == null)
{
OutputTextBox.Clear();
return;
}
OutputTextBox.AppendText(fullMsg);
OutputTextBox.ScrollToEnd();
});
}
string GetAbsoluteScriptPath(string relativePath)
{
string scriptPath = "";
if (Path.IsPathRooted(relativePath))
{
scriptPath = relativePath;
if (!File.Exists(scriptPath))//绝对路径,如果不存在,则不动作
{
return "";
}
}
else
{
scriptPath = Path.Combine(Path.GetDirectoryName(scriptProject.workDir), relativePath);//在项目工作路径下找
if (!File.Exists(scriptPath))//如果脚本文件不存在
{
scriptPath = Path.Combine(talonsWorkSpace.CurrentProjectDir, relativePath);
if (!File.Exists(scriptPath))//如果也不存在,则不动作
{
return "";
}
}
}
return scriptPath;
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
bool isWithOutput = false;
if (!(sender is Button button)) return;
if (!(button.Tag is ScriptButton scriptButton)) return;
TextBox_Msg_AddLine(null);
if (scriptButton.ScriptType == "file" || scriptButton.ScriptType == "dir")//打开文件或文件夹
{
string fullPath = "";
if (Path.IsPathRooted(scriptButton.ScriptContent))
{
fullPath = scriptButton.ScriptContent;
}
else
{
fullPath = Path.Combine(scriptProject.workDir, scriptButton.ScriptContent).Replace("/", "\\");
}
if (File.Exists(fullPath) || Directory.Exists(fullPath))
{
try
{
// 使用默认程序打开文件
Process.Start(new ProcessStartInfo(fullPath) { UseShellExecute = true });
TextBox_Msg_AddLine(scriptButton.Title);
}
catch (Exception ex)
{
TextBox_Msg_AddLine($"{scriptButton.Title}: 打开失败 - {ex.Message}");
}
}
else
{
TextBox_Msg_AddLine($"{scriptButton.Title}: 未找到项目,请检查路径配置!");
}
}
else if(scriptButton.ScriptType == "url")
{
Process.Start(scriptButton.ScriptContent);
TextBox_Msg_AddLine(scriptButton.Title);
}
else
{
var startInfo = new ProcessStartInfo
{
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
};
if (scriptButton.ScriptType == "cmd")//执行cmd命令
{
startInfo.FileName = "cmd.exe";
startInfo.Arguments = $"/c {scriptButton.ScriptContent}";
startInfo.WorkingDirectory = scriptProject.workDir;
if (scriptButton.ScriptContent.Contains("echo"))
{
isWithOutput = true;
}
}
else//运行脚本
{
//以下类型均为脚本文件,检查脚本是否存在
string scriptPath = GetAbsoluteScriptPath(scriptButton.ScriptContent);
if (scriptPath == "")//如果也不存在,则不动作
{
TextBox_Msg_AddLine($"{scriptButton.Title}: 未找到脚本文件,请检查路径配置!");
return;
}
switch (scriptButton.ScriptType)
{
case "simpleBat":
startInfo.FileName = scriptPath;
startInfo.Arguments = scriptButton.ScriptParameter;
startInfo.WorkingDirectory = Path.GetDirectoryName(scriptPath);
isWithOutput = true;
break;
case "bat":
startInfo.FileName = scriptPath;
startInfo.Arguments = scriptButton.ScriptParameter;
startInfo.CreateNoWindow = false;
startInfo.RedirectStandardOutput = false;
startInfo.RedirectStandardError = false;
startInfo.WorkingDirectory = Path.GetDirectoryName(scriptPath);
break;
case "ps1":
startInfo.FileName = "powershell.exe";
startInfo.Arguments = $"-NoProfile -ExecutionPolicy Bypass -File \"{scriptPath} {scriptButton.ScriptParameter}\"";
if (scriptPath.Contains(talonsWorkSpace.CurrentProjectDir))//如果脚本文件在脚本文件夹下
{
startInfo.WorkingDirectory = scriptProject.workDir;
}
else
{
startInfo.WorkingDirectory = Path.GetDirectoryName(scriptPath);
}
isWithOutput = true;
break;
case "python":
startInfo.FileName = "python.exe";
startInfo.Arguments = $"{scriptPath} {scriptButton.ScriptParameter}";
if (scriptPath.Contains(talonsWorkSpace.CurrentProjectDir))//如果脚本文件在脚本文件夹下
{
startInfo.WorkingDirectory = scriptProject.workDir;
}
else
{
startInfo.WorkingDirectory = Path.GetDirectoryName(scriptPath);
}
isWithOutput = true;
break;
case "exe":
startInfo.FileName = scriptPath;
startInfo.Arguments = scriptButton.ScriptParameter;
if (scriptButton.ScriptParameter != null)//如果参数不为空,一般参数中为相对路径,则以项目工作路径为工作文件夹
{
startInfo.WorkingDirectory = scriptProject.workDir;
isWithOutput = true;
}
else if (Path.IsPathRooted(scriptButton.ScriptContent))//如果是绝对路径,说明exe在项目外部(如安装程序),则以项目工作路径为工作文件夹
{
startInfo.WorkingDirectory = scriptProject.workDir;
}
else//如果是相对路径,说明exe文件在项目内部,则以exe所在文件夹为工作文件夹
{
startInfo.WorkingDirectory = Path.GetDirectoryName(scriptPath);
}
break;
default:
break;
}
}
if (isWithOutput == false)
{
var process = new Process { StartInfo = startInfo };
process.Start();
TextBox_Msg_AddLine(scriptButton.Title);
}
else
{
TextBox_Msg_AddLine($"{scriptButton.Title} : 开始执行");
var result = await ExecuteScript(startInfo);
if (scriptButton.ScriptType != "python")// todo: python脚本未执行完成就会退出进程,故这里不显示其完成信息
TextBox_Msg_AddLine($"{scriptButton.Title} : {result}");
}
}
OutputTextBox.ScrollToEnd();
}
private void ReplaceLastLine(string newText)
{
// 获取TextBox中的文本行
var lines = OutputTextBox.Text.Split(new[] { Environment.NewLine }, StringSplitOptions.None).ToList();
// 替换最后一行
if (lines.Count > 0)
{
lines[lines.Count - 1] = newText;
OutputTextBox.Text = string.Join(Environment.NewLine, lines);
}
}
private async Task<string> ExecuteScript(ProcessStartInfo startInfo)
{
if (string.IsNullOrEmpty(startInfo.FileName)) return null;
using (var process = new Process { StartInfo = startInfo }) // 添加using语句
{
process.OutputDataReceived += (s, evt) =>// 注意:启动异步输出读取后才会触发接收事件
{
if (!string.IsNullOrEmpty(evt.Data))
{
TextBox_Msg_AddLine(evt.Data);
}
};
process.ErrorDataReceived += (s, evt) =>
{
if (!string.IsNullOrEmpty(evt.Data))
{
TextBox_Msg_AddLine(evt.Data);
}
};
process.Start();
process.BeginOutputReadLine(); // 启动异步输出读取
process.BeginErrorReadLine();
var processExitedTask = WaitForExitAsync(process);
await processExitedTask; // 等待进程退出
return "执行完成";
}
}
// Task extension method to simplify waiting for a process to exit
private static Task WaitForExitAsync(Process process)
{
var tcs = new TaskCompletionSource<bool>();
process.EnableRaisingEvents = true;
process.Exited += (sender, args) => tcs.TrySetResult(true);
if (process.HasExited)
{
tcs.TrySetResult(true);
}
return tcs.Task;
}
private void Menu_Prj_Open_Click(object sender, RoutedEventArgs e)
{
Microsoft.Win32.OpenFileDialog ofd = new Microsoft.Win32.OpenFileDialog();
ofd.Filter = "ScriptBox项目文件|*.sbprj|所有文件|*.*";
ofd.Title = "选择文件";
ofd.InitialDirectory = "";
if (ofd.ShowDialog() == true)
{
//此处做你想做的事 ...=ofd.FileName;
ProjectConfig_Load(ofd.FileName);
}
}
private void Menu_Prj_New_Click(object sender, RoutedEventArgs e)
{
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Filter = "项目文件 (*.sbprj)|*.sbprj";
saveFileDialog.Title = "新建项目";
saveFileDialog.ShowDialog();
if (saveFileDialog.FileName == "")
return;
// 获取用户选择的文件路径和文件名
string selectedFilePath = saveFileDialog.FileName;
string projectDir = Path.GetDirectoryName(selectedFilePath);
string projectName = Path.GetFileNameWithoutExtension(selectedFilePath);
// 创建项目文件夹
string projectFolderPath = Path.Combine(projectDir, "icon");
Directory.CreateDirectory(projectFolderPath);
projectFolderPath = Path.Combine(projectDir, "bat");
Directory.CreateDirectory(projectFolderPath);
projectFolderPath = Path.Combine(projectDir, "python");
Directory.CreateDirectory(projectFolderPath);
// 创建一个匿名类型表示JSON数据
var data = new
{
projectName = projectName,
workDir = "./",
buttonGroups = new[]
{
new
{
groupName = "通用工具",
buttons = new[]
{
new
{
title = "hello",
scriptType = "cmd",
scriptContent = "echo Hello World!",
}
}
}
}
};
// 将数据序列化为JSON字符串
var json = JsonConvert.SerializeObject(data, Formatting.Indented);
// 将JSON字符串写入文件
File.WriteAllText(selectedFilePath, json);
ProjectConfig_Load(selectedFilePath);
}
private string GetTextEditorPath()
{
// 检查Notepad3安装路径(通过注册表)
using (var key = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32)
.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\Notepad3.exe"))
{
if (key?.GetValue(null) is string np3Path && File.Exists(np3Path))
return np3Path;
}
// 检查Notepad++安装路径
using (var key = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32)
.OpenSubKey(@"SOFTWARE\Notepad++"))
{
var npPath = key?.GetValue(null) as string;
if (!string.IsNullOrEmpty(npPath))
{
var exePath = Path.Combine(npPath, "notepad++.exe");
if (File.Exists(exePath))
return exePath;
}
}
// 使用系统自带记事本
return Path.Combine(Environment.SystemDirectory, "notepad.exe");
}
private void Menu_Prj_Edit_Click(object sender, RoutedEventArgs e)
{
var editorPath = GetTextEditorPath();
var dialog = new ProjectManagementDialog(editorPath, talonsWorkSpace.CurrentProjectPath);
if (dialog.ShowDialog() == true)
{
ProjectConfig_Load(talonsWorkSpace.CurrentProjectPath);
}
}
private void Menu_Prj_Reload_Click(object sender, RoutedEventArgs e)
{
ProjectConfig_Load(talonsWorkSpace.CurrentProjectPath);
}
private void Menu_About_Click(object sender, RoutedEventArgs e)
{
About about = new About(currSoftwareVersion);
about.Show();
}
private void Menu_Update_Click(object sender, RoutedEventArgs e)
{
talonsUpdate.StartUpdate();
Close();
}
private void Menu_RecentPrjClear_Click(object sender, RoutedEventArgs e)
{
talonsWorkSpace.ClearRecentProject();
}
private void Menu_Tool_DbcBalance_Click(object sender, RoutedEventArgs e)
{
Window_DbcBalance window_DbcBalance = new Window_DbcBalance();
window_DbcBalance.Show();
}
private void Menu_Tool_CRC_Click(object sender, RoutedEventArgs e)
{
try
{
// 修复路径获取方式
string appDir = AppDomain.CurrentDomain.BaseDirectory;
if (string.IsNullOrEmpty(appDir))
{
TextBox_Msg_AddLine("错误:无法获取应用程序目录");
return;
}
string crcToolPath = Path.Combine(appDir, "tools", "CRCToolS_V1.1.exe");
// TextBox_Msg_AddLine($"工具路径:{crcToolPath}");
if (File.Exists(crcToolPath))
{
var startInfo = new ProcessStartInfo(crcToolPath)
{
UseShellExecute = true,
WorkingDirectory = Path.GetDirectoryName(crcToolPath) ?? appDir // 添加空值保护
};
Process.Start(startInfo);
TextBox_Msg_AddLine("已启动CRC工具");
}
else
{
TextBox_Msg_AddLine("错误:CRC校验工具未找到,请检查安装完整性");
}
}
catch (Exception ex)
{
TextBox_Msg_AddLine($"发生异常:{ex.Message}");
TextBox_Msg_AddLine($"堆栈跟踪:{ex.StackTrace}");
}
}
private class RelayCommand : ICommand
{
private readonly Action _execute;
public RelayCommand(Action execute) => _execute = execute;
public bool CanExecute(object parameter) => true;
public void Execute(object parameter) => _execute();
public event EventHandler CanExecuteChanged;
}
private void Menu_Settings_Click(object sender, RoutedEventArgs e)
{
_isSettingsWindowOpen = true; // 标记设置窗口打开状态
var settingsWindow = new SettingsWindow(_appConfig);
settingsWindow.Owner = this; // 设置主窗口为Owner
if (settingsWindow.ShowDialog() == true)
{
// 应用新配置
_appConfig = settingsWindow.CurrentConfig;
_appConfig.Save();
// 新增热键重新注册
RegisterHotkeys();
}
_isSettingsWindowOpen = false; // 重置状态
}
}
public class ScriptProject
{
public string projectName { get; set; }
public string workDir { get; set; }
public List<ButtonGroup> buttonGroups { get; set; }
}
public class ButtonGroup
{
public string groupName { get; set; }
public List<ScriptButton> buttons { get; set; }
}
public class ScriptButton
{
[JsonProperty("title")]
public string Title { get; set; }
[JsonProperty("imgPath")]
public string ImgPath { get; set; }
[JsonProperty("scriptType")]
public string ScriptType { get; set; }
[JsonProperty("scriptContent")]
public string ScriptContent { get; set; }
[JsonProperty("scriptParameter")]
public string ScriptParameter { get; set; }
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。