DesktopManager Windows Verification について
DesktopManager は、Windows のデスクトップ操作を提供する .NET ライブラリ、PowerShell モジュール、CLI、MCP サーバー、トレイアプリです。MCP では、まず状態を確認し、明示的なセッションで変更するエージェント自動化に対応します。
主な機能
- 01モニターとウィンドウの配置を確認・調整
- 02壁紙、明るさ、ワークステーションプロファイルの管理
- 03オーディオ、電源、セッション、無線機器の確認
- 04保存済み Windows Wi-Fi プロファイルの管理
- 05複数のインターフェースで共通コアを利用
- 06確認を先に行う MCP 自動化
活用シーン
- 01モニターとウィンドウの状態を確認
- 02ワークステーション構成を保存・復元
- 03スクリプトや CLI でデスクトップ設定を管理
- 04エージェントによる確認とデスクトップ操作
MCP 対応
MCP サーバーは stdio 経由で、エージェントにデスクトップの確認と自動化機能を提供します。安全モデルでは、先に状態を確認し、明示的なサーバーセッションを通じて変更します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
このサーバーのパッケージやリモートエンドポイントはまだ取得できていません。プロジェクトの README の手順に従ってください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
DesktopManager - C# ライブラリと PowerShell モジュール
DesktopManager は、.NET ライブラリ、PowerShell モジュール、CLI、MCP サーバー、トレイアプリとして利用できる Windows デスクトップ自動化ツールキットです。
.NET ライブラリでは、Windows、macOS、GNOME、KDE Plasma で、現在のユーザーの壁紙、ディスプレイの検出、
セッション診断を行う PortableDesktopService も提供しています。各アダプターは対応機能を報告します。
ウィンドウ自動化、トレイアプリ、CLI、既存の PowerShell コマンドは、引き続き Windows のみを対象としています。
使用方法とプラットフォームの制限については、ポータブルデスクトップ統合をご覧ください。
PowerShell Gallery からダウンロードすることもできます。
お問い合わせは、Twitter または LinkedIn からどうぞ。
概要
DesktopManager は、5 つの用途で共有できる Windows 自動化コアを提供します。
- .NET アプリケーションおよびサービス向けの C# ライブラリ
- スクリプトおよび運用ワークフロー向けの PowerShell モジュール
- ターミナルおよび JSON による自動化向けの CLI 実行ファイル
- 調査を優先するエージェント自動化向けの MCP サーバー
- 日常的なホットキー操作やモニター操作向けの Windows トレイアプリ
次の機能があります。
- モニターに関する情報の取得
- ディスプレイデバイスに関する情報の取得
- 壁紙に関する情報の取得
- 壁紙の設定
- デスクトップの背景色の取得/設定
- モニター位置の取得/設定
- ウィンドウ位置の取得/設定
- ウィンドウ状態(最小化、最大化、復元)の取得/設定
- すべてのモニター、単一のモニター、またはカスタム領域のデスクトップスクリーンショットのキャプチャ
- モニターの明るさの管理
- 壁紙スライドショーの開始/停止/次への切り替え
- 壁紙の履歴の追跡
- モニターの解像度と向きの調整
- 仮想デスクトップ上でのモニターの移動
- ウィンドウレイアウトの保存と復元
- モニター間でのウィンドウのスナップまたは移動
- 解像度、向き、ディスプレイの変更の購読
- 定期的な入力を使った非アクティブなウィンドウのスリープ防止
- ウィンドウのスリープ防止セッションの管理
- ディスプレイ、オーディオ、個人用設定、タスクバーにまたがる一貫したワークステーションプロファイルの保存と復元
- Core Audio の再生/キャプチャエンドポイントの列挙、音量とミュートの変更、既定のロールの設定、エンドポイントの変更の監視
- 電源と対話型セッションの状態の調査、ロック、サインアウト、スリープ、休止状態への移行、または期限付きのスリープ防止リースの維持
- 個人用設定のスナップショットのキャプチャと復元、タスクバーの表示、位置、自動非表示の設定
- サポート対象の Windows 無線 API を通じた Wi-Fi、Bluetooth、モバイルブロードバンド、FM 無線の列挙、監視、明示的な有効化または無効化
- 保存済みの Windows Wi-Fi プロファイルの一覧表示と、周辺ネットワークをスキャンしたり認証情報を公開したりせずに、指定した保存済みプロファイルへの接続
- ウィンドウの仮想デスクトップの調査と、公開されている Windows 仮想デスクトップ API を通じた既知のデスクトップへの移動
- ドキュメント化されたネイティブ Windows API を通じた Plug and Play デバイスと Driver Store パッケージの列挙、監視、管理
壁紙の利用者
PowerBGInfo などのアプリケーションは、モニターのジオメトリ、ディスプレイのスケール、サインイン中のセッションユーザーをライブラリから直接読み取れます。
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");
スナップショットには、呼び出し元が DPI 対応でない場合でも、物理ピクセルの境界とモニターごとの DPI が含まれます。 呼び出し元スレッドの DPI コンテキストは復元されます。インデックスは現在のディスプレイトポロジを示すため、ドッキング後または再接続後に再度読み取ってください。セッションホストで壁紙のデバイスパスが見つからない場合も、その情報は保持されます。
Monitors.SetLogonWallpaperWithResult(imagePath) は、.NET Framework、モダン .NET、netstandard の利用者向けに、Windows Runtime を通じて現在のアカウントのロック画面を設定します。結果には成功の有無、使用された仕組み、失敗した場合の内容が含まれます。コンピューターのポリシーへのフォールバックには、allowPolicyFallback: true の明示的な指定と昇格が必要です。既存の SetLogonWallpaper メソッドでは、自動的にポリシーへフォールバックします。例、OS 要件、ポリシーの制限、セッションのデプロイ動作については、壁紙利用者向け API を参照してください。
デスクトップの状態と制御
ワークステーションプロファイルは、再現可能なセットアップを切り替えるための高レベルなエントリーポイントです。接続されているモニターのモードと配置、モニターの壁紙および対応する輝度/HDR の状態、アクティブなオーディオエンドポイントの状態と既定の役割、個人用設定、タスクバーを記録します。プロファイルを適用すると、安定した識別情報に基づいてモニターを照合し、ディスプレイの変更をまとめて適用します。必須の手順が失敗した場合は、選択されたセクションをロールバックします。マシン全体に適用される個人用設定ポリシーも記録されますが、明示的に要求された場合にのみ復元されます。
Save-DesktopWorkstationProfile -Name 'office'
Get-DesktopAudioEndpoint -DataFlow Render -ActiveOnly
Get-DesktopPowerStatus
Get-DesktopSession
Get-DesktopRadio
Get-DesktopWifiProfile
Connect-DesktopWifiProfile -Name 'Corporate WiFi'
Get-DesktopDevice -Present -Problem
Get-DesktopDriverPackage
Restore-DesktopWorkstationProfile -Name 'office' -Confirm
同じ機能を CLI からも利用できます。
desktopmanager workstation save --name office
desktopmanager audio list --flow render --active
desktopmanager system power
desktopmanager system session
desktopmanager radio list
desktopmanager wifi profiles
desktopmanager wifi connect --profile "Corporate WiFi"
desktopmanager device list --present --problem
desktopmanager driver list
desktopmanager workstation apply --name office
無線の制御には、意図的に分離された 2 つの API があります。RadioService と通常の radio list/radio set コマンドは、個々の無線に対してサポートされている Windows.Devices.Radios コントラクトを使用します。グローバルな機内モードでは、文書化されていない Windows シェル COM コントラクトを使用するため、ExperimentalAirplaneModeService 配下にあり、CLI では --experimental、PowerShell では -Experimental、MCP では --allow-experimental が必要です。
Wi-Fi プロファイルへの接続は、無線の制御とは別です。WifiProfileService、Get-DesktopWifiProfile、desktopmanager wifi profiles は、Windows にすでに保存されているプロファイルのみを列挙します。指定したプロファイルへの接続には、ネイティブ Wi-Fi プロファイル API と ACM 完了通知を使用します。近隣のネットワークをスキャンしたり、BSSID を返したり、プロファイルの XML や認証情報を公開したり、現在の接続に関する位置情報に依存する詳細を照会したりすることはありません。近隣ネットワークのスキャンや関連する Wi-Fi 情報 API には、引き続き Windows の位置情報への同意が必要です。Wi-Fi アクセスと位置情報に関する API 動作の変更をご覧ください。
VirtualDesktopService が公開するのは、Windows のパブリック操作のみです。トップレベルウィンドウが現在のデスクトップ上にあるかどうかの確認、デスクトップ ID の取得、既知のデスクトップ ID への移動ができます。デスクトップの列挙、作成、名前変更、切り替え、削除は、サポート対象の API として意図的に公開していません。
新しい CLI と MCP のインターフェイスに関する、オペレーター向けの追加ドキュメント:
- Docs/DesktopManager.Cli.md
- Docs/DesktopManager.Mcp.md
- Docs/DesktopManager.Architecture.md
- Docs/DesktopManager.DesktopState.md
- Docs/DesktopManager.DeviceManagement.md
- Docs/DesktopManager.AutomationBasics.md
- Docs/DesktopManager.Plugin.md
- .agents/skills/desktopmanager-operator/SKILL.md
- .agents/skills/desktopmanager-build/SKILL.md
どのインターフェイスを使えばよいですか?
| インターフェイス | 最適な用途 | 一般的なエントリーポイント |
|---|---|---|
| C# ライブラリ | DesktopManager を独自の .NET アプリまたはサービスに組み込む | DesktopManager.dll |
| PowerShell モジュール | スクリプト、オペレーター、管理ワークフロー、反復可能なタスクの自動化 | Install-Module DesktopManager |
| CLI 実行可能ファイル | 手動操作、シェル自動化、JSON 出力、MCP ホスティング | desktopmanager.exe |
| MCP サーバー | 検査を優先する安全モデルによる、stdio 経由のエージェント主導の自動化 | desktopmanager mcp serve |
| Windows トレイアプリ | 日常的なホットキー、モニターの割り当て、HDR 制御、トレイの実行環境、ユーザーごとのスタートアップ | DesktopManager.App.exe |
全体の仕組み
DesktopManager には、共有コアがひとつあり、その上にオペレーター向けの複数のインターフェースが用意されています。
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"]
コンポーネントやリクエストフローの詳しい図については、Docs/DesktopManager.Architecture.md を参照してください。
実際の使い分けは次のとおりです。
- DesktopManager を独自のアプリケーションに組み込む場合は、ライブラリを使用します
- スクリプトで管理者やオペレーター向けの自動化を行う場合は、PowerShell を使用します
- 人が使いやすい、または JSON に対応したコマンド操作を行う場合は、CLI を使用します
- エージェントにまず調査させ、明示的なサーバーセッションを通じてのみ変更を行わせる場合は、MCP を使用します
主なエントリーポイント
| 目的 | 推奨されるエントリーポイント |
|---|---|
| 独自のコードに DesktopManager の機能を追加する | DesktopManager NuGet パッケージを参照します |
| ターミナルからデスクトップ操作を手動で実行する | desktopmanager.exe |
| トレイから DesktopManager を毎日実行する | DesktopManager.App.exe または DesktopManager MSI |
| PowerShell スクリプトから使用する | DesktopManager PowerShell モジュール |
| エージェント/ツール層に接続する | desktopmanager mcp serve |
| 全体の構成を把握する | Docs/DesktopManager.Architecture.md |
リクエストフローの概要
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"]
重要なのは、CLI、MCP、PowerShell がそれぞれ独自のデスクトップ処理を実装するのではなく、同じ共有 C# の処理を再利用して、動作の整合性を保つことです。
利用可能な PowerShell コマンドレット
| Cmdlet | 説明 |
|---|---|
| Get-DesktopMonitor | フィルターオプションを指定してモニター情報を取得します |
| Get-DesktopWallpaper | モニターの現在の壁紙のパスを取得します |
| Set-DesktopWallpaper | パス、URL、またはストリームから壁紙を適用します |
| Get-DesktopWallpaperHistory | 保存されている壁紙履歴の項目を一覧表示します |
| Set-DesktopWallpaperHistory | 壁紙履歴ファイルを更新または消去します |
| Get-DesktopSlideshow | スライドショーの画像、状態、オプション、更新間隔を確認します |
| Set-DesktopSlideshowOptions | スライドショーのシャッフル動作と更新間隔を変更します |
| Start-DesktopSlideshow | モニター間で壁紙のスライドショーを開始します |
| Stop-DesktopSlideshow | 現在実行中のスライドショーを停止します |
| Step-DesktopSlideshow | スライドショーを前または後に進めます |
| Get-DesktopBackgroundColor | 現在のデスクトップ背景色を読み取ります |
| Set-DesktopBackgroundColor | デスクトップ背景色を変更します |
| Get-DesktopBrightness | モニターの輝度レベルを読み取ります |
| Set-DesktopBrightness | モニターの輝度レベルを設定します |
| Set-DesktopPosition | 解像度を変更せず、左上の座標でモニターを移動します |
| Set-DesktopResolution | モニターの解像度または向きを変更します |
| Set-DefaultAudioDevice | 既定のオーディオ再生デバイスを設定します |
| Get-DesktopAudioEndpoint | Core Audio のレンダーおよびキャプチャエンドポイントを、音量、ミュート状態、既定の役割とともに一覧表示します |
| Set-DesktopAudioEndpoint | エンドポイントの音量、ミュート状態、または選択した既定の役割を設定します |
| Register-DesktopAudioEvent | エンドポイント、状態、プロパティ、既定の役割の変更をサブスクライブします |
| Save-DesktopWorkstationProfile | ディスプレイ、オーディオ、個人用設定、タスクバーを1つの名前付きプロファイルとして記録します |
| Get-DesktopWorkstationProfile | 名前付きワークステーションプロファイルを一覧表示または読み込みます |
| Restore-DesktopWorkstationProfile | 一致条件とロールバックオプションを指定して、名前付きワークステーションプロファイルを適用します |
| Remove-DesktopWorkstationProfile | 名前付きワークステーションプロファイルを削除します |
| Get-DesktopPowerStatus | AC 電源とバッテリーの状態を読み取ります |
| Get-DesktopSession | 現在の対話型セッションの識別情報、接続、ロック、アイドル状態を読み取ります |
| Register-DesktopSessionEvent | セッションの重要な変更をサブスクライブします |
| Lock-DesktopSession | 現在の Windows セッションをロックします |
| Exit-DesktopSession | 確認に対応して、現在の Windows セッションからサインアウトします |
| Start-DesktopKeepAwake | 期限付きのシステム/ディスプレイのスリープ防止リースを保持します |
| Suspend-DesktopSystem | 確認に対応して、スリープまたは休止状態を要求します |
| Get-DesktopPersonalization | 現在の状態を記録するか、保存済みの個人用設定スナップショットを一覧表示/読み込みます |
| Save-DesktopPersonalization | 名前付きの個人用設定スナップショットを保存します |
| Set-DesktopPersonalization | 明示的に指定した個人用設定を適用します |
| Restore-DesktopPersonalization | 名前付きの個人用設定スナップショットを復元します |
| Remove-DesktopPersonalization | 名前付きの個人用設定スナップショットを削除します |
| Get-DesktopTaskbar | モニターとの対応、表示状態、端、境界を含めてタスクバーを一覧表示します |
| Set-DesktopTaskbarAutoHide | タスクバーの自動非表示状態を明示的に設定します |
| Get-DesktopRadio | サポートされている Windows ラジオ API を通じて無線デバイスを一覧表示します |
| Set-DesktopRadio | 条件に一致するサポート対象の無線デバイスを明示的に有効化または無効化します |
| Register-DesktopRadioEvent | サポート対象の無線デバイスの状態変更をサブスクライブします |
| Get-DesktopWifiProfile | 周辺ネットワークをスキャンせずに、保存済みの Windows Wi-Fi プロファイルを一覧表示します |
| Connect-DesktopWifiProfile | 名前が完全に一致する保存済み Windows Wi-Fi プロファイルに接続します |
| Get-DesktopAirplaneMode | 明示的な承認後、実験的なグローバル機内モードの状態を読み取ります |
| Set-DesktopAirplaneMode | 明示的な承認後、実験的なグローバル機内モードを適用して確認します |
| Get-DesktopVirtualDesktop | トップレベルウィンドウのサポート対象となる仮想デスクトップの状態を確認します |
| Move-DesktopWindowToVirtualDesktop | トップレベルウィンドウを既知の仮想デスクトップ ID に移動します |
| Get-LogonWallpaper | ロック画面の壁紙のパスを取得します |
| Set-LogonWallpaper | ロック画面の壁紙を設定します |
| Set-TaskbarPosition | タスクバーを移動または非表示にします |
| Invoke-DesktopMouseMove | マウスカーソルを移動します |
| Invoke-DesktopMouseClick | マウスクリックをシミュレートします |
| Invoke-DesktopMouseScroll | マウスホイールをスクロールします |
| Invoke-DesktopScreenshot | モニターまたは領域のスクリーンショットをキャプチャします |
| Get-DesktopWindow | 表示されているウィンドウを列挙します |
| Get-DesktopWindowGeometry | 条件に一致するウィンドウの外枠とクライアント領域のジオメトリを返します |
| Get-DesktopWindowControl | Win32 または UIA のウィンドウコントロールを列挙します |
| Get-DesktopWindowControlDiagnostic | Win32 と UIA のコントロール検出および操作可否について説明します |
| Get-DesktopWindowProcessInfo | 条件に一致するウィンドウのプロセス詳細を返します |
| Get-DesktopWindowTarget | 保存済みのウィンドウ相対ターゲットを一覧表示するか、実行中のウィンドウに対して解決します |
| Get-DesktopControlTarget | 保存済みのコントロールターゲットを一覧表示するか、実行中のウィンドウに対して解決します |
| Get-DesktopHostedSessionDiagnostic | 最新のホストセッション入力診断アーティファクト、または指定したアーティファクトを読み取ります |
| Invoke-DesktopControlClick | 共通のコントロール操作ルーティングを使用して、条件に一致するコントロールをクリックします |
| Invoke-DesktopWindowClick | ウィンドウ相対位置または保存済みウィンドウターゲットをクリックします |
| Invoke-DesktopWindowDrag | ウィンドウ相対位置または保存済みターゲット間をドラッグします |
| Invoke-DesktopWindowScroll | ウィンドウ相対位置または保存済みターゲット上でスクロールします |
| Send-DesktopControlKey | キーのルーティングを独自に再実装せず、条件に一致するコントロールにキーを送信します |
| Set-DesktopControlTarget | 再利用可能なコントロールセレクタープロファイルを保存します |
| Set-DesktopControlText | 特定のコントロールにテキストを直接書き込みます |
| Set-DesktopWindow | ウィンドウを移動、サイズ変更、または制御します |
| Set-DesktopWindowSnap | ウィンドウを一般的な位置にスナップします |
| Set-DesktopWindowTarget | 再利用可能なウィンドウ相対位置ターゲットを保存します |
| Set-DesktopWindowText | ウィンドウにテキストを貼り付けるか入力します |
| Wait-DesktopWindow | ウィンドウが表示されるまで待機します |
| Wait-DesktopWindowControl | コントロールが表示されるまで待機します |
| Test-DesktopWindow | ウィンドウが存在するか、アクティブウィンドウに一致するかを確認します |
| Test-DesktopWindowControl | コントロールが存在することを確認します |
| Start-DesktopWindowKeepAlive | ウィンドウをスリープさせないよう定期的に入力を送信します |
| Stop-DesktopWindowKeepAlive | キープアライブ入力の送信を停止します |
| Get-DesktopWindowKeepAlive | キープアライブが有効なウィンドウを一覧表示します |
| Save-DesktopWindowLayout | 現在のウィンドウレイアウトをファイルに保存します |
| Restore-DesktopWindowLayout | 保存済みのウィンドウレイアウトを復元します |
| Register-DesktopMonitorEvent | ディスプレイ構成の変更をサブスクライブします |
| Register-DesktopOrientationEvent | 向きの変更をサブスクライブします |
| Register-DesktopResolutionEvent | 解像度の変更をサブスクライブします |
Cmdlet と C# メソッドの対応表
以下の表は、各 PowerShell cmdlet の背後にある最も関連性の高い API メソッドを示しています。
| Cmdlet | Main C# methods |
|---|---|
| Get-DesktopMonitor | Monitors.GetMonitors |
| Get-DesktopWallpaper | Monitors.GetWallpaper or Monitor.GetWallpaper |
| Set-DesktopWallpaper | Monitors.SetWallpaper, Monitors.SetWallpaperFromUrl |
| Get-DesktopWallpaperHistory | WallpaperHistory.GetHistory |
| Set-DesktopWallpaperHistory | WallpaperHistory.SetHistory |
| Get-DesktopSlideshow | Monitors.GetWallpaperSlideshow |
| Set-DesktopSlideshowOptions | Monitors.SetWallpaperSlideshowOptions |
| Start-DesktopSlideshow | Monitors.StartWallpaperSlideshow |
| Stop-DesktopSlideshow | Monitors.StopWallpaperSlideshow |
| Step-DesktopSlideshow | Monitors.AdvanceWallpaperSlide |
| Get-DesktopBackgroundColor | Monitors.GetBackgroundColor |
| Set-DesktopBackgroundColor | Monitors.SetBackgroundColor |
| Get-DesktopBrightness | Monitors.GetMonitorBrightness |
| Set-DesktopBrightness | Monitors.SetMonitorBrightness |
| Set-DesktopPosition | Monitor.SetMonitorPosition or Monitors.SetMonitorPosition |
| Set-DesktopResolution | Monitors.SetMonitorResolution, Monitors.SetMonitorOrientation |
| Set-DefaultAudioDevice | AudioService.SetDefaultAudioDevice |
| Get-LogonWallpaper | Monitors.GetLogonWallpaper |
| Set-LogonWallpaper | Monitors.SetLogonWallpaper |
| Set-TaskbarPosition | TaskbarService.SetTaskbarPosition / SetTaskbarVisibility |
| Invoke-DesktopMouseMove | WindowManager.MoveMouse |
| Invoke-DesktopMouseClick | WindowManager.ClickMouse |
| Invoke-DesktopMouseScroll | WindowManager.ScrollMouse |
| Invoke-DesktopScreenshot | ScreenshotService.CaptureScreen, ScreenshotService.CaptureRegion |
| Get-DesktopWindow | WindowManager.GetWindows / GetWindowsForProcess |
| Get-DesktopWindowGeometry | DesktopAutomationService.GetWindowGeometry |
| Get-DesktopWindowControl | DesktopAutomationService.GetControls |
| Get-DesktopWindowControlDiagnostic | DesktopAutomationService.GetControlDiagnostics / GetControlTargetDiagnostics |
| Get-DesktopWindowProcessInfo | WindowManager.GetWindowProcessInfo |
| Get-DesktopWindowTarget | DesktopAutomationService.ListWindowTargets, GetWindowTarget, ResolveWindowTargets |
| Get-DesktopControlTarget | DesktopAutomationService.ListControlTargets, GetControlTarget, ResolveControlTargets |
| Invoke-DesktopControlClick | DesktopAutomationService.ClickControls / ClickControlTarget |
| Invoke-DesktopWindowClick | DesktopAutomationService.ClickWindowPoint / ClickWindowTarget |
| Invoke-DesktopWindowDrag | DesktopAutomationService.DragWindowPoints / DragWindowTargets |
| Invoke-DesktopWindowScroll | DesktopAutomationService.ScrollWindowPoint / ScrollWindowTarget |
| Send-DesktopControlKey | DesktopAutomationService.SendControlKeys / SendControlTargetKeys |
| Set-DesktopControlTarget | DesktopAutomationService.SaveControlTarget |
| Set-DesktopControlText | DesktopAutomationService.SetControlText |
| Set-DesktopWindow | WindowManager.SetWindowPosition, MoveWindowToMonitor, etc. |
| Set-DesktopWindowSnap | WindowManager.SnapWindow |
| Set-DesktopWindowTarget | DesktopAutomationService.SaveWindowTarget |
| Set-DesktopWindowText | WindowManager.TypeText, WindowManager.PasteText, WindowInputService |
| Wait-DesktopWindow | DesktopAutomationService.WaitForWindows |
| Wait-DesktopWindowControl | DesktopAutomationService.WaitForControls |
| Test-DesktopWindow | DesktopAutomationService.WindowExists / ActiveWindowMatches |
| Test-DesktopWindowControl | DesktopAutomationService.ControlExists |
| Start-DesktopWindowKeepAlive | WindowKeepAlive.Start |
| Stop-DesktopWindowKeepAlive | WindowKeepAlive.Stop or StopAll |
| Get-DesktopWindowKeepAlive | WindowKeepAlive.ActiveHandles |
| Save-DesktopWindowLayout | WindowManager.SaveLayout |
| Restore-DesktopWindowLayout | WindowManager.LoadLayout |
| Register-DesktopMonitorEvent | MonitorWatcher.DisplaySettingsChanged |
| Register-DesktopOrientationEvent | MonitorWatcher.OrientationChanged |
| Register-DesktopResolutionEvent | MonitorWatcher.ResolutionChanged |
インストール
PowerShell で使用する場合は、PowerShell Gallery からインストールできます。
Install-Module DesktopManager -Force -Verbose
日常的に使う Windows のトレイアプリには、利用可能な場合は DesktopManager MSI リリース成果物を使用してください。インストーラーはスタートメニューのショートカットを作成し、アプリのスタートアップ切り替え機能は、現在のユーザーが最小化された状態でトレイから起動するように登録します。
ソースからは、PowerForge を通じてアプリと MSI をビルドできます。
.\Build\Build-DesktopManagerApp.ps1
.\Build\Build-DesktopManagerApp-MSI.ps1
msiexec.exe /i .\Artefacts\PowerForge\Msi\DesktopManager.App\win-x64\net10.0-windows10.0.19041.0\PortableCompat\output\DesktopManager.msi
検証済みの変更例
「呼び出しで例外が発生しなかった」以上の確認が必要な場合は、-Verify と -PassThru を組み合わせて使うと、コマンドレットから確認された事後条件が返されます。
# Verify a window move against the observed geometry
Set-DesktopWindow -Name "*Visual Studio Code*" -Left 0 -Top 0 -Width 1600 -Height 1200 -Verify -PassThru
# Verify exact text after a control text update
Set-DesktopControlText -Control $ctrl -Text "Hello world" -Verify -PassThru
# Verify the observed check state
Set-DesktopControlCheck -Control $checkbox -Check $true -Verify -PassThru
# Return a structured record after a control click
Invoke-DesktopControlClick -Control $button -PassThru
# Return a structured record after sending keys
Send-DesktopControlKey -Control $editor -Keys @([DesktopManager.VirtualKey]::VK_RETURN) -PassThru
検証の動作はアクションに応じて異なります。
- ウィンドウの変更では、事後条件に意味がある場合に、位置とサイズ、状態、最前面表示、クローズ、またはフォアグラウンドの条件を検証します。
Set-DesktopControlText -Verifyは、コントロールを再取得できる場合、確認されたテキスト/値を検証します。Set-DesktopControlCheck -Verifyは、確認されたチェック状態を検証します。- コントロールのクリック/キー操作では、厳密な意味での検証が誤解を招く場合、コントロールの存在とフォアグラウンド状態について、実際に確認できる情報を返します。
テストに関する注意事項
ローカル開発中にウィンドウが開いたり、デスクトップが変更されたりしないよう、UI に影響するテストはオプトイン方式です。以下の環境変数で動作を制御します。
RUN_UI_TESTS=true(またはDESKTOPMANAGER_RUN_UI_TESTS=true)を設定すると、トップレベルの UI テストパックが有効になります。RUN_OWNED_WINDOW_UI_TESTS=true(またはDESKTOPMANAGER_RUN_OWNED_WINDOW_UI_TESTS=true)を設定すると、リポジトリで作成したハーネスウィンドウを使用する、所有ウィンドウの UI テストが有効になります。RUN_DESTRUCTIVE_UI_TESTS=true(またはDESKTOPMANAGER_RUN_DESTRUCTIVE_UI_TESTS=true)を設定すると、リポジトリで作成したハーネスウィンドウに対する移動、サイズ変更、非表示、スナップ、透明度変更などの、所有ウィンドウの変更テストが有効になります。RUN_FOREGROUND_UI_TESTS=true(またはDESKTOPMANAGER_RUN_FOREGROUND_UI_TESTS=true)を設定すると、リポジトリで作成したハーネスウィンドウだけを対象にする場合でも、フォアグラウンドフォーカスを意図的に奪うテストが有効になります。RUN_SYSTEM_UI_TESTS=true(またはDESKTOPMANAGER_RUN_SYSTEM_UI_TESTS=true)を設定すると、壁紙、輝度、解像度など、現在のセッションに影響する可能性のあるモニターレベルの変更を含む、デスクトップ全体に関わる変更が有効になります。RUN_EXTERNAL_UI_TESTS=true(またはDESKTOPMANAGER_RUN_EXTERNAL_UI_TESTS=true)を設定すると、実際のデスクトップアプリを起動する、外部アプリのライブ UI テストと MCP のエンドツーエンドハーネスが有効になります。RUN_EXPERIMENTAL_UI_TESTS=true(またはDESKTOPMANAGER_RUN_EXPERIMENTAL_UI_TESTS=true)を設定すると、手動検証に役立つものの、安定版のリグレッションテストパックには含まれない、実験的なライブ UI ハーネスが有効になります。SKIP_UI_TESTS=true(またはDESKTOPMANAGER_SKIP_UI_TESTS=true)を設定すると、ほかで有効になっていても UI テストはスキップされます。
所有する WinForms フィクスチャは、アクティブ化せずに表示されます。ウィンドウを明示的にアクティブ化するテストや、フォアグラウンドフォーカスに依存するテストには、フォアグラウンドゲートも必要です。デスクトップの使用中は RUN_FOREGROUND_UI_TESTS と DESKTOPMANAGER_RUN_FOREGROUND_UI_TESTS を無効のままにし、専用の対話的な実行中に限って、そのテスト群を有効にしてください。
各ゲートは意図的に組み合わせて使用します。
| ゲート | 許可される操作 | 典型的な影響 |
|---|---|---|
RUN_UI_TESTS | トップレベルの UI テストパックの有効化のみ | 低 |
RUN_OWNED_WINDOW_UI_TESTS | リポジトリ所有の WinForms/WPF ハーネスウィンドウ | 低~中 |
RUN_DESTRUCTIVE_UI_TESTS | 所有するハーネスウィンドウに対する変更 | 中~高 |
RUN_FOREGROUND_UI_TESTS | フォアグラウンドフォーカスを意図的に取得するテスト | 中~高 |
RUN_SYSTEM_UI_TESTS | デスクトップ全体に関わる変更 | 高 |
RUN_EXTERNAL_UI_TESTS | 実際のデスクトップアプリの起動 | 中~高 |
RUN_EXPERIMENTAL_UI_TESTS | 実験的なライブハーネス | さまざま |
# 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 slice
dotnet 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 slice
dotnet 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 harness
dotnet test Sources/DesktopManager.Tests/DesktopManager.Tests.csproj -f net8.0-windows10.0.19041.0 --no-build --filter "McpServer_TestApp"
ホストセッションまたは実験的なライブハーネスで、フォーカスや検出可能性が安定しないためにスキップされた場合、現在は構造化された診断情報と成果物が残され、黙って失敗することはありません。ホストセッションでの成果物の流れとゲートのガイダンスについては、Docs/Build.Runbook.md を参照してください。
使用方法
C# の例
DesktopManager.Example プロジェクトには、追加の例が含まれています。デフォルトのモードは読み取り専用です。変更を行うデモを実行するには、--run-mutations オプションを明示的に指定する必要があります。
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);
C# の例 - ウィンドウ位置の取得と設定
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);
}
プラットフォームに関する注意事項
ウィンドウのスタイルを取得する際、ライブラリはヘルパーメソッドを使用しており、32 ビットプロセスでは
GetWindowLong を、64 ビットプロセスでは GetWindowLongPtr を呼び出します。この
メソッドは IntPtr を返すため、呼び出し側で値を適切な数値型に変換してください。
PowerShell の例 - モニター情報の取得
Get-DesktopMonitor | Format-Table
Get-DesktopWallpaper -Index 0
Set-DesktopWallpaper -Index 1 -WallpaperPath "C:\Wallpapers\Landscape.jpg" -Position Fit
Set-DesktopWallpaper -Index 0 -WallpaperPath "C:\Wallpapers\Portrait.jpg"
Set-DesktopBackgroundColor -Color 0x0000FF
Get-DesktopBackgroundColor
PowerShell の例 - 壁紙スライドショー
Start-DesktopSlideshow -ImagePath 'C:\Wallpapers\img1.jpg','C:\Wallpapers\img2.jpg' -Shuffle -SlideshowTick 300000
Get-DesktopSlideshow
Set-DesktopSlideshowOptions -NoShuffle -SlideshowTick 600000
Step-DesktopSlideshow -Direction Forward
Stop-DesktopSlideshow
$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
PowerShell の例 - モニター位置の設定
$Desktop2 = Get-DesktopMonitor -ConnectedOnly
$Desktop2 | Format-Table
Set-DesktopPosition -Index 0 -Left -3840 -Top 0 -WhatIf
Set-DesktopPosition -Index 1 -Left 0 -Top 0 -WhatIf
PowerShell の例 - ウィンドウ位置の取得と設定
Get-DesktopWindow | Format-Table *
$np = Start-Process notepad -PassThru
Get-DesktopWindow -ProcessId $np.Id
$np | Stop-Process
Set-DesktopWindow -Name '*Zadanie - Notepad' -Height 800 -Width 1200 -Left 100
Set-DesktopWindow -Name '*Zadanie - Notepad' -State Maximize
Set-DesktopWindowText -Name '*Notepad*' -Text 'Hello world'
# 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
PowerShell の例 - ウィンドウのアクティブ化と最前面表示の設定
Set-DesktopWindow -Name '*Notepad*' -TopMost -Activate
C# の例 - ウィンドウのアクティブ化と最前面表示の設定
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.
```powershell
Register-DesktopMonitorEvent -Duration (New-TimeSpan -Seconds 30) -Action { Write-Host 'Display settings changed' }
方向または解像度の変更を個別に処理するには、Register-DesktopOrientationEvent または Register-DesktopResolutionEvent を使用します。
Register-DesktopResolutionEvent -Duration (New-TimeSpan -Seconds 30) -Action { Write-Host 'Resolution changed' }
Register-DesktopOrientationEvent -Duration (New-TimeSpan -Seconds 30) -Action { Write-Host 'Orientation changed' }
C# の例 - ディスプレイの変更の監視
アプリケーションは MonitorWatcher.DisplaySettingsChanged イベントをサブスクライブできます。
MonitorWatcherExample.Run(TimeSpan.FromSeconds(30));
PowerShell の例 - ウィンドウレイアウトの保存と復元
仮想デスクトップへの割り当て、ピン留め、エクスプローラーのフォルダー、およびデスクトップごとの壁紙の明示的な復元については、ワークスペースの復元を参照してください。
Save-DesktopWindowLayout -Path './layout.json'
# ... move windows around ...
Restore-DesktopWindowLayout -Path './layout.json' -Validate
C# の例 - ウィンドウレイアウトの保存と復元
var manager = new WindowManager();
manager.SaveLayout("layout.json");
// ... move windows around ...
manager.LoadLayout("layout.json", validate: true);
レイアウトの復元では、各稼働中のウィンドウを最大 1 回だけ使用し、曖昧な対象や見つからない対象はスキップします。保存されるレイアウトにはプロセス名とネイティブクラス名が含まれるため、タイトルだけに頼らず、再起動したアプリケーションを照合できます。従来のファイルでは、プロセス ID とタイトルの完全一致を維持します。タイトルのみ、またはプロセスのみを使ったフォールバックは無効です。PlanLayout を使用して照合結果を確認し、ApplyLayout を使用してウィンドウごとの結果を取得します。
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);
PowerShell の例 - ウィンドウ維持用コマンドレット
# Keep Notepad alive for one minute
Start-DesktopWindowKeepAlive -Name '*Notepad*' -Interval 00:01:00
# List active sessions
Get-DesktopWindowKeepAlive
# Stop the session
Stop-DesktopWindowKeepAlive -Name '*Notepad*'
# Keep Notepad and Calculator alive
Start-DesktopWindowKeepAlive -Name '*Notepad*'
Start-DesktopWindowKeepAlive -Name '*Calculator*' -Interval 00:00:30
Start-Sleep -Seconds 5
Get-DesktopWindowKeepAlive | Format-Table Title, Handle
Stop-DesktopWindowKeepAlive -All
# Monitor RDP windows
Start-DesktopWindowKeepAlive -Name '*RDP*' -Interval 00:00:30
1..3 | ForEach-Object {
Start-Sleep -Seconds 10
Get-DesktopWindowKeepAlive | ForEach-Object { "Active: $($_.Title)" }
}
Stop-DesktopWindowKeepAlive -Name '*RDP*'
C# の例 - ウィンドウの維持
var manager = new WindowManager();
var notepad = manager.GetWindows("*Notepad*").FirstOrDefault();
if (notepad != null) {
WindowKeepAlive.Instance.Start(notepad, TimeSpan.FromMinutes(1));
}
foreach (var window in new WindowManager().GetWindows("*Chrome*")) {
WindowKeepAlive.Instance.Start(window, TimeSpan.FromSeconds(30));
}
foreach (var handle in WindowKeepAlive.Instance.ActiveHandles) {
Console.WriteLine($"Keeping {handle} alive");
}
WindowKeepAlive.Instance.StopAll();
C# API の主な機能
DesktopManager は、net472、netstandard2.0、net8.0-windows10.0.19041.0、および net10.0-windows10.0.19041.0 を対象とする .NET ライブラリとして提供されています。主なエントリーポイントは次のとおりです。
- モニターの列挙、壁紙の管理、明るさ、解像度、方向、およびスライドショーの制御には
Monitorsを使用します。 - ウィンドウの列挙、位置設定、サイズ変更、およびレイアウトの永続化には
WindowManagerを使用します。 - ディスプレイ設定の変更時にイベントを受信するには
MonitorWatcherを使用します。 - デスクトップ全体またはカスタム領域をキャプチャするには
ScreenshotServiceを使用します。 - 一貫性のある名前付きワークステーション状態には
WorkstationProfileServiceとWorkstationProfileStoreを使用します。 - Core Audio エンドポイント、既定のロール、音量、ミュート、および変更には
AudioServiceとAudioEndpointWatcherを使用します。 - 電源とセッションの状態や操作には
SystemPowerService、DesktopSessionService、およびDesktopSessionWatcherを使用します。 - 元に戻せるユーザー設定とタスクバーには
PersonalizationService、PersonalizationStateStore、およびTaskbarServiceを使用します。 - サポート対象の無線ごとの操作には
RadioServiceを、別途確認が必要な非公開のグローバル切り替え機能にはExperimentalAirplaneModeServiceを使用します。 - 保存済みプロファイルの一覧表示と、周辺ネットワークをスキャンせずにプロファイルを正確に指定して接続するには
WifiProfileServiceを使用します。 - サポート対象のウィンドウとデスクトップ間の操作には
VirtualDesktopServiceを使用します。
入力、待機、プロバイダーの健全性
TypeText と PasteText は、編集可能なコントロールの現在の選択位置に挿入します。予期しない結果を修正するために、値全体を置き換えることはありません。バックグラウンドでのテキスト送信では、対象でフォーカスされているエディターが優先され、フォーカスされたエディターがない場合は、複数の対象エディターがあると拒否されます。置き換えを意図する場合は、WindowControlService.SetText を使用してください。貼り付け、ネイティブクリック、文字メッセージはそれぞれ1回送信されます。InputRetryCount が適用されるのは、SendInput によって入力が一切送信されなかったことが確認された場合のみです。NativeOperationOutcomeUnknownException は、対象がすでに変更されている可能性があることを意味します。再試行するかどうかを判断する前に、その状態を確認してください。要求されたフォーカスとクリップボードテキストの復元は、送信に失敗した場合にも実行されます。
非同期の待機は、すべてのライブラリターゲットでキャンセルに対応しています。タイムアウトをゼロにすると、一致するものが現れるかキャンセルが要求されるまで、無期限に待機します。
using var cancellation = new CancellationTokenSource(TimeSpan.FromSeconds(10));
WindowInfo window = await manager.WaitWindowAsync("*Notepad*", cancellationToken: cancellation.Token);
UI Automation は対象プロセスごとに個別の STA ワーカーを使用し、ワーカー数は最大16、各ワーカーのキューに入れられる操作数は最大64です。各ワーカーでは、クリーンアップ用の予約容量を確保したうえで、最大64件のアクティブなイベントサブスクリプションを許可します。そのため、操作キューが満杯でもクリーンアップが失われることはありません。あるプロバイダーがブロックされても、容量に余裕があれば、ほかのプロセスは引き続き利用できます。実行中のネイティブ呼び出しは安全にキャンセルまたは再実行できないため、完了するまでワーカーを占有します。DesktopAutomationDiagnostics.GetUiAutomationHealth() は、プロバイダーに接続せずに、保留中の作業とブロックされた呼び出しを報告します。ワーカーのシャットダウンには上限時間が設けられており、ワーカー数またはキューの上限に達すると、新しい作業は失敗します。
ウィンドウキャプチャの取得元情報
CaptureWindow は、従来のデスクトップへのフォールバック動作を維持します。CaptureWindowDetailed は既定で厳密なウィンドウキャプチャを使用し、バックエンド、実際の画面上の境界、暗色ピクセルの検出結果、フォールバックの理由を記録します。画像が暗くても問題ない場合があります。厳密モードでは、そのピクセルが保持されます。デスクトップへのフォールバックには、前面にあるアプリケーションのピクセルが含まれる場合があります。
using WindowCaptureResult capture = ScreenshotService.CaptureWindowDetailed(window.Handle);
Console.WriteLine($"{capture.Backend}: {capture.ScreenBounds}");
capture.Bitmap.Save("window.png");
new WindowCaptureOptions { AllowDesktopFallback = true } を渡すと、表示中のデスクトップへのフォールバックを選択できます。DesktopAutomationService のキャプチャオブジェクトと CLI/MCP のスクリーンショット結果にも、キャプチャのバックエンドとフォールバックの理由が含まれます。暗色画像の疎なサンプリングと視覚的差分のサンプリングでは、ロックされたピクセルを直接読み取り、画像全体のマネージドコピーを避けます。テンプレートマッチングでは、従来どおり密なピクセルバッファーを使用します。
再起動が必要なディスプレイ要求
Windows がシステムの再起動を必要とするディスプレイ要求を受け入れた場合、SetMonitorDisplayModeDetailed は RestartRequired を返します。既存の void メソッド SetMonitorDisplayMode は、この結果に対して DisplayRestartRequiredException をスローします。ワークステーションプロファイルの結果では、この要求に対して Succeeded = false および RestartRequired = true が報告されます。PowerShell とトレイアプリには警告が表示され、CLI JSON と MCP の結果には再起動の必要性が保持されます。Windows を自動的に再起動する API はありません。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。