feat(activity): install on Windows + Windows release asset (nanoya-biz/rkd#1147) #11
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/1147-activity-windows-install"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
This is the Windows half of nanoya-biz/rkd#1147 on the plugin side.
rkd-activitynow serves and pairs on Windows over the named pipe, andinstall/uninstallregister it as a per-user autostart inHKCU\…\Run. Av*tag also builds and attachesrkd-activity-<tag>-x86_64-pc-windows-msvc.tar.gz+.sha256.This compiles and passes clippy (
-D warnings, all targets, tests included) forx86_64-pc-windows-msvc, and it links with cargo-xwin, but it has never been run on Windows. Nobody here has a Windows machine.local/WINDOWS-CHECKLIST.mdstep 11 is how to check it.Refs nanoya-biz/rkd#1147
What changed
server/pipe.rsis a copy of rkd-terminal's named-pipe transport. It serves\\.\pipe\rkd-plugins-<SID>-activitywith an owner-only DACL, checks that each client is the same user, and refuses a secondserve.cli.rsgets the same Windowsconnect/request_code/ Ctrl+C handling as rkd-terminal. Before this PR,rkd-activity.exeonly printed "not available on this platform". Game detection on Windows is still out of scope (#1122), soservealways reports that nothing is being played.REG_SZvaluerkd-activity="<exe>" serveunderHKCU\Software\Microsoft\Windows\CurrentVersion\Run. The path is always quoted, so a profile path with a space in it works. It then stops anyservealready answering on the pipe, starts<exe> servewithDETACHED_PROCESS | CREATE_NO_WINDOW | CREATE_NEW_PROCESS_GROUP(it also triesCREATE_BREAKAWAY_FROM_JOBand drops that flag if the job forbids breakaway), and waits until the newserveanswers. Running it again sets the same value and restartsserve, so an upgraded binary takes over at once, the same as systemd'srestart.--no-startonly writes the value.serveon the pipe. It finds that process withGetNamedPipeServerProcessIdwhile holding a client handle, then callsTerminateProcessand waits for it to exit. Running it when nothing is installed is fine. The binary stays for the app to remove, as in the launchd/systemd flow.installaccepts: the same rules as unix. The path is canonical with\\?\stripped.%TEMP%and cargo build folders are refused unless--force. A binary another user could replace is refused even with--force: the file and every folder above it must be owned by the user, SYSTEM, Administrators or TrustedInstaller, and must not grant anyone else DELETE, WRITE_DAC, WRITE_OWNER or GENERIC_WRITE/ALL. On foldersFILE_DELETE_CHILDis also refused, and on the exeFILE_WRITE_DATA/APPEND_DATA. Inherit-only ACEs are ignored, soC:\itself passes, but a folder created directly inC:\fails because it inherits Authenticated Users' Modify.autostart.rsholds all the rules (Run value string, path choice, install/uninstall flow, ACL rule) as plain strings behind aSystemtrait, and they are unit-tested on every host.autostart/win.rsholds the Win32 calls.build_dir_reasonmoved fromservice.rstocli.rsso both platforms share it.windows-sys0.61, the versionrkd-local-linkalready uses. The lockfile gains one dependency edge and no new crate. I chose it overwinregbecause it was already in the tree and it also covers the pipe, process, console and DACL calls.build-windowsjob runs on ubuntu-24.04:rustup target add, aptclang lld llvm,cargo install --locked cargo-xwin --version 0.23.1(built from source, as the app's CI does), thencargo xwin build --release -p rkd-activity. It checks the output is a PE32+ console binary that does not import vcruntime/msvcp, packages and uploads it, andpublishnow waits for it. rkd-terminal gets no Windows asset: its Windows build is experimental and nothing installs it (it would be a one-word change).install.shstays unix-only..cargo/config.tomlsets+crt-staticforx86_64-pc-windows-msvc. Without it the exe importedVCRUNTIME140.dlland would fail to start on machines without the VC++ Redistributable.<plugin>.exefor*-windows-*targets and only there. The archive keeps the unix layout:<name>/rkd-activity.exe, README.md and LICENSE.local/README.md(new Windows section for rkd-activity),WINDOWS-CHECKLIST.mdstep 11, and the root README table.Contract notes (for the app-side PR)
rkd-activity-v<ver>-x86_64-pc-windows-msvc/rkd-activity.exe. It appears exactly once, is a regular file, and sits beside README.md/LICENSE like the unix assets, so the app'sbinary_member()needs.exeon Windows. I read the contract's "single regular-file member" as the one member the app extracts, not a one-entry tarball, because the unix assets have the same README/LICENSE entries.servecallsFreeConsolewhen it is the only process on its console (GetConsoleProcessList== 1), so a window may flash briefly at sign-in. This is a mitigation, not a fix. A real fix would be a GUI-subsystem launcher or aconsoleAllocationPolicymanifest (Windows 11 24H2+). Checklist step 11 asks the tester to note what happens.servestarted byinstallhas no stdout/stderr (NUL), so nothing is logged on Windows.statusshows whether it runs.installmakes its own std handles non-inheritable before it spawnsserve. Otherwiseservewould inherit the app's pipe to install's stdout and keep the app waiting for EOF.Test plan
cargo fmt --all --checkcargo clippy --workspace --all-targets --locked -- -D warnings(macOS host)cargo clippy --target x86_64-pc-windows-msvc --workspace --all-targets --locked -- -D warnings(exactly as ci.yml; plain cross-clippy needed no C toolchain)cargo test --workspace --locked(macOS): all green, including 11 newautostarttests (Run value quoting with spaces, UNC, refusals; plain canonical path choice; ancestors; ACL rule; install/restart/no-start/never-answers; uninstall idempotent and still removes the value when stopping fails; status) and the movedbuild_and_temp_dirs_are_namedcargo xwin build --release --locked -p rkd-activity -p rkd-terminal --target x86_64-pc-windows-msvclinks;cargo xwin test --no-run -p rkd-activitylinks the unit tests and the newtests/pipe.rssh scripts/test-release.sh(shellcheck included): new packaging checks for the .exe member, refusal without .exe, and refusal of .exe for a non-Windows target. A hand-applied mutation of the member rule turned them red.sh scripts/test-install.shv*tag; not tagged (needs the owner's OK)Evidence
rkd-activity --help, main (before) vs this branch (after):On Windows, main's
rkd-activity.exe(before) did nothing but print this, frommain.rson origin/main:release.yml jobs and targets, before (main):
after (this branch):
The new job's package step, run locally on the cargo-xwin build:
Before the
+crt-staticconfig, the same exe also importedVCRUNTIME140.dllandapi-ms-win-crt-*.dll.No version bump, tag or release in this PR.
https://claude.ai/code/session_01Bs7kRiXy79YjZrXDBuMabP