feat(windows): Phase 6 C1 — 单实例 mutex + HKCU Run 启动项
- src/windows/mod.rs: cfg(windows) 模块入口,pub use single_
instance + startup;其他 Phase 6 模块(C2 托盘 / C3 Toast / URL
打开)在后续 commit 加
- src/windows/single_instance.rs: CreateMutexExW("Local\\...")
→ mutex 名称 user-scope(多 RDP 会话各自能跑一个实例);第
二参 bInitialOwner=true 让 GetLastError() 可靠;返回 Acquired
/ AlreadyRunning enum
- src/windows/startup.rs: HKCU\Software\Microsoft\Windows\
CurrentVersion\Run\WindowsGotifyClientRust = 当前 exe 路径;set_
enabled / is_enabled 接口给 C2 Settings toggle 留口子;自定义
Win32Error 类型(windows-sys 0.59 没有 core::Error)
- src/lib.rs: 加 #[cfg(windows)] pub mod windows 入口
- src/main.rs: 启动前 enforce_single_instance() 检查;已有实
例直接 std::process::exit(0)(不抢前台窗口,留给 C2 tray
拿 hwnd 后再做)
- Cargo.toml: windows-sys 0.59 features 加 Win32 / Win32_Security
/ Win32_Foundation / Win32_System_Threading / Win32_System_
Registry / Win32_UI_WindowsAndMessaging / Win32_UI_Shell
避坑:
- windows-sys 0.59 没有 CreateMutexW(只是宏名 / 16-bit 兼容)
→ 用 CreateMutexExW
- HANDLE 不是 newtype struct,是裸 *mut c_void → 直接 as
isize,不要 .0
- CreateMutex[A/ExA/ExW/W] 全部 cfg-gated 在 Win32_Security feature
→ 必须开
- windows-sys 子 feature(Win32_System_Threading 等)依赖顶层
Win32 feature → 必须同时开
- std::mem::zeroed() 必须放 unsafe block 里
验证:cargo build / build --release 都 exit 0,0 warning
- cargo test: 15 passed; 0 failed
- debug 35.56 MB, subsystem = WINDOWS_CUI
- release 9.77 MB, subsystem = WINDOWS_GUI
- 实际功能(重复启动会 exit 0)只能手测;test 只能覆盖 JSON /
Rust 内部状态
This commit is contained in:
+16
@@ -44,6 +44,22 @@ reqwest = { version = "0.12", default-features = false, features = ["blocking",
|
||||
# --- Date/time (Phase 3 C2 convert Gotify RFC3339) ---
|
||||
chrono = { version = "0.4", default-features = false, features = ["clock", "serde"] }
|
||||
|
||||
# --- Windows-only (Phase 6 integration) ---
|
||||
# `windows-sys` is the low-level ABI layer of `windows-rs`. We only pull
|
||||
# the focused feature subsets we actually use (mutex, registry, message
|
||||
# loop, windowing); AGENTS.md §1 forbids pulling the umbrella `windows`
|
||||
# crate wholesale. `Win32` is the umbrella feature that gates the
|
||||
# `Win32_*` sub-features.
|
||||
windows-sys = { version = "0.59", features = [
|
||||
"Win32",
|
||||
"Win32_Foundation",
|
||||
"Win32_Security",
|
||||
"Win32_System_Threading",
|
||||
"Win32_System_Registry",
|
||||
"Win32_UI_WindowsAndMessaging",
|
||||
"Win32_UI_Shell",
|
||||
] }
|
||||
|
||||
# --- WebSocket (Phase 4 real-time stream) ---
|
||||
tungstenite = { version = "0.21", default-features = false, features = ["rustls-tls-webpki-roots", "handshake"] }
|
||||
url = "2"
|
||||
|
||||
Reference in New Issue
Block a user