### InkCanvasForClass Startup Command-Line Arguments Source: https://context7.com/inkcanvasforclass/community/llms.txt Control application startup behavior using command-line arguments for scenarios like shortcut configuration, external calls, and automation. Examples include launching directly into whiteboard mode or initiating the update process. ```bash # 直接以白板模式启动(跳过浮动栏,直接进入黑白板模式) InkCanvasForClass.exe --brode # 以更新模式启动(由自动更新系统内部调用,用户无需手动使用) InkCanvasForClass.exe --update-mode \ --old-process-id=5678 \ --extract-path="C:\ Program Files\InkCanvasForClass\AutoUpdate\Extract_1.7.18.0" \ --target-path="C:\ Program Files\InkCanvasForClass" \ --is-silence=False # 跳过互斥锁检查启动(更新完成后由更新进程调用) InkCanvasForClass.exe --final-app --skip-mutex-check ``` -------------------------------- ### Manage Auto Update Lines and Downloads Source: https://context7.com/inkcanvasforclass/community/llms.txt Check available download lines and their latency, clear cache for re-testing, manually select a line group for download, or initiate a manual download and install for a specific historical version. You can also cancel ongoing downloads and check if the application is currently in a silent period to avoid disruptions. ```csharp // 查看所有可用线路及延迟(缓存 15 分钟) var ordered = await AutoUpdateHelper.GetAvailableLineGroupsOrdered(UpdateChannel.Release); // 输出示例: // 1. inkeys (延迟: 38ms) // 2. bgithub备用 (延迟: 120ms) // 3. kkgithub线路 (延迟: 185ms) // 4. gh-proxy (延迟: 210ms) // 清除线路缓存(强制重新测速) AutoUpdateHelper.InvalidateOrderedGroupsCache(); // 手动指定线路组下载 var inkeysGroup = AutoUpdateHelper.ChannelLineGroups[UpdateChannel.Release] .First(g => g.GroupName == "inkeys"); bool ok = await AutoUpdateHelper.DownloadSetupFile("1.7.18.0", inkeysGroup); // 手动下载并安装指定历史版本(版本回滚场景) bool rollback = await AutoUpdateHelper.StartManualDownloadAndInstall( version: "1.7.15.0", channel: UpdateChannel.Release, progressCallback: (pct, msg) => Console.WriteLine($"{pct:F0}% - {msg}") ); // 取消正在进行的下载 AutoUpdateHelper.RequestCancelDownload(); // 获取静默期配置(避免上课时段自动更新打扰) bool inSilence = AutoUpdateWithSilenceTimeComboBox.CheckIsInSilencePeriod( startTime: "22:00", endTime: "06:00" ); Console.WriteLine($"当前是否在静默期: {inSilence}"); ``` -------------------------------- ### Automated System Updates with AutoUpdateHelper Source: https://context7.com/inkcanvasforclass/community/llms.txt Implement an automated update system that checks for new versions via GitHub Releases or fallback text files. Supports multiple channels, tiered rollouts, and provides options for downloading, installing, and retrieving update logs. ```csharp // 检测是否有新版本可用(Release 稳定通道) var (remoteVersion, lineGroup, releaseNotes) = await AutoUpdateHelper.CheckForUpdates( channel: UpdateChannel.Release, // Release / Preview / Beta alwaysGetRemote: false, // 是否强制获取远程版本(忽略版本比较) isVersionFix: false // 版本修复模式(绕过分级推送限制) ); if (remoteVersion != null) { Console.WriteLine($"发现新版本: {remoteVersion}"); Console.WriteLine($"更新日志:\n{releaseNotes}"); // 使用最快线路下载(支持多线路自动切换 + 多线程分块下载) var groups = await AutoUpdateHelper.GetAvailableLineGroupsOrdered(UpdateChannel.Release); bool downloaded = await AutoUpdateHelper.DownloadSetupFileWithFallback( version: remoteVersion, groups: groups, progressCallback: (percent, msg) => Console.WriteLine($"[{percent:F1}%] {msg}") ); // 下载进度示例输出: // [0.0%] 尝试使用32线程下载 // [23.5%] 多线程下载中(32线程): 23.5% // [100.0%] 多线程下载完成(32线程) if (downloaded) { // 安装新版本(解压 ZIP → 启动新进程替换文件 → 退出当前进程) AutoUpdateHelper.InstallNewVersionApp(remoteVersion, isInSilence: false); } } else { Console.WriteLine("当前已是最新版本"); } // 获取更新日志(自动选最快线路) string log = await AutoUpdateHelper.GetUpdateLog(UpdateChannel.Release); // 一键版本修复(强制重新下载并安装当前通道最新版) bool fixed = await AutoUpdateHelper.FixVersion(UpdateChannel.Release); // 获取所有历史版本列表(用于版本回滚 UI) var releases = await AutoUpdateHelper.GetAllGithubReleases(UpdateChannel.Release); foreach (var (ver, url, notes) in releases) Console.WriteLine($"{ver}: {url}"); ``` -------------------------------- ### AutoUpdateHelper Source: https://context7.com/inkcanvasforclass/community/llms.txt Provides functionality for an automatic update system, including checking for new versions across multiple channels, downloading installers, and applying updates. ```APIDOC ## AutoUpdateHelper `AutoUpdateHelper` implements an automatic update mechanism with support for multiple network lines, channels, and tiered release strategies. It prioritizes checking for new versions via the GitHub Releases API and falls back to a text file solution if the API check fails. Update distribution is determined based on device ID. ### Checking for Updates Asynchronously checks for available updates for a specified channel. It can optionally bypass version comparison to always fetch remote information. ```csharp // Check for new versions in the Release channel var (remoteVersion, lineGroup, releaseNotes) = await AutoUpdateHelper.CheckForUpdates( channel: UpdateChannel.Release, // Options: Release, Preview, Beta alwaysGetRemote: false, // Set to true to force fetching remote version info isVersionFix: false // Set to true for version fix mode (bypasses tiered push) ); if (remoteVersion != null) { Console.WriteLine($"New version found: {remoteVersion}"); Console.WriteLine($"Release Notes:\n{releaseNotes}"); // Download the setup file using the fastest available line var groups = await AutoUpdateHelper.GetAvailableLineGroupsOrdered(UpdateChannel.Release); bool downloaded = await AutoUpdateHelper.DownloadSetupFileWithFallback( version: remoteVersion, groups: groups, progressCallback: (percent, msg) => Console.WriteLine($"[{percent:F1}%] {msg}") ); // Example progress output: // [0.0%] Attempting download with 32 threads // [23.5%] Downloading with multiple threads (32 threads): 23.5% // [100.0%] Multi-threaded download complete (32 threads) if (downloaded) { // Install the new version AutoUpdateHelper.InstallNewVersionApp(remoteVersion, isInSilence: false); } } else { Console.WriteLine("You are already on the latest version."); } ``` ### Getting Update Log Retrieves the update log for a specified channel, automatically selecting the fastest network line. ```csharp string log = await AutoUpdateHelper.GetUpdateLog(UpdateChannel.Release); ``` ### Version Fix Forces a re-download and installation of the latest version for the current channel. ```csharp bool fixed = await AutoUpdateHelper.FixVersion(UpdateChannel.Release); ``` ### Getting All GitHub Releases Fetches a list of all historical releases from GitHub for a given channel, useful for building version rollback UIs. ```csharp var releases = await AutoUpdateHelper.GetAllGithubReleases(UpdateChannel.Release); foreach (var (ver, url, notes) in releases) Console.WriteLine($"{ver}: {url}"); ``` ``` -------------------------------- ### Implement a Minimal Plugin with IPlugin Interface Source: https://context7.com/inkcanvasforclass/community/llms.txt Demonstrates the basic structure of a plugin by implementing the IPlugin interface. It shows how to define metadata, initialize with the host, and provide UI elements. ```csharp using Ink_Canvas.Plugins; public class MyDemoPlugin : PluginBase { // 插件唯一标识(建议用反向域名格式) public override string Id => "com.example.my-demo-plugin"; public override string Name => "我的演示插件"; public override string Version => "1.0.0"; public override string Description => "一个展示 ICC CE 插件开发的示例插件"; public override string Author => "ExampleDev"; // 加载顺序(数字越小越先加载) public override int Order => 100; public override void Initialize(IPluginHost host) { base.Initialize(host); // 通过 IPluginHost 记录日志 Log("MyDemoPlugin 已初始化"); // 通过 IPluginHost 获取内置服务 var inkSvc = GetService(); if (inkSvc != null) { // 调用主程序服务:打开白板 inkSvc.OpenWhiteboard(); } } public override void Shutdown() { Log("MyDemoPlugin 正在关闭"); } // 返回插件的主视图(WPF UIElement),null 表示无 UI public override object GetMainView() => new MyPluginMainView(); // 返回插件的设置视图,null 表示无设置页 public override object GetSettingsView() => null; } // 插件宿主接口参考 // host.Log("消息"); // host.LogError("错误消息", exception); // host.GetService(); // 获取墨迹画布服务 // host.RegisterService(myService); // 注册自定义服务供其他插件使用 ``` -------------------------------- ### Implementing a Basic Plugin Source: https://context7.com/inkcanvasforclass/community/llms.txt Demonstrates how to create a simple plugin by implementing the IPlugin interface, including metadata, initialization, and shutdown logic. ```APIDOC ## Implementing a Basic Plugin This example shows a minimal plugin implementation. It defines basic metadata and uses the `IPluginHost` to log messages and interact with the `IInkCanvasService`. ### Plugin Metadata - **Id**: Unique identifier for the plugin (e.g., `com.example.my-demo-plugin`). - **Name**: Display name of the plugin (e.g., `我的演示插件`). - **Version**: Plugin version (e.g., `1.0.0`). - **Description**: A brief description of the plugin's purpose. - **Author**: The developer's name. - **Order**: Load order priority (lower numbers load first). ### Lifecycle Methods - **Initialize(IPluginHost host)**: Called when the plugin is loaded. Receives the `IPluginHost` for communication. - **Shutdown()**: Called when the plugin is unloaded. - **GetMainView()**: Returns the main UI element for the plugin, or null if none. - **GetSettingsView()**: Returns the settings UI element for the plugin, or null if none. ### Example Code ```csharp // 实现一个最简插件示例 using Ink_Canvas.Plugins; public class MyDemoPlugin : PluginBase { // 插件唯一标识(建议用反向域名格式) public override string Id => "com.example.my-demo-plugin"; public override string Name => "我的演示插件"; public override string Version => "1.0.0"; public override string Description => "一个展示 ICC CE 插件开发的示例插件"; public override string Author => "ExampleDev"; // 加载顺序(数字越小越先加载) public override int Order => 100; public override void Initialize(IPluginHost host) { base.Initialize(host); // 通过 IPluginHost 记录日志 Log("MyDemoPlugin 已初始化"); // 通过 IPluginHost 获取内置服务 var inkSvc = GetService(); if (inkSvc != null) { // 调用主程序服务:打开白板 inkSvc.OpenWhiteboard(); } } public override void Shutdown() { Log("MyDemoPlugin 正在关闭"); } // 返回插件的主视图(WPF UIElement),null 表示无 UI public override object GetMainView() => new MyPluginMainView(); // 返回插件的设置视图,null 表示无设置页 public override object GetSettingsView() => null; } // 插件宿主接口参考 // host.Log("消息"); // host.LogError("错误消息", exception); // host.GetService(); // 获取墨迹画布服务 // host.RegisterService(myService); // 注册自定义服务供其他插件使用 ``` ``` -------------------------------- ### Handle Update Mode Startup Parameters Source: https://context7.com/inkcanvasforclass/community/llms.txt Process command-line arguments at the application's startup entry point to handle the update mode. This involves waiting for the old process to exit, copying files, and then restarting the final application. ```csharp // 在 App.xaml.cs 的启动入口处处理更新模式 string[] args = Environment.GetCommandLineArgs(); bool isUpdateMode = AutoUpdateHelper.HandleUpdateModeStartup(args); if (isUpdateMode) { // 更新模式:等待旧进程退出 → 复制文件 → 启动最终应用 → 退出更新进程 // 命令行参数格式: // InkCanvasForClass.exe --update-mode // --old-process-id=1234 // --extract-path="C:\...\AutoUpdate\Extract_1.7.18.0" // --target-path="C:\...\InkCanvasForClass" // --is-silence=True return; // 等待更新完成后自动退出 } // 最终应用启动(更新完成后由更新进程以此参数启动) // InkCanvasForClass.exe --final-app --skip-mutex-check if (args.Contains("--final-app")) { // 跳过单例互斥检查,直接启动正常应用逻辑 } ``` -------------------------------- ### Utilize IPluginHost for Logging and Service Access Source: https://context7.com/inkcanvasforclass/community/llms.txt Shows how to use the IPluginHost interface within a plugin to log messages, handle errors, access core services like IInkCanvasService and IAppRestartService, and register custom services. ```csharp // 在插件内部使用宿主服务的完整示例 public override void Initialize(IPluginHost host) { base.Initialize(host); // 1. 普通日志 host.Log("[MyPlugin] 初始化开始"); // 2. 错误日志(可附带异常) try { DoSomethingRisky(); } catch (Exception ex) { host.LogError("[MyPlugin] 操作失败", ex); } // 3. 获取内置 IInkCanvasService:控制白板开关 var inkSvc = host.GetService(); if (inkSvc != null) { inkSvc.OpenWhiteboard(); // 同步打开白板 // await inkSvc.OpenWhiteboardAsync(500); // 延迟500ms异步打开 // inkSvc.CloseWhiteboard(); // 关闭白板 } // 4. 获取内置 IAppRestartService:控制应用重启 var restartSvc = host.GetService(); if (restartSvc != null) { bool isAdmin = restartSvc.IsRunningAsAdmin; // restartSvc.RestartWithCurrentPrivileges(); // 以当前权限重启 // restartSvc.RestartAsAdmin(); // 以管理员权限重启 // restartSvc.SwitchToUIATopMostAndRestart(); // 切换到UIA置顶模式重启 } // 5. 注册自定义服务(供其他插件使用) host.RegisterService(new MyCustomServiceImpl()); } ``` -------------------------------- ### Control Whiteboard with IInkCanvasService Source: https://context7.com/inkcanvasforclass/community/llms.txt Illustrates how to use the IInkCanvasService to control the whiteboard, including opening and closing it synchronously or asynchronously with a delay. ```csharp // 异步延迟打开白板示例 public class AutoWhiteboardPlugin : PluginBase { public override string Id => "com.example.auto-whiteboard"; public override string Name => "自动白板插件"; public override string Version => "1.0.0"; public override string Description => "定时自动打开白板"; public override string Author => "Dev"; public override int Order => 50; private IInkCanvasService _inkSvc; public override void Initialize(IPluginHost host) { base.Initialize(host); _inkSvc = GetService(); } // 由外部逻辑(如定时器)调用 public async Task OpenWithDelay(int delayMs = 1000) { if (_inkSvc == null) return; // 延迟指定毫秒后打开白板 await _inkSvc.OpenWhiteboardAsync(delayMs); } public void ToggleWhiteboard(bool open) { if (_inkSvc == null) return; if (open) _inkSvc.OpenWhiteboard(); // 同步打开 else _inkSvc.CloseWhiteboard(); // 同步关闭 } } ``` -------------------------------- ### Using IPluginHost for Host Communication Source: https://context7.com/inkcanvasforclass/community/llms.txt Details on how plugins can use the `IPluginHost` interface to log messages, handle errors, access core services, and register their own services. ```APIDOC ## Using IPluginHost for Host Communication The `IPluginHost` interface is central to plugin-application interaction. It provides capabilities for logging, service discovery, and service registration. ### Logging - **Log(string message)**: Records a general informational message. - **LogError(string message, Exception exception = null)**: Records an error message, optionally with an associated exception. ### Service Access - **GetService()**: Retrieves an instance of a registered service of type `T`. Returns `null` if the service is not found. ### Service Registration - **RegisterService(T serviceInstance)**: Registers an instance of a custom service of type `T` so other plugins can access it via `GetService()`. ### Example Usage in Initialize ```csharp // 在插件内部使用宿主服务的完整示例 public override void Initialize(IPluginHost host) { base.Initialize(host); // 1. 普通日志 host.Log("[MyPlugin] 初始化开始"); // 2. 错误日志(可附带异常) try { DoSomethingRisky(); } catch (Exception ex) { host.LogError("[MyPlugin] 操作失败", ex); } // 3. 获取内置 IInkCanvasService:控制白板开关 var inkSvc = host.GetService(); if (inkSvc != null) { inkSvc.OpenWhiteboard(); // 同步打开白板 // await inkSvc.OpenWhiteboardAsync(500); // 延迟500ms异步打开 // inkSvc.CloseWhiteboard(); // 关闭白板 } // 4. 获取内置 IAppRestartService:控制应用重启 var restartSvc = host.GetService(); if (restartSvc != null) { bool isAdmin = restartSvc.IsRunningAsAdmin; // restartSvc.RestartWithCurrentPrivileges(); // 以当前权限重启 // restartSvc.RestartAsAdmin(); // 以管理员权限重启 // restartSvc.SwitchToUIATopMostAndRestart(); // 切换到UIA置顶模式重启 } // 5. 注册自定义服务(供其他插件使用) host.RegisterService(new MyCustomServiceImpl()); } ``` ``` -------------------------------- ### Hotkey Configuration File Structure Source: https://context7.com/inkcanvasforclass/community/llms.txt Defines the JSON structure for storing and loading hotkey configurations. This file allows users to customize key bindings, which are automatically loaded on startup and applied immediately upon modification. ```json { "Version": "1.0", "LastModified": "2025-01-28T15:30:00", "Hotkeys": [ { "Name": "Undo", "Key": "Z", "Modifiers": "Control" }, { "Name": "Redo", "Key": "Y", "Modifiers": "Control" }, { "Name": "Clear", "Key": "E", "Modifiers": "Control" }, { "Name": "Paste", "Key": "V", "Modifiers": "Control" }, { "Name": "SelectTool", "Key": "S", "Modifiers": "Alt" }, { "Name": "DrawTool", "Key": "D", "Modifiers": "Alt" }, { "Name": "EraserTool", "Key": "E", "Modifiers": "Alt" }, { "Name": "BlackboardTool","Key": "B", "Modifiers": "Alt" }, { "Name": "QuitDrawTool", "Key": "Q", "Modifiers": "Alt" }, { "Name": "Pen1", "Key": "D1", "Modifiers": "Alt" }, { "Name": "Pen2", "Key": "D2", "Modifiers": "Alt" }, { "Name": "Pen3", "Key": "D3", "Modifiers": "Alt" }, { "Name": "Pen4", "Key": "D4", "Modifiers": "Alt" }, { "Name": "Pen5", "Key": "D5", "Modifiers": "Alt" }, { "Name": "DrawLine", "Key": "L", "Modifiers": "Alt" }, { "Name": "Screenshot", "Key": "C", "Modifiers": "Alt" }, { "Name": "QuickDraw", "Key": "K", "Modifiers": "Alt" }, { "Name": "Hide", "Key": "V", "Modifiers": "Alt" }, { "Name": "Exit", "Key": "Escape", "Modifiers": "None" } ] } ``` -------------------------------- ### Plugin Metadata Structure Source: https://context7.com/inkcanvasforclass/community/llms.txt The PluginInfo structure holds plugin instance references and loading status, populated by the plugin host. Developers can use the IsLoaded flag to check initialization status and the Order property to manage plugin initialization sequence. ```csharp // PluginInfo 数据结构示例(由宿主自动填充,开发者无需手动创建) var info = new PluginInfo { Id = "com.example.my-demo-plugin", Name = "我的演示插件", Version = "1.0.0", Description = "一个展示 ICC CE 插件开发的示例插件", Author = "ExampleDev", Order = 100, Instance = new MyDemoPlugin(), IsLoaded = true }; // 宿主通过 IsLoaded 判断插件是否已成功初始化 if (info.IsLoaded) Console.WriteLine($"插件 [{info.Name} v{info.Version}] 已加载,作者:{info.Author}"); // Order 越小,插件越先被初始化(适用于有依赖关系的插件) // 建议约定: // 0-99 : 核心/基础插件 // 100-499: 普通功能插件 // 500+ : 扩展/装饰性插件 ``` -------------------------------- ### Manage Application Restarts with IAppRestartService Source: https://context7.com/inkcanvasforclass/community/llms.txt Demonstrates various methods provided by IAppRestartService for restarting the application with different privilege levels (admin, normal) and top-most modes. ```csharp var restartSvc = GetService(); if (restartSvc == null) return; // 查询当前权限 bool isAdmin = restartSvc.IsRunningAsAdmin; Console.WriteLine($"当前是否以管理员运行: {isAdmin}"); // 以当前权限重启(不改变权限级别) restartSvc.RestartWithCurrentPrivileges(); // 提权后重启(触发 UAC 弹窗) if (!isAdmin) restartSvc.RestartAsAdmin(); // 降权后重启 if (isAdmin) restartSvc.RestartAsNormal(); // 切换到 UIA 置顶模式并重启(用于特殊窗口置顶场景) restartSvc.SwitchToUIATopMostAndRestart(); // 切换到普通置顶模式并重启 restartSvc.SwitchToNormalTopMostAndRestart(); // 使用 IsRunningAsAdmin 接受任意 bool 参数重启 restartSvc.RestartApp(asAdmin: true); ``` -------------------------------- ### Manage Global Hotkeys with GlobalHotkeyManager Source: https://context7.com/inkcanvasforclass/community/llms.txt Initialize and use GlobalHotkeyManager for registering, unregistering, and updating custom hotkeys. Supports persistence via configuration files and multi-screen awareness. ```csharp // 初始化(在 MainWindow 内部使用) var hotkeyManager = new GlobalHotkeyManager(mainWindow); // 1. 注册自定义快捷键 bool ok = hotkeyManager.RegisterHotkey( hotkeyName: "MyAction", key: Key.F1, modifiers: ModifierKeys.Control | ModifierKeys.Shift, action: () => Console.WriteLine("自定义操作被触发") ); // 2. 注销单个快捷键 hotkeyManager.UnregisterHotkey("MyAction"); // 3. 更新快捷键(自动保存到配置文件) hotkeyManager.UpdateHotkey("Screenshot", Key.P, ModifierKeys.Control); // 4. 从配置文件重新加载(适用于用户在设置界面修改后) hotkeyManager.LoadHotkeysFromSettings(); // 5. 查询已注册快捷键列表 List list = hotkeyManager.GetRegisteredHotkeys(); foreach (var h in list) Console.WriteLine($"{h.Name}: {h.Modifiers}+{h.Key}"); // 6. 工具模式联动(切换到鼠标模式时可临时禁用快捷键) hotkeyManager.UpdateHotkeyStateForToolMode(isMouseMode: true); // 鼠标模式 hotkeyManager.UpdateHotkeyStateForToolMode(isMouseMode: false); // 批注模式 // 7. 多屏幕支持 hotkeyManager.RefreshMultiScreenSettings(); // 刷新多屏配置 Console.WriteLine(hotkeyManager.GetCurrentScreenInfo()); // 输出:多屏幕环境 - 当前屏幕: \\.\\DISPLAY1 (1920x1080) ``` -------------------------------- ### GlobalHotkeyManager Source: https://context7.com/inkcanvasforclass/community/llms.txt Manages global hotkeys, allowing registration, unregistration, configuration persistence, and multi-screen awareness. Hotkey configurations are stored in HotkeyConfig.json. ```APIDOC ## GlobalHotkeyManager `GlobalHotkeyManager` is a class that facilitates the management of global hotkeys within an application. It is built upon the NHotkey library and supports registering, unregistering, persisting hotkey configurations to a file, and adapting to multi-screen environments. The configuration file is located at `{AppRoot}/Configs/HotkeyConfig.json`. ### Initialization Initialize the `GlobalHotkeyManager` within your main window context. ```csharp var hotkeyManager = new GlobalHotkeyManager(mainWindow); ``` ### Registering a Hotkey Register a custom hotkey with a specific name, key, modifier combination, and an action to be executed. ```csharp bool ok = hotkeyManager.RegisterHotkey( hotkeyName: "MyAction", key: Key.F1, modifiers: ModifierKeys.Control | ModifierKeys.Shift, action: () => Console.WriteLine("Custom action triggered") ); ``` ### Unregistering a Hotkey Remove a previously registered hotkey by its name. ```csharp hotkeyManager.UnregisterHotkey("MyAction"); ``` ### Updating a Hotkey Update an existing hotkey's key and modifiers. This action automatically saves the changes to the configuration file. ```csharp hotkeyManager.UpdateHotkey("Screenshot", Key.P, ModifierKeys.Control); ``` ### Loading Hotkeys from Settings Reload hotkey configurations from the settings file. This is useful after user modifications in a settings interface. ```csharp hotkeyManager.LoadHotkeysFromSettings(); ``` ### Getting Registered Hotkeys Retrieve a list of all currently registered hotkeys. ```csharp List list = hotkeyManager.GetRegisteredHotkeys(); foreach (var h in list) Console.WriteLine($"{h.Name}: {h.Modifiers}+{h.Key}"); ``` ### Tool Mode Hotkey State Temporarily disable hotkeys when switching to a tool mode, such as a mouse mode. ```csharp hotkeyManager.UpdateHotkeyStateForToolMode(isMouseMode: true); // For mouse mode hotkeyManager.UpdateHotkeyStateForToolMode(isMouseMode: false); // For annotation mode ``` ### Multi-Screen Support Refresh multi-screen settings and get information about the current screen setup. ```csharp hotkeyManager.RefreshMultiScreenSettings(); // Refresh multi-screen configuration Console.WriteLine(hotkeyManager.GetCurrentScreenInfo()); // Example output: Multi-screen environment - Current screen: \\.\DISPLAY1 (1920x1080) ``` ## Hotkey Configuration File (HotkeyConfig.json) The hotkey configuration is stored in JSON format at `{AppRoot}/Configs/HotkeyConfig.json`. Users can customize key combinations, and these settings are loaded automatically on application startup and take effect immediately upon modification. ``` -------------------------------- ### IInkCanvasService for Whiteboard Control Source: https://context7.com/inkcanvasforclass/community/llms.txt Provides methods to control the main application's whiteboard, allowing plugins to open and close it synchronously or asynchronously. ```APIDOC ## IInkCanvasService for Whiteboard Control This service allows plugins to manage the state of the main application's whiteboard. ### Methods - **OpenWhiteboard()**: Opens the whiteboard immediately (synchronous). - **OpenWhiteboardAsync(int delayMs)**: Opens the whiteboard after a specified delay in milliseconds (asynchronous). - **CloseWhiteboard()**: Closes the whiteboard immediately (synchronous). ### Example Usage ```csharp // 异步延迟打开白板示例 public class AutoWhiteboardPlugin : PluginBase { public override string Id => "com.example.auto-whiteboard"; public override string Name => "自动白板插件"; public override string Version => "1.0.0"; public override string Description => "定时自动打开白板"; public override string Author => "Dev"; public override int Order => 50; private IInkCanvasService _inkSvc; public override void Initialize(IPluginHost host) { base.Initialize(host); _inkSvc = GetService(); } // 由外部逻辑(如定时器)调用 public async Task OpenWithDelay(int delayMs = 1000) { if (_inkSvc == null) return; // 延迟指定毫秒后打开白板 await _inkSvc.OpenWhiteboardAsync(delayMs); } public void ToggleWhiteboard(bool open) { if (_inkSvc == null) return; if (open) _inkSvc.OpenWhiteboard(); // 同步打开 else _inkSvc.CloseWhiteboard(); // 同步关闭 } } ``` ``` -------------------------------- ### IAppRestartService for Application Restart Control Source: https://context7.com/inkcanvasforclass/community/llms.txt Offers various methods for restarting the application with different privilege levels or windowing modes. ```APIDOC ## IAppRestartService for Application Restart Control This service provides flexible options for restarting the application, including privilege management and windowing behavior. ### Properties - **IsRunningAsAdmin**: A boolean indicating if the application is currently running with administrator privileges. ### Methods - **RestartWithCurrentPrivileges()**: Restarts the application without changing the current privilege level. - **RestartAsAdmin()**: Restarts the application with administrator privileges (may trigger UAC prompt). - **RestartAsNormal()**: Restarts the application with normal user privileges. - **SwitchToUIATopMostAndRestart()**: Restarts the application in a UIA top-most mode. - **SwitchToNormalTopMostAndRestart()**: Restarts the application in a normal top-most mode. - **RestartApp(bool asAdmin)**: A general restart method that takes a boolean to specify if the restart should be as administrator. ### Example Usage ```csharp var restartSvc = GetService(); if (restartSvc == null) return; // 查询当前权限 bool isAdmin = restartSvc.IsRunningAsAdmin; Console.WriteLine($"当前是否以管理员运行: {isAdmin}"); // 以当前权限重启(不改变权限级别) restartSvc.RestartWithCurrentPrivileges(); // 提权后重启(触发 UAC 弹窗) if (!isAdmin) restartSvc.RestartAsAdmin(); // 降权后重启 if (isAdmin) restartSvc.RestartAsNormal(); // 切换到 UIA 置顶模式并重启(用于特殊窗口置顶场景) restartSvc.SwitchToUIATopMostAndRestart(); // 切换到普通置顶模式并重启 restartSvc.SwitchToNormalTopMostAndRestart(); // 使用 IsRunningAsAdmin 接受任意 bool 参数重启 restartSvc.RestartApp(asAdmin: true); ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.