DesktopManager Windows Verification

io.github.EvotecIT由 GitHub 账号 EvotecIT 发布v0.2.3更新于 Oct 25, 2026

Inspect and verify Windows x64 desktop apps through a local, read-only-by-default MCP server.

概览

AI 生成的概览

本地 Windows x64 MCP 服务器,让助手检查并验证桌面应用、显示器、窗口、音频、电源、无线电和设备,默认只读

可以做什么
检查显示器、显示设备、壁纸、亮度、分辨率和方向,并从全部显示器、单个显示器或自定义区域截取桌面截图。枚举并控制窗口:位置、大小、状态、置顶、布局、保活会话和虚拟桌面归属。读取和更改音频端点、音量、静音和默认角色,以及电源和交互式会话状态。检查并应用工作站配置、个性化快照和任务栏设置。列出已保存的 Wi-Fi 配置文件、无线电、即插即用设备和驱动程序包,并可显式启用、禁用或连接。
适用场景
适合助手需要检查或验证 Windows 桌面状态(显示布局、窗口位置、音频、电源或设备),并且只做有意的更改时使用。适用于 Windows x64 机器上的运维和测试工作流,而非通用的跨平台自动化。
运行要求
作为本地进程运行在 Windows x64 桌面机器上,以 stdio 传输的 mcpb 包分发。未声明身份验证、环境变量或请求头。README 说明部分操作需要确认或提权,实验性功能需要显式的 allow-experimental 标志。
安装前请注意
虽然默认只读,但该工具集可以更改状态:壁纸、显示器位置和分辨率、窗口位置和状态、音频默认设备、任务栏和个性化、无线电开关、Wi-Fi 配置文件连接,以及会话锁定、注销、睡眠或休眠。部分操作需要确认或提权,全局飞行模式依赖未公开的 Windows 接口并置于实验性标志之后。连接助手前请确认启用了哪些更改操作。

安装

在 SourceWeft 中

  1. 打开 控制台中的 DesktopManager Windows Verification,将其添加到工作区。
  2. 为需要使用其工具的对话启用该服务。

Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。

其他 MCP 客户端

参照 仓库 中的启动说明。

README

DesktopManager - C# Library and PowerShell Module

DesktopManager is a Windows desktop automation toolkit available as a .NET library, PowerShell module, CLI, MCP server, and tray app.

The .NET library also exposes PortableDesktopService for current-user wallpaper, display discovery, and session diagnostics on Windows, macOS, GNOME, and KDE Plasma. Each adapter reports its capabilities; the window automation, tray app, CLI, and existing PowerShell commands retain their Windows scope. See Portable desktop integration for usage and platform limits.

[nuget downloads] [nuget version]

You can also download it from PowerShell Gallery

[PowerShell Gallery Version] [PowerShell Gallery Preview Version] [PowerShell Gallery Downloads]

[PowerShell Gallery Platform] [GitHub top language] [GitHub code size in bytes] [GitHub license]

If you would like to contact me you can do so via Twitter or LinkedIn.

[Twitter Follow] [Blog evotec.xyz] [LinkedIn pklys] [Discord] [Threads @PrzemyslawKlys]

What it's all about

[图片]

DesktopManager provides one shared Windows automation core through five surfaces:

  • C# library for .NET applications and services
  • PowerShell module for scripts and operator workflows
  • CLI executable for terminal and JSON automation
  • MCP server for inspect-first agent automation
  • Windows tray app for daily hotkeys and monitor actions

It has following features:

  • Get information about monitors
  • Get information about display devices
  • Get information about wallpapers
  • Set wallpapers
  • Get/Set desktop background color
  • Get/Set monitor position
  • Get/Set window position
  • Get/Set window state (minimize, maximize, restore)
  • Capture desktop screenshots from all monitors, a single monitor or a custom region
  • Manage monitor brightness
  • Start/Stop/Advance wallpaper slideshows
  • Track wallpaper history
  • Adjust monitor resolution and orientation
  • Move monitors around the virtual desktop
  • Save and restore window layouts
  • Snap or move windows between monitors
  • Subscribe to resolution, orientation or display changes
  • Keep inactive windows awake using periodic input
  • Manage keep-alive sessions for windows
  • Save and restore cohesive workstation profiles across displays, audio, personalization, and taskbars
  • Enumerate Core Audio render/capture endpoints, change volume and mute, set default roles, and observe endpoint changes
  • Inspect power and interactive-session state; lock, sign out, sleep, hibernate, or hold a bounded keep-awake lease
  • Capture and restore personalization snapshots and configure taskbar visibility, position, and auto-hide
  • Enumerate, observe, and explicitly enable or disable Wi-Fi, Bluetooth, mobile broadband, and FM radios through the supported Windows radio API
  • List saved Windows Wi-Fi profiles and connect an exact saved profile without scanning nearby networks or exposing credentials
  • Inspect a window's virtual desktop and move it to a known desktop through the public Windows virtual-desktop API
  • Inspect and manage Plug and Play devices and Driver Store packages through documented native Windows APIs

Wallpaper consumers

Applications such as PowerBGInfo can read monitor geometry, display scale and the signed-in session user directly from the library:

csharp
using DesktopManager;
var monitors = new Monitors();foreach (var display in monitors.GetMonitorSnapshots()) {    Console.WriteLine($"{display.Index}: {display.DeviceName}, " +        $"{display.Width} x {display.Height}, scale {display.Scale}");}
var user = new DesktopSessionService().GetSessionUser();Console.WriteLine(user?.AccountName ?? "Unknown");

Snapshots contain physical pixel bounds and per-monitor DPI even when the caller is not DPI aware. The calling thread's DPI context is restored. Indexes describe the current display topology; read them again after docking or reconnecting. Missing wallpaper device paths on session hosts are retained.

Monitors.SetLogonWallpaperWithResult(imagePath) sets the current account's lock screen through Windows Runtime on .NET Framework, modern .NET and netstandard consumers. The result reports success, the mechanism used and any failure. Machine policy fallback requires an explicit allowPolicyFallback: true and elevation. The existing SetLogonWallpaper method keeps its automatic policy fallback. See Wallpaper consumer APIs for examples, OS requirements, policy limits and session deployment behavior.

Desktop state and controls

The workstation profile is the high-level entrypoint when you want to move between repeatable setups. It captures connected monitor modes and placement, monitor wallpaper and supported brightness/HDR state, active audio endpoint state and default roles, personalization, and taskbars. Applying a profile matches monitors by stable identity, stages display changes together, and rolls back the selected sections when a required step fails. Machine-wide personalization policies are captured but only restored when explicitly requested.

powershell
Save-DesktopWorkstationProfile -Name 'office'Get-DesktopAudioEndpoint -DataFlow Render -ActiveOnlyGet-DesktopPowerStatusGet-DesktopSessionGet-DesktopRadioGet-DesktopWifiProfileConnect-DesktopWifiProfile -Name 'Corporate WiFi'Get-DesktopDevice -Present -ProblemGet-DesktopDriverPackageRestore-DesktopWorkstationProfile -Name 'office' -Confirm

The same capabilities are available from the CLI:

text
desktopmanager workstation save --name officedesktopmanager audio list --flow render --activedesktopmanager system powerdesktopmanager system sessiondesktopmanager radio listdesktopmanager wifi profilesdesktopmanager wifi connect --profile "Corporate WiFi"desktopmanager device list --present --problemdesktopmanager driver listdesktopmanager workstation apply --name office

Radio control has two deliberately separate APIs. RadioService and the normal radio list / radio set commands use the supported Windows.Devices.Radios contract for individual radios. Global airplane mode uses an undocumented Windows shell COM contract, so it lives under ExperimentalAirplaneModeService and requires --experimental in the CLI, -Experimental in PowerShell, or --allow-experimental in MCP.

Wi-Fi profile connection is separate from radio control. WifiProfileService, Get-DesktopWifiProfile, and desktopmanager wifi profiles enumerate only profiles already stored by Windows. Connecting an exact profile uses the Native Wi-Fi profile API and ACM completion notifications; it does not scan nearby networks, return BSSIDs, expose profile XML or credentials, or query location-sensitive current-connection details. Windows still requires location consent for nearby-network scanning and related Wi-Fi information APIs. See Changes to API behavior for Wi-Fi access and location.

VirtualDesktopService exposes only the public Windows operations: check whether a top-level window is on the current desktop, get its desktop ID, and move it to a known desktop ID. Desktop enumeration, creation, renaming, switching, and removal are intentionally not presented as supported APIs.

Additional operator-focused docs for the newer CLI and MCP surfaces:

Which Surface Should You Use?

SurfaceBest forTypical entrypoint
C# libraryEmbedding DesktopManager into your own .NET app or serviceDesktopManager.dll
PowerShell moduleScripts, operators, admin workflows, repeatable task automationInstall-Module DesktopManager
CLI executableManual use, shell automation, JSON output, and MCP hostingdesktopmanager.exe
MCP serverAgent-driven automation over stdio with an inspect-first safety modeldesktopmanager mcp serve
Windows tray appDaily hotkeys, monitor bindings, HDR controls, tray runtime, and per-user startupDesktopManager.App.exe

How It Fits Together

DesktopManager now has one shared core and several operator-facing surfaces on top of it.

mermaid
flowchart LR    A["Your .NET app"] --> B["DesktopManager library"]    C["PowerShell module"] --> B    D["desktopmanager.exe CLI"] --> B    E["MCP server"] --> D    J["DesktopManager.App tray app"] --> B    B --> F["Windows desktop APIs"]    F --> G["Monitors / wallpapers / brightness"]    F --> H["Windows / controls / input"]    F --> I["Layouts / snapshots / targets"]

If you want the fuller component and request-flow diagrams, see Docs/DesktopManager.Architecture.md.

The practical way to think about this:

  • use the library when DesktopManager is part of your own application
  • use PowerShell when you want scriptable admin/operator automation
  • use the CLI when you want a human-friendly or JSON-friendly command surface
  • use MCP when an agent should inspect first and mutate only through an explicit server session

Common Entry Points

GoalRecommended entrypoint
Add DesktopManager features to your own codeReference the DesktopManager NuGet package
Run manual desktop operations from a terminaldesktopmanager.exe
Run DesktopManager every day from the trayDesktopManager.App.exe or the DesktopManager MSI
Use it from PowerShell scriptsDesktopManager PowerShell module
Connect an agent/tooling layerdesktopmanager mcp serve
Understand the overall wiringDocs/DesktopManager.Architecture.md

Request Flow at a Glance

mermaid
flowchart LR    A["User, script, or agent"] --> B{"Surface"}    B -->|".NET"| C["DesktopManager library"]    B -->|"PowerShell"| D["Cmdlets"]    B -->|"CLI"| E["desktopmanager.exe"]    B -->|"MCP"| F["desktopmanager mcp serve"]    B -->|"Tray app"| J["DesktopManager.App.exe"]
    D --> C    E --> G["DesktopOperations"]    F --> G    J --> C    G --> C    C --> H["Win32, UI Automation, monitor, screenshot, and input services"]

The important part is that CLI, MCP, and PowerShell are meant to stay aligned by reusing the same shared C# behavior rather than inventing separate desktop logic in each surface.

Available PowerShell Cmdlets

CmdletDescription
Get-DesktopMonitorRetrieve monitor information with filtering options
Get-DesktopWallpaperGet current wallpaper path for monitors
Set-DesktopWallpaperApply wallpaper from path, URL or stream
Get-DesktopWallpaperHistoryList stored wallpaper history entries
Set-DesktopWallpaperHistoryUpdate or clear wallpaper history file
Get-DesktopSlideshowInspect slideshow images, state, options and tick interval
Set-DesktopSlideshowOptionsUpdate slideshow shuffle behavior and tick interval
Start-DesktopSlideshowBegin wallpaper slideshow across monitors
Stop-DesktopSlideshowStop currently running slideshow
Step-DesktopSlideshowMove slideshow forward or backward
Get-DesktopBackgroundColorRead current desktop background color
Set-DesktopBackgroundColorChange desktop background color
Get-DesktopBrightnessRead monitor brightness level
Set-DesktopBrightnessSet monitor brightness level
Set-DesktopPositionMove a monitor by its top-left coordinates without changing resolution
Set-DesktopResolutionChange monitor resolution or orientation
Set-DefaultAudioDeviceSet the default audio playback device
Get-DesktopAudioEndpointList Core Audio render and capture endpoints with volume, mute, and default roles
Set-DesktopAudioEndpointSet endpoint volume, mute, or selected default roles
Register-DesktopAudioEventSubscribe to endpoint, state, property, and default-role changes
Save-DesktopWorkstationProfileCapture displays, audio, personalization, and taskbars as one named profile
Get-DesktopWorkstationProfileList or load named workstation profiles
Restore-DesktopWorkstationProfileApply a named workstation profile with matching and rollback options
Remove-DesktopWorkstationProfileDelete a named workstation profile
Get-DesktopPowerStatusRead AC and battery state
Get-DesktopSessionRead current interactive-session identity, connection, lock, and idle state
Register-DesktopSessionEventSubscribe to meaningful session changes
Lock-DesktopSessionLock the current Windows session
Exit-DesktopSessionSign out the current Windows session with confirmation support
Start-DesktopKeepAwakeHold a bounded system/display keep-awake lease
Suspend-DesktopSystemRequest sleep or hibernation with confirmation support
Get-DesktopPersonalizationCapture current state or list/load saved personalization snapshots
Save-DesktopPersonalizationSave a named personalization snapshot
Set-DesktopPersonalizationApply explicit personalization settings
Restore-DesktopPersonalizationRestore a named personalization snapshot
Remove-DesktopPersonalizationDelete a named personalization snapshot
Get-DesktopTaskbarList taskbars with monitor mapping, visibility, edge, and bounds
Set-DesktopTaskbarAutoHideSet the explicit taskbar auto-hide state
Get-DesktopRadioList radios through the supported Windows radio API
Set-DesktopRadioExplicitly enable or disable matching supported radios
Register-DesktopRadioEventSubscribe to supported radio state changes
Get-DesktopWifiProfileList saved Windows Wi-Fi profiles without scanning nearby networks
Connect-DesktopWifiProfileConnect an exact saved Windows Wi-Fi profile
Get-DesktopAirplaneModeRead the experimental global airplane-mode state after explicit acknowledgement
Set-DesktopAirplaneModeApply and verify experimental global airplane mode after explicit acknowledgement
Get-DesktopVirtualDesktopInspect the supported virtual-desktop state for a top-level window
Move-DesktopWindowToVirtualDesktopMove a top-level window to a known virtual-desktop ID
Get-LogonWallpaperGet the lock screen wallpaper path
Set-LogonWallpaperSet the lock screen wallpaper
Set-TaskbarPositionMove or hide the taskbar
Invoke-DesktopMouseMoveMove the mouse cursor
Invoke-DesktopMouseClickSimulate a mouse click
Invoke-DesktopMouseScrollScroll the mouse wheel
Invoke-DesktopScreenshotCapture monitor or region screenshots
Get-DesktopWindowEnumerate visible windows
Get-DesktopWindowGeometryReturn outer-window and client-area geometry for matched windows
Get-DesktopWindowControlEnumerate Win32 or UIA window controls
Get-DesktopWindowControlDiagnosticExplain Win32 vs UIA control discovery and actionability
Get-DesktopWindowProcessInfoReturn process details for matched windows
Get-DesktopWindowTargetList saved window-relative targets or resolve one against live windows
Get-DesktopControlTargetList saved control targets or resolve one against live windows
Get-DesktopHostedSessionDiagnosticRead the latest hosted-session typing diagnostic artifact or a specific one
Invoke-DesktopControlClickClick a matched control using shared control action routing
Invoke-DesktopWindowClickClick a window-relative point or saved window target
Invoke-DesktopWindowDragDrag between window-relative points or saved targets
Invoke-DesktopWindowScrollScroll at a window-relative point or saved target
Send-DesktopControlKeySend keys to a matched control without reimplementing key routing
Set-DesktopControlTargetSave a reusable control selector profile
Set-DesktopControlTextWrite text directly to a specific control
Set-DesktopWindowMove, resize or control windows
Set-DesktopWindowSnapSnap window to common positions
Set-DesktopWindowTargetSave a reusable window-relative point target
Set-DesktopWindowTextPaste or type text into a window
Wait-DesktopWindowWait for a window to appear
Wait-DesktopWindowControlWait for a control to appear
Test-DesktopWindowVerify that a window exists or matches the active window
Test-DesktopWindowControlVerify that a control exists
Start-DesktopWindowKeepAliveSend periodic input to keep a window awake
Stop-DesktopWindowKeepAliveStop sending keep-alive input
Get-DesktopWindowKeepAliveList windows with active keep-alive
Save-DesktopWindowLayoutSave current window layout to file
Restore-DesktopWindowLayoutRestore saved window layout
Register-DesktopMonitorEventSubscribe to display configuration changes
Register-DesktopOrientationEventSubscribe to orientation changes
Register-DesktopResolutionEventSubscribe to resolution changes

Cmdlet to C# method map

The table below shows the most relevant API methods behind each PowerShell cmdlet.

CmdletMain C# methods
Get-DesktopMonitorMonitors.GetMonitors
Get-DesktopWallpaperMonitors.GetWallpaper or Monitor.GetWallpaper
Set-DesktopWallpaperMonitors.SetWallpaper, Monitors.SetWallpaperFromUrl
Get-DesktopWallpaperHistoryWallpaperHistory.GetHistory
Set-DesktopWallpaperHistoryWallpaperHistory.SetHistory
Get-DesktopSlideshowMonitors.GetWallpaperSlideshow
Set-DesktopSlideshowOptionsMonitors.SetWallpaperSlideshowOptions
Start-DesktopSlideshowMonitors.StartWallpaperSlideshow
Stop-DesktopSlideshowMonitors.StopWallpaperSlideshow
Step-DesktopSlideshowMonitors.AdvanceWallpaperSlide
Get-DesktopBackgroundColorMonitors.GetBackgroundColor
Set-DesktopBackgroundColorMonitors.SetBackgroundColor
Get-DesktopBrightnessMonitors.GetMonitorBrightness
Set-DesktopBrightnessMonitors.SetMonitorBrightness
Set-DesktopPositionMonitor.SetMonitorPosition or Monitors.SetMonitorPosition
Set-DesktopResolutionMonitors.SetMonitorResolution, Monitors.SetMonitorOrientation
Set-DefaultAudioDeviceAudioService.SetDefaultAudioDevice
Get-LogonWallpaperMonitors.GetLogonWallpaper
Set-LogonWallpaperMonitors.SetLogonWallpaper
Set-TaskbarPositionTaskbarService.SetTaskbarPosition / SetTaskbarVisibility
Invoke-DesktopMouseMoveWindowManager.MoveMouse
Invoke-DesktopMouseClickWindowManager.ClickMouse
Invoke-DesktopMouseScrollWindowManager.ScrollMouse
Invoke-DesktopScreenshotScreenshotService.CaptureScreen, ScreenshotService.CaptureRegion
Get-DesktopWindowWindowManager.GetWindows / GetWindowsForProcess
Get-DesktopWindowGeometryDesktopAutomationService.GetWindowGeometry
Get-DesktopWindowControlDesktopAutomationService.GetControls
Get-DesktopWindowControlDiagnosticDesktopAutomationService.GetControlDiagnostics / GetControlTargetDiagnostics
Get-DesktopWindowProcessInfoWindowManager.GetWindowProcessInfo
Get-DesktopWindowTargetDesktopAutomationService.ListWindowTargets, GetWindowTarget, ResolveWindowTargets
Get-DesktopControlTargetDesktopAutomationService.ListControlTargets, GetControlTarget, ResolveControlTargets
Invoke-DesktopControlClickDesktopAutomationService.ClickControls / ClickControlTarget
Invoke-DesktopWindowClickDesktopAutomationService.ClickWindowPoint / ClickWindowTarget
Invoke-DesktopWindowDragDesktopAutomationService.DragWindowPoints / DragWindowTargets
Invoke-DesktopWindowScrollDesktopAutomationService.ScrollWindowPoint / ScrollWindowTarget
Send-DesktopControlKeyDesktopAutomationService.SendControlKeys / SendControlTargetKeys
Set-DesktopControlTargetDesktopAutomationService.SaveControlTarget
Set-DesktopControlTextDesktopAutomationService.SetControlText
Set-DesktopWindowWindowManager.SetWindowPosition, MoveWindowToMonitor, etc.
Set-DesktopWindowSnapWindowManager.SnapWindow
Set-DesktopWindowTargetDesktopAutomationService.SaveWindowTarget
Set-DesktopWindowTextWindowManager.TypeText, WindowManager.PasteText, WindowInputService
Wait-DesktopWindowDesktopAutomationService.WaitForWindows
Wait-DesktopWindowControlDesktopAutomationService.WaitForControls
Test-DesktopWindowDesktopAutomationService.WindowExists / ActiveWindowMatches
Test-DesktopWindowControlDesktopAutomationService.ControlExists
Start-DesktopWindowKeepAliveWindowKeepAlive.Start
Stop-DesktopWindowKeepAliveWindowKeepAlive.Stop or StopAll
Get-DesktopWindowKeepAliveWindowKeepAlive.ActiveHandles
Save-DesktopWindowLayoutWindowManager.SaveLayout
Restore-DesktopWindowLayoutWindowManager.LoadLayout
Register-DesktopMonitorEventMonitorWatcher.DisplaySettingsChanged
Register-DesktopOrientationEventMonitorWatcher.OrientationChanged
Register-DesktopResolutionEventMonitorWatcher.ResolutionChanged

Installation

For using in PowerShell you can install it from PowerShell Gallery

powershell
Install-Module DesktopManager -Force -Verbose

For the daily Windows tray app, use the DesktopManager MSI release artifact when available. The installer creates a Start Menu shortcut, and the app's Startup toggle registers the current user for minimized tray startup.

From source, the app and MSI are built through PowerForge:

powershell
.\Build\Build-DesktopManagerApp.ps1.\Build\Build-DesktopManagerApp-MSI.ps1msiexec.exe /i .\Artefacts\PowerForge\Msi\DesktopManager.App\win-x64\net10.0-windows10.0.19041.0\PortableCompat\output\DesktopManager.msi

Verified mutation examples

When you want more than "the call did not throw", prefer -Verify together with -PassThru so the cmdlet returns the observed postcondition.

powershell
# Verify a window move against the observed geometrySet-DesktopWindow -Name "*Visual Studio Code*" -Left 0 -Top 0 -Width 1600 -Height 1200 -Verify -PassThru
# Verify exact text after a control text updateSet-DesktopControlText -Control $ctrl -Text "Hello world" -Verify -PassThru
# Verify the observed check stateSet-DesktopControlCheck -Control $checkbox -Check $true -Verify -PassThru
# Return a structured record after a control clickInvoke-DesktopControlClick -Control $button -PassThru
# Return a structured record after sending keysSend-DesktopControlKey -Control $editor -Keys @([DesktopManager.VirtualKey]::VK_RETURN) -PassThru

Verification behavior is action-aware:

  • window mutations verify geometry, state, topmost, close, or foreground conditions when those postconditions are meaningful
  • Set-DesktopControlText -Verify verifies the observed text/value when the control can be re-queried
  • Set-DesktopControlCheck -Verify verifies the observed check state
  • control click/key actions return honest presence and foreground evidence when exact semantic verification would be misleading

Testing notes

UI-impacting tests are opt-in to avoid opening windows or changing the desktop during local development. Use the environment variables below to control behavior:

  • RUN_UI_TESTS=true (or DESKTOPMANAGER_RUN_UI_TESTS=true) enables the top-level UI test pack.
  • RUN_OWNED_WINDOW_UI_TESTS=true (or DESKTOPMANAGER_RUN_OWNED_WINDOW_UI_TESTS=true) enables owned-window UI tests that use repo-created harness windows.
  • RUN_DESTRUCTIVE_UI_TESTS=true (or DESKTOPMANAGER_RUN_DESTRUCTIVE_UI_TESTS=true) enables owned-window mutation tests such as move, resize, hide, snap, and transparency changes against repo-created harness windows.
  • RUN_FOREGROUND_UI_TESTS=true (or DESKTOPMANAGER_RUN_FOREGROUND_UI_TESTS=true) enables tests that intentionally steal foreground focus, even when they only target repo-created harness windows.
  • RUN_SYSTEM_UI_TESTS=true (or DESKTOPMANAGER_RUN_SYSTEM_UI_TESTS=true) enables system-wide desktop changes such as wallpapers, brightness, resolution, and other monitor-level mutations that can affect your current session.
  • RUN_EXTERNAL_UI_TESTS=true (or DESKTOPMANAGER_RUN_EXTERNAL_UI_TESTS=true) enables live external-application UI tests and MCP end-to-end harnesses that launch real desktop apps.
  • RUN_EXPERIMENTAL_UI_TESTS=true (or DESKTOPMANAGER_RUN_EXPERIMENTAL_UI_TESTS=true) enables experimental live UI harnesses that are useful for manual validation but are not part of the stable regression pack.
  • SKIP_UI_TESTS=true (or DESKTOPMANAGER_SKIP_UI_TESTS=true) forces UI tests to skip, even if enabled elsewhere.

Owned WinForms fixtures show without activation. Tests that explicitly activate a window or depend on foreground focus also require the foreground gate. Keep RUN_FOREGROUND_UI_TESTS and DESKTOPMANAGER_RUN_FOREGROUND_UI_TESTS disabled while using the desktop; enable that slice only during a dedicated interactive run.

The gates compose intentionally:

GateWhat it permitsTypical impact
RUN_UI_TESTSTop-level UI pack enablement onlyLow
RUN_OWNED_WINDOW_UI_TESTSRepo-owned WinForms/WPF harness windowsLow to medium
RUN_DESTRUCTIVE_UI_TESTSMutations against owned harness windowsMedium to high
RUN_FOREGROUND_UI_TESTSTests that intentionally take foreground focusMedium to high
RUN_SYSTEM_UI_TESTSSystem-wide desktop changesHigh
RUN_EXTERNAL_UI_TESTSLaunching real desktop appsMedium to high
RUN_EXPERIMENTAL_UI_TESTSExperimental live harnessesVaries
powershell
# Run owned-window UI tests$env:RUN_UI_TESTS = "true"$env:RUN_OWNED_WINDOW_UI_TESTS = "true"
# Run repo-owned window mutation tests$env:RUN_DESTRUCTIVE_UI_TESTS = "true"
# Run tests that intentionally steal foreground focus$env:RUN_FOREGROUND_UI_TESTS = "true"
# Run system-wide desktop mutations$env:RUN_SYSTEM_UI_TESTS = "true"
# Run live external-application harnesses$env:RUN_EXTERNAL_UI_TESTS = "true"
# Run experimental live UI harnesses$env:RUN_EXPERIMENTAL_UI_TESTS = "true"
# Force skip$env:SKIP_UI_TESTS = "true"
# Run the repo-owned window mutation slicedotnet test Sources/DesktopManager.Tests/DesktopManager.Tests.csproj -f net8.0-windows10.0.19041.0 --no-build --filter "WindowPositionTests|WindowStateHelpersTests|WindowVisibilityTests|WindowTransparencyTests|WindowStyleModificationTests|WindowLayoutTests"
# Run the foreground-window slicedotnet test Sources/DesktopManager.Tests/DesktopManager.Tests.csproj -f net8.0-windows10.0.19041.0 --no-build --filter "DesktopAutomationAssertionTests|WindowManagerFilterTests|WindowTopMostActivationTests"
# Run the live MCP desktop pack backed by the repo-owned DesktopManager.TestApp harnessdotnet test Sources/DesktopManager.Tests/DesktopManager.Tests.csproj -f net8.0-windows10.0.19041.0 --no-build --filter "McpServer_TestApp"

When the hosted-session or experimental live harnesses skip because focus or discoverability never stabilize, they now leave structured diagnostics and artifacts rather than failing silently. See Docs/Build.Runbook.md for the hosted-session artifact flow and gate guidance.

Usage

Example in C#

The DesktopManager.Example project contains additional examples. Its default mode is read-only; mutation demos require the explicit --run-mutations option.

csharp
var monitors = new Monitors();foreach (var monitor in monitors.GetMonitors(connectedOnly: true)) {    MonitorPosition bounds = monitor.GetMonitorPosition();    Console.WriteLine($"{monitor.Index}: {monitor.DeviceName} at {bounds.Left},{bounds.Top} " +        $"({bounds.Right - bounds.Left}x{bounds.Bottom - bounds.Top})");}
// Moving a monitor changes only its top-left coordinate. Change resolution separately.// monitors.SetMonitorPosition(selected.DeviceId, left: -1920, top: 0);
Example in C# - Getting/Setting Window Position
csharp
var manager = new WindowManager();WindowInfo? window = manager.GetWindows(processName: "notepad").FirstOrDefault();if (window != null) {    manager.SetWindowPosition(window, left: 100, top: 100, width: 1000, height: 700);    manager.ActivateWindow(window);}

Platform notes

When retrieving a window's style the library uses a helper method that calls GetWindowLong on 32-bit processes and GetWindowLongPtr on 64-bit ones. The method returns an IntPtr, so callers should convert the value to the appropriate numeric type.

Example in PowerShell - Getting Monitor Information
powershell
Get-DesktopMonitor | Format-Table
Get-DesktopWallpaper -Index 0
Set-DesktopWallpaper -Index 1 -WallpaperPath "C:\Wallpapers\Landscape.jpg" -Position FitSet-DesktopWallpaper -Index 0 -WallpaperPath "C:\Wallpapers\Portrait.jpg"Set-DesktopBackgroundColor -Color 0x0000FFGet-DesktopBackgroundColor
Example in PowerShell - Wallpaper Slideshow
powershell
Start-DesktopSlideshow -ImagePath 'C:\Wallpapers\img1.jpg','C:\Wallpapers\img2.jpg' -Shuffle -SlideshowTick 300000Get-DesktopSlideshowSet-DesktopSlideshowOptions -NoShuffle -SlideshowTick 600000Step-DesktopSlideshow -Direction ForwardStop-DesktopSlideshow
powershell
$Desktop1 = Get-DesktopMonitor$Desktop1 | Format-Table
$Desktop2 = Get-DesktopMonitor -ConnectedOnly$Desktop2 | Format-Table
$Desktop3 = Get-DesktopMonitor -PrimaryOnly$Desktop3 | Format-Table
$Desktop4 = Get-DesktopMonitor -Index 1$Desktop4 | Format-Table
$Desktop5 = Get-DesktopMonitor -DeviceName "\\.\DISPLAY2"$Desktop5 | Format-Table
Example in PowerShell - Setting Monitor Position
powershell
$Desktop2 = Get-DesktopMonitor -ConnectedOnly$Desktop2 | Format-Table
Set-DesktopPosition -Index 0 -Left -3840 -Top 0 -WhatIfSet-DesktopPosition -Index 1 -Left 0 -Top 0 -WhatIf

Example in PowerShell - Getting/Setting Window Position

powershell
Get-DesktopWindow | Format-Table *
powershell
$np = Start-Process notepad -PassThruGet-DesktopWindow -ProcessId $np.Id$np | Stop-Process

[image]

powershell
Set-DesktopWindow -Name '*Zadanie - Notepad' -Height 800 -Width 1200 -Left 100Set-DesktopWindow -Name '*Zadanie - Notepad' -State Maximize
powershell
Set-DesktopWindowText -Name '*Notepad*' -Text 'Hello world'
powershell
# Send Ctrl+S to Notepad$notepad = Get-DesktopWindow -Name '*Notepad*'Invoke-DesktopKeyPress -Window $notepad -Keys @(    [DesktopManager.VirtualKey]::VK_CONTROL,    [DesktopManager.VirtualKey]::VK_S)# See Examples/KeyboardActions.ps1

Example in PowerShell - Activating and Setting Window Top-Most

powershell
Set-DesktopWindow -Name '*Notepad*' -TopMost -Activate
Example in C# - Activating and Setting Window Top-Most
csharp
var manager = new WindowManager();var window = manager.GetWindows().First();manager.SetWindowTopMost(window, true);manager.ActivateWindow(window);#### Example in PowerShell - Monitoring Display Changes
Use `Register-DesktopMonitorEvent` to react when monitors are plugged in or the display configuration changes.
```powershellRegister-DesktopMonitorEvent -Duration (New-TimeSpan -Seconds 30) -Action { Write-Host 'Display settings changed' }

Use Register-DesktopOrientationEvent or Register-DesktopResolutionEvent to handle orientation or resolution changes individually.

powershell
Register-DesktopResolutionEvent -Duration (New-TimeSpan -Seconds 30) -Action { Write-Host 'Resolution changed' }Register-DesktopOrientationEvent -Duration (New-TimeSpan -Seconds 30) -Action { Write-Host 'Orientation changed' }
Example in C# - Monitoring Display Changes

Applications can subscribe to the MonitorWatcher.DisplaySettingsChanged event.

csharp
MonitorWatcherExample.Run(TimeSpan.FromSeconds(30));
Example in PowerShell - Saving and Restoring Window Layout

For optional virtual desktop assignments, pins, Explorer folders and explicit per-desktop wallpaper restoration, see Workspace recovery.

powershell
Save-DesktopWindowLayout -Path './layout.json'# ... move windows around ...Restore-DesktopWindowLayout -Path './layout.json' -Validate
Example in C# - Saving and Restoring Window Layout
csharp
var manager = new WindowManager();manager.SaveLayout("layout.json");// ... move windows around ...manager.LoadLayout("layout.json", validate: true);

Layout restoration uses each live window at most once and skips ambiguous or missing targets. Saved layouts include process and native class names so a restarted application can be matched without relying only on its title. Legacy files retain exact process-ID/title matching; title-only and process-only fallback are disabled. Use PlanLayout to inspect matches and ApplyLayout to obtain per-window outcomes:

csharp
var layout = JsonSerializer.Deserialize<WindowLayout>(File.ReadAllText("layout.json"))!;WindowLayoutPlan plan = manager.PlanLayout(layout);foreach (WindowLayoutMatch match in plan.Windows) {    Console.WriteLine($"{match.SavedWindow.Title}: {match.Status} ({match.CandidateCount} candidates)");}IReadOnlyList<WindowLayoutApplyResult> results = manager.ApplyLayout(layout);
Examples in PowerShell - Window Keep-Alive Cmdlets
powershell
# Keep Notepad alive for one minuteStart-DesktopWindowKeepAlive -Name '*Notepad*' -Interval 00:01:00
# List active sessionsGet-DesktopWindowKeepAlive
# Stop the sessionStop-DesktopWindowKeepAlive -Name '*Notepad*'
powershell
# Keep Notepad and Calculator aliveStart-DesktopWindowKeepAlive -Name '*Notepad*'Start-DesktopWindowKeepAlive -Name '*Calculator*' -Interval 00:00:30Start-Sleep -Seconds 5Get-DesktopWindowKeepAlive | Format-Table Title, HandleStop-DesktopWindowKeepAlive -All
powershell
# Monitor RDP windowsStart-DesktopWindowKeepAlive -Name '*RDP*' -Interval 00:00:301..3 | ForEach-Object {    Start-Sleep -Seconds 10    Get-DesktopWindowKeepAlive | ForEach-Object { "Active: $($_.Title)" }}Stop-DesktopWindowKeepAlive -Name '*RDP*'
Examples in C# - Window Keep-Alive
csharp
var manager = new WindowManager();var notepad = manager.GetWindows("*Notepad*").FirstOrDefault();if (notepad != null) {    WindowKeepAlive.Instance.Start(notepad, TimeSpan.FromMinutes(1));}
csharp
foreach (var window in new WindowManager().GetWindows("*Chrome*")) {    WindowKeepAlive.Instance.Start(window, TimeSpan.FromSeconds(30));}
csharp
foreach (var handle in WindowKeepAlive.Instance.ActiveHandles) {    Console.WriteLine($"Keeping {handle} alive");}WindowKeepAlive.Instance.StopAll();

C# API Highlights

DesktopManager ships as a .NET library targeting net472, netstandard2.0, net8.0-windows10.0.19041.0, and net10.0-windows10.0.19041.0. The main entry points are:

  • Monitors for monitor enumeration, wallpaper management, brightness, resolution, orientation and slideshow control.
  • WindowManager for window enumeration, positioning, resizing and layout persistence.
  • MonitorWatcher to receive events when display settings change.
  • ScreenshotService to capture the desktop or custom regions.
  • WorkstationProfileService and WorkstationProfileStore for cohesive named workstation state.
  • AudioService and AudioEndpointWatcher for Core Audio endpoints, default roles, volume, mute, and changes.
  • SystemPowerService, DesktopSessionService, and DesktopSessionWatcher for power and session state/actions.
  • PersonalizationService, PersonalizationStateStore, and TaskbarService for reversible user settings and taskbars.
  • RadioService for supported per-radio operations and ExperimentalAirplaneModeService for the separately acknowledged undocumented global switch.
  • WifiProfileService for saved-profile inventory and exact profile connection without nearby-network scanning.
  • VirtualDesktopService for the supported window-to-desktop operations.

Input, waits, and provider health

TypeText and PasteText insert at an editable control's current selection. They do not replace its whole value to repair an unexpected result. Background text delivery prefers the target's focused editor and rejects multiple eligible editors when none is focused. Use WindowControlService.SetText when replacement is intended. Paste, native clicks, and character messages are delivered once. InputRetryCount applies only when SendInput confirms zero input was delivered. A NativeOperationOutcomeUnknownException means the target may already have changed; observe its state before deciding whether to retry. Requested focus and clipboard-text restoration also runs when delivery fails.

Asynchronous waits support cancellation on every library target. A zero timeout waits indefinitely until a match appears or cancellation is requested:

csharp
using var cancellation = new CancellationTokenSource(TimeSpan.FromSeconds(10));WindowInfo window = await manager.WaitWindowAsync("*Notepad*", cancellationToken: cancellation.Token);

UI Automation uses a separate STA worker per target process, with at most 16 workers and 64 queued operations per worker. Each worker permits up to 64 active event subscriptions with reserved cleanup capacity, so a full operation queue cannot lose cleanup. One blocked provider therefore leaves other processes available while capacity remains. In-flight native calls cannot be safely canceled or replayed and retain their worker until they return. DesktopAutomationDiagnostics.GetUiAutomationHealth() reports pending work and blocked calls without contacting the providers. Worker shutdown is bounded, and new work fails when the worker or queue limit is reached.

Window capture provenance

CaptureWindow retains its desktop fallback behavior. CaptureWindowDetailed defaults to strict window capture and records the backend, actual screen bounds, dark-pixel observation, and fallback reason. A dark image can be legitimate; strict mode retains those pixels. Desktop fallback may contain a covering application's pixels.

csharp
using WindowCaptureResult capture = ScreenshotService.CaptureWindowDetailed(window.Handle);Console.WriteLine($"{capture.Backend}: {capture.ScreenBounds}");capture.Bitmap.Save("window.png");

Pass new WindowCaptureOptions { AllowDesktopFallback = true } to opt into visible-desktop fallback. DesktopAutomationService capture objects and CLI/MCP screenshot results also expose the capture backend and fallback reason. Sparse dark-image and visual-difference sampling reads locked pixels directly, avoiding full-image managed copies; template matching retains its dense pixel buffer.

Display requests requiring a restart

SetMonitorDisplayModeDetailed returns RestartRequired when Windows accepts a display request that needs a system restart. The existing void SetMonitorDisplayMode method throws DisplayRestartRequiredException for that outcome. Workstation profile results report Succeeded = false and RestartRequired = true for this request. PowerShell and the tray app display a warning; CLI JSON and MCP results preserve the restart requirement. No API restarts Windows automatically.

来源:README.MD,提交 948a584

工具

0
SourceWeft 曾在隔离沙箱中以无凭据方式启动该软件包一次,以列出其工具,但未能完成:该软件包类型无法在沙箱中运行。

版本历史

3
  1. v0.2.3最新Oct 25, 2026
  2. v0.2.2Oct 23, 2026
  3. v0.2.1Oct 15, 2026

评分

已满足适用检查项的 50%

该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。

  • 近 30 天内可连通25 分

    请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。

  • 已声明认证方式10 分

    请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。

  • 已列出工具15 分

    请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。

  • 描述必需15 分
  • 图标10 分
  • 文档15 分
  • 许可证10 分