diff --git a/src/WindowResizer.Base/ConfigUtils.cs b/src/WindowResizer.Base/ConfigUtils.cs index 6bbf4b8..85f5b12 100644 --- a/src/WindowResizer.Base/ConfigUtils.cs +++ b/src/WindowResizer.Base/ConfigUtils.cs @@ -25,5 +25,35 @@ public static bool Load(string? configPath, Action? onError) return false; } } + + public static bool LoadOrCreate(string? configPath, string? profileName, Action? onError) + { + configPath ??= Path.Combine( + Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), nameof(WindowResizer)), + DefaultConfigFile); + + profileName ??= string.Empty; + + try + { + ProfilesFactory.Load(configPath); + } + catch (Exception ex) + { + if (ex is System.IO.FileNotFoundException) + { + var cnf = ProfileConfig.NewConfig(profileName); + } + else + { + onError?.Invoke("Unexpected error while trying to load config file at \"" + configPath + "\": " + ex.Message); + return false; + } + } + + ProfilesFactory.ConfigPath = configPath; + return true; + } + } } diff --git a/src/WindowResizer.Base/WindowCmd.cs b/src/WindowResizer.Base/WindowCmd.cs index e8067c7..cad2283 100644 --- a/src/WindowResizer.Base/WindowCmd.cs +++ b/src/WindowResizer.Base/WindowCmd.cs @@ -75,6 +75,48 @@ public static bool Resize(string? configPath, string? profileName, string? proce return true; } + public static bool SaveAll(string? configPath, string? profileName, + Action? onError = null, + Action>? onDebug = null) + { + var profile = LoadOrCreateConfig(configPath, profileName, onError); + + if (profile == null) + { + return false; + } + + profile.WindowSizes.Clear(); + + var windows = Resizer.GetOpenWindows(); + var targets = new List(); + + foreach (var handle in windows) + { + if (!IsProcessAvailable(handle, out string processName, null)) + { + continue; + } + + var t = Resizer.GetWindowTitle(handle); + + targets.Add(new TargetWindow(handle, processName, t)); + } + + foreach (var tp in targets) + { + UpdateOrSaveWindowSize(tp.Handle, profile, (p, e) => + { + tp.Result = "Elevated privileges may be required."; + onError?.Invoke($"Unable to save position for process <{p}>, elevated privileges may be required."); + }); + } + + onDebug?.Invoke(targets); + + return true; + } + public class TargetWindow { public TargetWindow(IntPtr handle, string processName, string? title) @@ -114,4 +156,14 @@ public TargetWindow(IntPtr handle, string processName, string? title) return p; } + + private static ProfileConfig? LoadOrCreateConfig(string? configPath, string? profileName, Action? onError) + { + if (!ConfigUtils.LoadOrCreate(configPath, profileName, onError)) + { + return null; + } + + return ProfilesFactory.Current; + } } diff --git a/src/WindowResizer.CLI/Commands/SaveAllCommand.cs b/src/WindowResizer.CLI/Commands/SaveAllCommand.cs new file mode 100755 index 0000000..2f06be4 --- /dev/null +++ b/src/WindowResizer.CLI/Commands/SaveAllCommand.cs @@ -0,0 +1,65 @@ +using System.Collections.Generic; +using System.CommandLine; +using System.Linq; +using System.Threading.Tasks; +using Spectre.Console; +using WindowResizer.Base; +using WindowResizer.CLI.Utils; + +namespace WindowResizer.CLI.Commands +{ + internal class SaveAllCommand : Command + { + public SaveAllCommand() : base("saveAll", "Saves the current position of all open windows.") + { + var configOption = new ConfigOption(); + AddOption(configOption); + var profileOption = new ProfileOption(); + AddOption(profileOption); + var verboseOption = new VerboseOption(); + AddOption(verboseOption); + + this.SetHandler((config, profile, verbose) => + { + void VerboseInfo(List lists) + { + if (verbose) + { + Verbose(lists); + } + } + + var success = WindowCmd.SaveAll(config?.FullName, profile, Output.Error, VerboseInfo); + + return Task.FromResult(success ? 0 : 1); + }, configOption, profileOption, verboseOption); + } + + private static void Verbose(List lists) + { + if (!lists.Any()) + { + Output.Echo("No windows to be saved."); + return; + } + + Output.Echo("The following windows were saved:"); + + var table = new Table(); + table.AddColumn(new TableColumn("Handle")); + table.AddColumn(new TableColumn("Process")); + table.AddColumn(new TableColumn("Title")); + table.AddColumn(new TableColumn("Success").Centered()); + table.AddColumn(new TableColumn("Error")); + foreach (var item in lists) + { + var result = string.IsNullOrEmpty(item.Result) ? "[green]Y[/]" : "[red]N[/]"; + table.AddRow(item.Handle.ToString(), $"[green]{item.ProcessName}[/]", item.Title ?? string.Empty, result, $"[red]{item.Result}[/]"); + } + + table.Border(TableBorder.Square); + table.Alignment(Justify.Left); + AnsiConsole.Write(table); + } + } +} diff --git a/src/WindowResizer.CLI/Program.cs b/src/WindowResizer.CLI/Program.cs index 970adc8..ca3bc0b 100644 --- a/src/WindowResizer.CLI/Program.cs +++ b/src/WindowResizer.CLI/Program.cs @@ -18,6 +18,7 @@ static Task Main(string[] args) var rootCommand = new RootCommand($"{nameof(WindowResizer)} CLI."); rootCommand.AddCommand(new ResizeCommand()); + rootCommand.AddCommand(new SaveAllCommand()); var parser = new CommandLineBuilder(rootCommand) .UseDefaults()