Skip to content

Instantly share code, notes, and snippets.

@hsimah
Created May 16, 2020 23:26
Show Gist options
  • Save hsimah/d5cfaf0d56afcb8178eba7433e84855c to your computer and use it in GitHub Desktop.
Save hsimah/d5cfaf0d56afcb8178eba7433e84855c to your computer and use it in GitHub Desktop.
PowerShell interactive menu
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Management.Automation;
namespace ProjectShell.Startup
{
enum ActionType
{
Exit,
Run,
Selection,
None
}
class MenuItem
{
public string Label { get; set; }
public bool Active { get; set; }
public ActionType Type { get; set; }
public string Path { get; set; }
}
[Cmdlet("Start", "SolutionProject")]
public class StartupCmdlet : Cmdlet
{
private MenuItem[] menu;
private int SelectedIndex { get; set; } = 0;
[Parameter]
public string RepositoryPath { get; set; } = Path.Combine(Environment.GetEnvironmentVariable("dev_src"), "MySolutionDir");
protected override void BeginProcessing()
{
menu = new MenuItem[]
{
new MenuItem {
Label = "Account Service",
Active = false,
Type = ActionType.Selection,
Path = @"src\Account.Service\Account.Service.csproj"
},
new MenuItem {
Label = "API",
Active = false,
Type = ActionType.Selection,
Path = @"src\Api\Api.csproj"
},
new MenuItem {
Label = "Management Service",
Active = false,
Type = ActionType.Selection,
Path = @"src\Management.Service\Management.Service.csproj"
},
new MenuItem { Label = "Run selection", Type = ActionType.Run },
new MenuItem { Label = "Quit", Type = ActionType.Exit }
};
}
protected override void ProcessRecord()
{
Console.Clear();
Console.CursorVisible = false;
var run = false;
while (!run)
{
var action = RenderMenu();
switch (action)
{
case ActionType.Run:
run = true;
break;
case ActionType.Exit:
Console.CursorVisible = true;
return;
default:
break;
}
}
}
protected override void EndProcessing()
{
foreach (var item in menu.Where(i => i.Active))
{
StartProcess(Path.Combine(RepositoryPath, item.Path));
}
}
private ActionType RenderMenu()
{
Console.SetCursorPosition(0, 0);
var count = menu.Length;
var returnAction = ActionType.None;
for (int i = 0; i < count; i++)
{
if (i == SelectedIndex)
{
Console.BackgroundColor = ConsoleColor.Gray;
Console.ForegroundColor = ConsoleColor.Black;
}
Console.WriteLine(RenderMenuItem(menu[i]));
Console.ResetColor();
}
var input = Console.ReadKey();
switch (input.Key)
{
case ConsoleKey.DownArrow:
SelectedIndex = SelectedIndex == count - 1 ? 0 : SelectedIndex + 1;
break;
case ConsoleKey.UpArrow:
SelectedIndex = SelectedIndex <= 0 ? count - 1 : SelectedIndex - 1;
break;
case ConsoleKey.Spacebar:
var item = menu[SelectedIndex];
if (item.Type == ActionType.Selection)
{
item.Active = !item.Active;
}
returnAction = item.Type;
break;
case ConsoleKey.Enter:
returnAction = menu[SelectedIndex].Type;
break;
}
return returnAction;
}
private string RenderMenuItem(MenuItem item)
{
if (item.Type == ActionType.Selection)
return $"{(item.Active ? "[x]" : "[ ]")} {item.Label}";
return item.Label;
}
private void StartProcess(string name)
{
var process = new Process();
process.StartInfo.UseShellExecute = true;
process.StartInfo.FileName = "dotnet.exe";
process.StartInfo.Arguments = $"run --project {name}";
var success = process.Start();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment