diff --git a/plugins/topwindow/.gitignore b/plugins/topwindow/.gitignore
new file mode 100644
index 00000000..0008ed17
--- /dev/null
+++ b/plugins/topwindow/.gitignore
@@ -0,0 +1,6 @@
+node_modules/
+dist/
+build/
+temp-ztools/
+.env*
+*.log
diff --git a/plugins/topwindow/CHANGELOG.md b/plugins/topwindow/CHANGELOG.md
new file mode 100644
index 00000000..5d557cae
--- /dev/null
+++ b/plugins/topwindow/CHANGELOG.md
@@ -0,0 +1,9 @@
+# Changelog
+
+## v1.0.0
+
+- 窗口置顶/取消置顶功能
+- 通过 PowerShell 调用 Win32 API 实现
+- 系统通知即时反馈操作结果
+- 透明背景图标
+- 仅支持 Windows (win32) 平台
diff --git a/plugins/topwindow/README.md b/plugins/topwindow/README.md
new file mode 100644
index 00000000..3a2d229e
--- /dev/null
+++ b/plugins/topwindow/README.md
@@ -0,0 +1,41 @@
+# TopWindow - ZTools 窗口置顶插件
+
+一个简单高效的 Windows 窗口置顶插件,适用于 [ZTools](https://github.com/ZToolsCenter/ZTools)。
+
+## 功能
+
+- **一键置顶**:将当前活动窗口设为置顶(Always on Top)
+- **一键取消**:再次执行即可取消置顶
+- **窗口识别**:系统通知中显示被操作窗口的标题名称
+- **即时反馈**:通过系统通知提示操作结果
+
+## 使用方式
+
+1. 呼出 ZTools
+2. 输入 `置顶`、`TopWindow` 或 `窗口置顶`
+3. 当前窗口即被置顶/取消置顶,并收到系统通知
+
+## 技术实现
+
+- 通过 PowerShell 调用 Win32 API (`SetWindowPos`, `GetForegroundWindow`, `GetWindowText`)
+- 使用 `preload.js` 的 Node.js 能力执行系统级操作
+- 无需额外安装任何依赖
+
+## 文件结构
+
+```
+TopWindow-ztools/
+├── plugin.json # 插件配置
+├── preload.js # 插件入口(Node.js 环境)
+├── toggle-topmost.ps1 # 核心 PowerShell 脚本
+├── index.html # 插件界面
+└── logo.png # 插件图标
+```
+
+## 仅支持 Windows
+
+本插件使用 Windows 原生 API,仅支持 Windows 系统。
+
+## License
+
+MIT
diff --git a/plugins/topwindow/index.html b/plugins/topwindow/index.html
new file mode 100644
index 00000000..50211614
--- /dev/null
+++ b/plugins/topwindow/index.html
@@ -0,0 +1,66 @@
+
+
+
+
+
+ TopWindow
+
+
+
+
+
📌
+
正在切换置顶状态...
+
+
TopWindow 插件已启动
+
+
+
diff --git a/plugins/topwindow/logo.png b/plugins/topwindow/logo.png
new file mode 100644
index 00000000..b4593aa1
Binary files /dev/null and b/plugins/topwindow/logo.png differ
diff --git a/plugins/topwindow/plugin.json b/plugins/topwindow/plugin.json
new file mode 100644
index 00000000..32d7e13d
--- /dev/null
+++ b/plugins/topwindow/plugin.json
@@ -0,0 +1,20 @@
+{
+ "name": "topwindow",
+ "title": "窗口置顶",
+ "description": "一个简单的窗口置顶插件,支持切换当前窗口的置顶状态。",
+ "author": "evanwen97-ops",
+ "version": "1.0.0",
+ "logo": "logo.png",
+ "main": "index.html",
+ "preload": "preload.js",
+ "platform": ["win32"],
+ "features": [
+ {
+ "code": "topwindow",
+ "explain": "将当前窗口置顶或取消置顶",
+ "icon": "logo.png",
+ "cmds": ["TopWindow", "窗口置顶", "置顶"],
+ "platform": ["win32"]
+ }
+ ]
+}
diff --git a/plugins/topwindow/preload.js b/plugins/topwindow/preload.js
new file mode 100644
index 00000000..c9fb6a5b
--- /dev/null
+++ b/plugins/topwindow/preload.js
@@ -0,0 +1,60 @@
+const { exec } = require('child_process');
+const path = require('path');
+
+/**
+ * 切换当前窗口的置顶状态
+ * 调用同目录下的 toggle-topmost.ps1 脚本完成:
+ * 1. 获取当前前台窗口句柄和窗口标题
+ * 2. 切换 TOPMOST 状态
+ * 3. 弹出一个自动消失的 Toast 提示(含窗口名称)
+ */
+function toggleTopMost() {
+ // 隐藏 ZTools 主窗口,将焦点还给之前的窗口
+ try {
+ window.ztools.hideMainWindow(true);
+ } catch (e) {
+ console.error('hideMainWindow failed:', e);
+ }
+
+ // 等待焦点完全切换回目标窗口
+ setTimeout(() => {
+ // 获取 ps1 脚本的绝对路径(与 preload.js 同目录)
+ const scriptPath = path.join(__dirname, 'toggle-topmost.ps1');
+ const command = 'powershell -NoProfile -ExecutionPolicy Bypass -File "' + scriptPath + '"';
+
+ exec(command, (error, stdout, stderr) => {
+ if (error) {
+ console.error('TopWindow exec error:', error.message);
+ try {
+ window.ztools.showNotification('TopWindow 执行失败: ' + error.message);
+ } catch (e) { /* ignore */ }
+ } else {
+ // 解析结果: "Pinned||窗口标题" 或 "Unpinned||窗口标题"
+ const output = stdout.trim();
+ const parts = output.split('||');
+ const action = parts[0] || '';
+ const title = parts[1] || '';
+
+ if (action === 'Pinned') {
+ window.ztools.showNotification('已置顶: ' + title);
+ } else if (action === 'Unpinned') {
+ window.ztools.showNotification('已取消置顶: ' + title);
+ } else if (action === 'NoWindow') {
+ window.ztools.showNotification('未找到活动窗口');
+ }
+ }
+
+ // 退出插件
+ setTimeout(() => {
+ try { window.ztools.outPlugin(); } catch (e) { /* ignore */ }
+ }, 200);
+ });
+ }, 350);
+}
+
+// 插件进入时触发
+window.ztools.onPluginEnter(({ code, type, payload }) => {
+ if (code === 'topwindow') {
+ toggleTopMost();
+ }
+});
diff --git a/plugins/topwindow/toggle-topmost.ps1 b/plugins/topwindow/toggle-topmost.ps1
new file mode 100644
index 00000000..174cac32
--- /dev/null
+++ b/plugins/topwindow/toggle-topmost.ps1
@@ -0,0 +1,54 @@
+$code = @'
+using System;
+using System.Text;
+using System.Runtime.InteropServices;
+public class Win32Top {
+ [DllImport("user32.dll")]
+ public static extern IntPtr GetForegroundWindow();
+
+ [DllImport("user32.dll")]
+ public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
+
+ [DllImport("user32.dll")]
+ public static extern int GetWindowLong(IntPtr hWnd, int nIndex);
+
+ [DllImport("user32.dll", CharSet = CharSet.Unicode)]
+ public static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);
+
+ public const int GWL_EXSTYLE = -20;
+ public const int WS_EX_TOPMOST = 0x00000008;
+ public const uint SWP_NOSIZE = 0x0001;
+ public const uint SWP_NOMOVE = 0x0002;
+ public static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
+ public static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2);
+
+ public static string GetTitle(IntPtr hwnd) {
+ StringBuilder sb = new StringBuilder(512);
+ GetWindowText(hwnd, sb, sb.Capacity);
+ return sb.ToString();
+ }
+}
+'@
+try { Add-Type -TypeDefinition $code -ErrorAction Stop } catch {}
+
+$hwnd = [Win32Top]::GetForegroundWindow()
+if ($hwnd -eq [IntPtr]::Zero) {
+ Write-Output "NoWindow||"
+ exit
+}
+
+$windowTitle = [Win32Top]::GetTitle($hwnd)
+if ([string]::IsNullOrWhiteSpace($windowTitle)) {
+ $windowTitle = "(unnamed)"
+}
+
+$exStyle = [Win32Top]::GetWindowLong($hwnd, [Win32Top]::GWL_EXSTYLE)
+$flags = [Win32Top]::SWP_NOSIZE -bor [Win32Top]::SWP_NOMOVE
+
+if (($exStyle -band [Win32Top]::WS_EX_TOPMOST) -eq [Win32Top]::WS_EX_TOPMOST) {
+ [Win32Top]::SetWindowPos($hwnd, [Win32Top]::HWND_NOTOPMOST, 0, 0, 0, 0, $flags) | Out-Null
+ Write-Output "Unpinned||$windowTitle"
+} else {
+ [Win32Top]::SetWindowPos($hwnd, [Win32Top]::HWND_TOPMOST, 0, 0, 0, 0, $flags) | Out-Null
+ Write-Output "Pinned||$windowTitle"
+}