Skip to content

feat: add Windows support for pinixd and pinix CLI - #133

Open
yan5xu wants to merge 5 commits into
mainfrom
feat/windows-support
Open

feat: add Windows support for pinixd and pinix CLI#133
yan5xu wants to merge 5 commits into
mainfrom
feat/windows-support

Conversation

@yan5xu

@yan5xu yan5xu commented May 26, 2026

Copy link
Copy Markdown
Contributor

Summary

pinixdpinix CLI 能在 Windows 上编译和运行。

Changes

新文件 (9 个平台文件)

文件 用途
cmd/pinix/process_windows.go daemonSysProcAttr, checkProcessAlive, signalProcess 的 Windows 实现
cmd/pinix/daemon_process_unix.go bb-browser 进程组管理 (Unix: Setpgid + Kill(-pid))
cmd/pinix/daemon_process_windows.go bb-browser 进程组管理 (Windows: CREATE_NEW_PROCESS_GROUP)
internal/daemon/registry_flock_unix.go 文件锁 (Unix: syscall.Flock)
internal/daemon/registry_flock_windows.go 文件锁 (Windows: LockFileEx/UnlockFileEx)
internal/daemon/process_signal_unix.go Clip 进程终止 (Unix: SIGTERM)
internal/daemon/process_signal_windows.go Clip 进程终止 (Windows: Kill)
internal/pidfile/pidfile_unix.go 进程活性检查 (Unix: Signal(0))
internal/pidfile/pidfile_windows.go 进程活性检查 (Windows: OpenProcess)

修改文件 (8 个)

  • registry.go: 去掉 syscall.Flock,改用跨平台 lockFile/unlockFile
  • daemon.go: 去掉 syscall.Kill(-pid), Setpgid, SIGTERM,改用平台函数
  • process.go: stopProcesssendTermSignalfindBunBinary.exe 和 Windows 路径
  • pidfile.go: Signal(0) 改用 isProcessAlive
  • main.go (pinixd): signal.NotifyContextos.Interrupt 替代 syscall.SIGTERM
  • stop.go: 用 filepath.Join 替代手动 / 拼接;用 os.Interrupt 替代 syscall.SIGTERM
  • install.go: symlink 失败时 fallback 到复制文件(Windows 无 Developer Mode 时需要)
  • Makefile: 加 windows/amd64 构建目标

Verification

# Windows cross-compilation
GOOS=windows GOARCH=amd64 go build ./cmd/pinix   ✅
GOOS=windows GOARCH=amd64 go build ./cmd/pinixd  ✅
GOOS=windows GOARCH=amd64 go vet ./...           ✅

# Native (macOS) still works
go build ./cmd/pinix && go build ./cmd/pinixd     ✅
go vet ./...                                       ✅
go test ./...                                      ✅

# Linux cross-compilation
GOOS=linux GOARCH=amd64 go build ./cmd/pinix      ✅
GOOS=linux GOARCH=arm64 go build ./cmd/pinixd     ✅

Closes #132

yan5xu added 2 commits May 26, 2026 15:00
- Add process_windows.go with Windows-specific daemon process management
  (CREATE_NEW_PROCESS_GROUP, OpenProcess, GenerateConsoleCtrlEvent)
- Replace syscall.Flock with cross-platform file locking
  (LockFileEx/UnlockFileEx on Windows, syscall.Flock on Unix)
- Extract bb-browser process group management into platform files
  (Setpgid on Unix, CREATE_NEW_PROCESS_GROUP on Windows)
- Replace Process.Signal(SIGTERM) with platform-gated sendTermSignal
- Replace Signal(0) liveness check with OpenProcess on Windows
- Use os.Interrupt instead of syscall.SIGTERM for signal.NotifyContext
- Add .exe suffix and Windows path for bun binary detection
- Add symlink fallback to file copy for Windows without Developer Mode
- Fix path concatenation to use filepath.Join
- Add windows/amd64 build target to Makefile

Closes #132
@yan5xu

yan5xu commented May 26, 2026

Copy link
Copy Markdown
Contributor Author

Windows 实测结果

在 Windows Server 2022 (10.0.20348) 上完成端到端测试。

环境

  • OS: Windows Server 2022 Datacenter
  • Bun: 1.3.14 (从 npmmirror 安装)
  • 网络: ZeroTier LAN

测试结果

测试项 结果
pinixd --version
pinix daemon (前台运行) ✅ Hub + Runtime 正常启动
pinix hub list ✅ 连接 Hub 正常
pinix hub add @pinix/todo ✅ registry 下载 + bun install 成功 (12.72s)
pinix hub list (有 Clip) ✅ 显示 todo clip + 所有 commands
pinix invoke todo list ✅ Clip 进程启动、IPC 通信、返回 []
pinix stop ✅ 进程终止
pinix start (后台 detach) ⚠️ daemon 启动后立即退出

已知问题

pinix start 后台 daemon 化在 Windows 上不工作 — CREATE_NEW_PROCESS_GROUP | CREATE_NO_WINDOW 不足以让 daemon 在父进程退出后保持运行。需要改用 Windows Service 或其他机制。

核心功能(Hub、Runtime、Clip 安装和运行)全部正常。 daemon 化问题开单独 issue 跟踪。

yan5xu added 3 commits May 26, 2026 16:24
On Windows, OpenSSH Server places all session processes in a Job Object
with 'Kill on Job Close' and without 'Breakaway OK'. This means any
child process — even with DETACHED_PROCESS or CREATE_BREAKAWAY_FROM_JOB
— gets killed when the SSH session ends.

Fix: on Windows, 'pinix start' now launches the daemon via a Windows
Scheduled Task (schtasks), which runs outside the SSH Job Object. This
is the standard workaround recommended by the Win32-OpenSSH project
(PowerShell/Win32-OpenSSH#1032).

Also:
- Add SetConsoleCtrlHandler(NULL, TRUE) to ignore CTRL_CLOSE_EVENT
- Use DETACHED_PROCESS instead of CREATE_NO_WINDOW for daemon detach
- Use Process.Release() to detach Go process handle
- Extract startBackgroundDaemon into platform files

Verified on Windows Server 2022: pinix start -> SSH disconnect -> new
SSH session -> pinix hub list shows clips -> pinix invoke works -> pinix
stop works.
Usage: irm dl.pinixai.com/install.ps1 | iex

- Downloads pinix.exe + pinixd.exe to ~/.pinix/bin/
- Adds to user PATH
- Auto-installs Bun from npmmirror (China-friendly)
- Updates Makefile upload-cos to include Windows binaries and install.ps1
…r + bb-viewer)

One command installs everything:
  irm dl.pinixai.com/install.ps1 | iex

Components installed:
1. pinix.exe + pinixd.exe -> ~/.pinix/bin/
2. Bun (from npmmirror) -> ~/.bun/bin/
3. Node.js (from npmmirror) -> ~/.node/
4. bb-browser (npm) -> global
5. bb-viewer + DLLs -> ~/.bb-browser/bin/

All downloads use China-friendly mirrors (npmmirror).
Idempotent: skips already-installed components.
@yan5xu
yan5xu force-pushed the feat/windows-support branch 2 times, most recently from 6b69559 to 9603125 Compare June 2, 2026 11:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Windows 支持 — pinixd + pinix CLI 编译与运行

1 participant