Instantly share code, notes, and snippets.
Created
May 16, 2020 23:26
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save hsimah/d5cfaf0d56afcb8178eba7433e84855c to your computer and use it in GitHub Desktop.
PowerShell interactive menu
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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