mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 03:37:59 +01:00
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request
Adds a new command-line interface (CLI) tool for FancyZones, enabling
users and automation scripts to manage window layouts without the GUI.
**Commands:**
| Command | Aliases | Description |
|---------|---------|-------------|
| `help` | | Displays general help information for all commands |
| `open-editor` | `editor`, `e` | Launch FancyZones layout editor |
| `get-monitors` | `monitors`, `m` | List all monitors and their
properties |
| `get-layouts` | `layouts`, `ls` | List all available layouts with
ASCII art preview |
| `get-active-layout` | `active`, `a` | Show currently active layout |
| `set-layout <uuid>` | `set`, `s` | Apply layout by UUID or template
name |
| `open-settings` | `settings` | Open FancyZones settings page |
| `get-hotkeys` | `hotkeys`, `hk` | List all layout hotkeys |
| `set-hotkey <key> <uuid>` | `shk` | Assign hotkey (0-9) to custom
layout |
| `remove-hotkey <key>` | `rhk` | Remove hotkey assignment |
**Key Capabilities:**
- ASCII art visualization of layouts (grid, focus, priority-grid,
canvas)
- Support for both template layouts and custom layouts
- Monitor-specific layout targeting (`--monitor N` or `--all`)
- Real-time notification to FancyZones via Windows messages
- Native AOT compilation support for fast startup
### Example Usage
```bash
# List all layouts with visual previews
FancyZonesCLI.exe ls
# Apply "columns" template to all monitors
FancyZonesCLI.exe s columns --all
# Set custom layout on monitor 2
FancyZonesCLI.exe s {uuid} --monitor 2
# Assign hotkey Win+Ctrl+Alt+3 to a layout
FancyZonesCLI.exe shk 3 {uuid}
```
https://github.com/user-attachments/assets/2b141399-a4ca-4f64-8750-f123b7e0fea7
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [ ] Closes: #xxx
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [ ] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [ ] **Tests:** Added/updated and all pass
- [ ] **Localization:** All end-user-facing strings can be localized
- [ ] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [ ] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [ ] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
91 lines
2.9 KiB
C#
91 lines
2.9 KiB
C#
// Copyright (c) Microsoft Corporation
|
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
|
// See the LICENSE file in the project root for more information.
|
|
|
|
using System;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Linq;
|
|
|
|
namespace FancyZonesCLI.Commands;
|
|
|
|
/// <summary>
|
|
/// Editor and Settings commands.
|
|
/// </summary>
|
|
internal static class EditorCommands
|
|
{
|
|
public static (int ExitCode, string Output) OpenEditor()
|
|
{
|
|
var editorExe = "PowerToys.FancyZonesEditor.exe";
|
|
|
|
// Check if editor-parameters.json exists
|
|
if (!FancyZonesData.EditorParametersExist())
|
|
{
|
|
return (1, "Error: editor-parameters.json not found.\nPlease launch FancyZones Editor using Win+` (Win+Backtick) hotkey first.");
|
|
}
|
|
|
|
// Check if editor is already running
|
|
var existingProcess = Process.GetProcessesByName("PowerToys.FancyZonesEditor").FirstOrDefault();
|
|
if (existingProcess != null)
|
|
{
|
|
NativeMethods.SetForegroundWindow(existingProcess.MainWindowHandle);
|
|
return (0, "FancyZones Editor is already running. Brought window to foreground.");
|
|
}
|
|
|
|
// Only check same directory as CLI
|
|
var editorPath = Path.Combine(AppContext.BaseDirectory, editorExe);
|
|
|
|
if (File.Exists(editorPath))
|
|
{
|
|
try
|
|
{
|
|
Process.Start(new ProcessStartInfo
|
|
{
|
|
FileName = editorPath,
|
|
UseShellExecute = true,
|
|
});
|
|
return (0, "FancyZones Editor launched successfully.");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return (1, $"Failed to launch: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
return (1, $"Error: Could not find {editorExe} in {AppContext.BaseDirectory}");
|
|
}
|
|
|
|
public static (int ExitCode, string Output) OpenSettings()
|
|
{
|
|
try
|
|
{
|
|
// Find PowerToys.exe in common locations
|
|
string powertoysExe = null;
|
|
|
|
// Check in the same directory as the CLI (typical for dev builds)
|
|
var sameDirPath = Path.Combine(AppContext.BaseDirectory, "PowerToys.exe");
|
|
if (File.Exists(sameDirPath))
|
|
{
|
|
powertoysExe = sameDirPath;
|
|
}
|
|
|
|
if (powertoysExe == null)
|
|
{
|
|
return (1, "Error: PowerToys.exe not found. Please ensure PowerToys is installed.");
|
|
}
|
|
|
|
Process.Start(new ProcessStartInfo
|
|
{
|
|
FileName = powertoysExe,
|
|
Arguments = "--open-settings=FancyZones",
|
|
UseShellExecute = false,
|
|
});
|
|
return (0, "FancyZones Settings opened successfully.");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return (1, $"Error: Failed to open FancyZones Settings. {ex.Message}");
|
|
}
|
|
}
|
|
}
|