Skip to content

feat: add a classic Services page - #26

Merged
cursor[bot] merged 1 commit into
mainfrom
cursor/services-page-033e
Oct 20, 2026
Merged

cursor[bot] merged 1 commit into
mainfrom
cursor/services-page-033e

Conversation

@JamesLinYJ

Copy link
Copy Markdown
Owner

Summary

Adds a Services page in the style of the existing classic Task Manager pages. No dependency upgrades, no new platform targets, and no Options field changes. The page is appended as PageId::Services = 7, so existing saved page indexes stay valid.

  • The list shows service name, description, status, startup type, and the owning process when a verified ProcIdentity exists. Enumeration uses SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE. Per-service config and description use SERVICE_QUERY_CONFIG. A row-level failure keeps the other rows.
  • Start opens the service with SERVICE_START | SERVICE_QUERY_STATUS. Stop uses SERVICE_STOP | SERVICE_QUERY_STATUS. Success is only a following status of running/start-pending or stopped/stop-pending. Any API failure or unchanged state opens an error dialog immediately. A disabled command beeps.
  • Go to Process sends WM_FINDPROC with pid plus creation time. The command stays disabled when the service has no verified process identity.
  • SCM queries and control calls run on the existing single-flight worker. The UI thread only dispatches, lays out, and paints. Refresh keeps the selected service, focus, and scroll position. The page is shown only after its dialog and menu exist.
  • New strings are in TextKey and every locale. The three commands have unique resource IDs, routing, enabled state, and status-bar help. The Services menu separator is explicit.

Tests

  • SCM status and startup constants map without collapsing unknown values.
  • Start is available only for a stopped service whose startup type is not Disabled. Stop is available for Running or Paused. Go to Process stays off for a missing or PID-only identity and turns on only for a verified creation time.
  • A control result is success only in the requested state. An API error and an unchanged state are both failures.
  • A pending start or stop is not replaced by a coalesced refresh. A newer control replaces an older one.
  • Selection is kept by service name, case-insensitively, and refresh uses the preserve-viewport policy.
  • An unverified owning process is blank even if an image name was supplied. A verified process shows the file name, or PID {n} when the name is missing.

Verification

This host is Linux. cargo fmt --all -- --check, cargo check --all-targets --locked, and cargo clippy --all-targets --locked -- -D warnings passed for the default x86_64-pc-windows-msvc target. The same check passed for i686-pc-windows-msvc and aarch64-pc-windows-msvc. cargo test --all-targets --locked stops at link.exe, which is not on this machine. Linking the i686 tests with rust-lld stops because the Windows import libraries are absent. Those checks are not a Windows device test.

CI on this PR runs Quality (x86_64) and Architecture (i686, aarch64), including the Windows test and release builds.

Open in Web Open in Cursor 

List Win32 services with name, description, status, startup type, and a
verified owning process. Start and stop use the minimum SCM rights and
report failures immediately. Go to Process requires a ProcIdentity.

Co-authored-by: jameslincn <jameslincn@outlook.sg>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-20T00:13:14.908273Z 838524d PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 838524d0a9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +180 to +182
match (&*pending, &incoming) {
(ServiceRequest::Control { .. }, ServiceRequest::Refresh) => {}
_ => *pending = incoming,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve every queued service control request

When a refresh or control request is already in flight, one service action becomes pending; if the user invokes another action before completion, this branch replaces the first action with the second. This can readily happen during the full per-service metadata refresh, and the discarded Start/Stop request never reaches the SCM or produces an error. Preserve pending control requests in order, or reject/disable additional controls while continuing to coalesce refreshes.

AGENTS.md reference: AGENTS.md:L53-L55

Useful? React with 👍 / 👎.

Comment on lines +143 to +146
stop: matches!(
selected.status,
ServiceRunState::Running | ServiceRunState::Paused
),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Require SERVICE_ACCEPT_STOP before enabling Stop

For a running or paused service that does not advertise SERVICE_ACCEPT_STOP, status alone still enables Stop, even though ControlService(SERVICE_CONTROL_STOP) will reject it. ENUM_SERVICE_STATUS_PROCESSW already supplies dwControlsAccepted, but the sampler discards it; carry that capability into the row and gate the button and menu on it so their enabled state reflects whether the service accepts the command.

AGENTS.md reference: AGENTS.md:L62-L64

Useful? React with 👍 / 👎.

Comment on lines +141 to +142
start: selected.status == ServiceRunState::Stopped
&& selected.startup != ServiceStartupType::Disabled,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep Start disabled when startup metadata is unknown

When QueryServiceConfigW fails for a stopped service, the sampler records ServiceStartupType::Unknown(0), but Unknown != Disabled makes Start appear enabled. If the inaccessible service is actually disabled, the UI therefore presents an operation it cannot safely determine is allowed and only discovers that through an avoidable action failure; require a known startable startup type instead of treating unknown metadata as non-disabled.

AGENTS.md reference: AGENTS.md:L52-L55

Useful? React with 👍 / 👎.

@cursor
cursor Bot merged commit e4afbde into main Oct 20, 2026
3 checks passed
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.

2 participants