Files
ProductionDataBaseSync_Data…/.claude/skills/nssm-114/SKILL.md
2026-07-14 11:12:34 +08:00

7.3 KiB

name, description
name description
nssm-114 NSSM (Non-Sucking Service Manager) operations and Windows service maintenance targeting the internal host 114. Use this skill whenever the user mentions NSSM, nssm.exe, or any nssm command (install, remove, set, get, reset, dump, start, stop, restart, pause, continue, rotate, status), or asks to manage/configure/restart a Windows service that you know or suspect is an NSSM-wrapped service. Also use it when the user says "运维/管理/重启/查一下服务" in connection with 114 or an internal service. In this environment, NSSM-related ops ALWAYS target host 114 (SSH alias `114`) — never run nssm locally. Route everything through `ssh 114 "..."`.

NSSM Ops on Host 114

The core routing rule

Every NSSM operation targets host 114 over SSH. Never run nssm on the local machine.

  • SSH alias: 114 (Windows Server host, non-interactive)
  • All commands go through: ssh 114 "nssm <subcommand> ..." or ssh 114 "cmd /c ..." / ssh 114 "powershell -Command \"...\""
  • If the user says "114" + anything about services, or just "查一下/重启一下服务" with NSSM context, that's host 114.

How SSH to 114 actually works (read this before running anything)

This is the part that bites. SSH to 114 is non-interactive:

  1. No session. Each ssh 114 "..." is a one-shot. stdin is not a TTY, so you cannot open an interactive shell and type follow-ups. Run one command per invocation, or chain with && / ;.
  2. Pseudo-terminal will not be allocated warnings are normal — ignore them.
  3. Bash double-quote escaping eats PowerShell $ variables. When you run ssh 114 "powershell -Command \"... $_ ...\"", bash mangles $_ and $var into \extglob garbage, producing hundreds of errors. This is the #1 source of broken commands.
    • Avoid $_, $PSItem, and any $var in PowerShell sent over SSH-through-bash.
    • Prefer plain cmd.exe tools: findstr, where, dir, type, reg query.
    • If you need PowerShell, avoid pipeline $_ (use Where-Object/ForEach-Object scriptblocks that don't reference $_, or filter in cmd).
    • For complex logic, write a .ps1 or .py file to the host first (via scp or a heredoc), then run it. Don't try to cram multi-line PowerShell into a quoted -Command.
  4. Verify command output. Many nssm subcommands print 操作成功完成 / Set parameter ... for service ... on success. Read what comes back before declaring done.

Listing services (always start here when scope is unclear)

ssh 114 "nssm list"

This enumerates all NSSM-managed services on the host. If the user says "查一下服务" / "有哪些服务", run this first.

The NSSM command reference (essentials)

Full official command reference is bundled at references/nssm-commands.md — read it when you need exact syntax, subparameters, or less-common parameters. The everyday set:

Lifecycle

nssm install <servicename> <program> [<arguments>]   # install
nssm remove   <servicename> [confirm]                 # uninstall (confirm skips prompt)
nssm start    <servicename>
nssm stop     <servicename>
nssm restart  <servicename>
nssm status   <servicename>                            # 0=stopped, 1=running, etc.

Inspect config

nssm dump    <servicename>            # full config as nssm set commands (great for snapshots)
nssm get     <servicename> <parameter> [<subparameter>]

Edit config

nssm set    <servicename> <parameter> [<subparameter>] <value>
nssm reset  <servicename> <parameter> [<subparameter>]   # back to default / delete reg entry

Common parameters: Application/AppProgram, AppParameters, AppDirectory, AppStdout, AppStderr, AppExit, AppEnvironmentExtra, AppEnvironment, AppRotateFiles, AppRotateBytes, AppRotateOnline, Description, DisplayName, ObjectName, Start, Type, DependOnService.

Service controls

nssm pause    <servicename>     # SERVICE_PAUSE_PENDING capable
nssm continue <servicename>
nssm rotate   <servicename>     # online log rotation (needs AppRotateFiles + AppRotateOnline)

NSSM gotchas (these will save you)

Gotcha 1 — AppEnvironmentExtra replaces, it does not append

nssm set <svc> AppEnvironmentExtra <value> writes the entire environment block. Calling it multiple times in a row (e.g. chained with &&) wipes everything except the last value. The official docs confirm:

When setting an environment block with nssm set, each variable should be specified as a KEY=VALUE pair in a separate argument.

Correct — all variables in ONE call:

nssm set <svc> AppEnvironmentExtra VAR1=v1 VAR2=v2 VAR3=v3

Wrong — only VAR3 survives:

nssm set <svc> AppEnvironmentExtra VAR1=v1 && nssm set <svc> AppEnvironmentExtra VAR2=v2 && nssm set <svc> AppEnvironmentExtra VAR3=v3

Before adding env vars, snapshot the current block so you can include existing entries:

ssh 114 "nssm get <svc> AppEnvironmentExtra"     # or: reg query ...\Parameters /v AppEnvironmentExtra

Gotcha 2 — what nssm dump prefixes mean

nssm dump <svc> prints each env var with a prefix that encodes its semantics:

  • :NAME=valueconditional: set only if not already present in the process environment. Won't override a value inherited from the machine/user environment.
  • +NAME=valueoverride: force-set, replacing any inherited value.

The raw registry (reg query) stores values without these prefixes; the prefix is NSSM's display convention. If you need a service-level env var to override a machine-level one (very common for proxies), make sure it shows as + in nssm dump, i.e. write it without a leading : in the nssm set value.

Gotcha 3 — restart to apply env/log/path changes

nssm set only edits the registry. The running process won't pick up AppParameters, AppDirectory, AppEnvironmentExtra, log paths, etc. until you restart the service. Snapshot logs first if the service is mid-task:

ssh 114 "nssm restart <svc>"

Gotcha 4 — LocalSystem vs user-account services

Most NSSM services run as LocalSystem, which can't access network shares or the current user's profile/credentials. If a service needs LAN file access, it runs as a real account (e.g. .\peng). Check with nssm get <svc> ObjectName before assuming network access works the same way as your shell.

Working safely on a production host

114 runs real services. Before mutating state:

  1. Snapshot first. nssm dump <svc> > before.txt (or capture relevant nssm get output) so you have an exact rollback recipe.
  2. One change at a time, verify output, then move on.
  3. Prefer nssm restart over stop+start; it's atomic from NSSM's perspective.
  4. Tail logs after changes: nssm get <svc> AppStdout / AppStderr to find the log paths, then read the tail for new errors.
  5. Rollback = re-run the snapshot's nssm set lines, or nssm reset the parameter, then restart.

When to read the bundled reference

Read references/nssm-commands.md when you need:

  • Exact subparameter syntax for AppExit, AppEnvironment(Extra), DependOnService, ObjectName, Start, Type
  • The full list of native vs non-standard parameters
  • Priority class constants for AppPriority
  • Confirmation that a parameter exists before guessing

Do NOT read it for the everyday lifecycle/config commands above — those are the hot path.