protected override async Task <int> InvokeAsync(InvocationContext context, IStandardStreamWriter console, RolandMidiClient client) { using (var device = new DeviceController(client)) { var schema = device.Schema; var channel = context.ParseResult.ValueForOption <int>("channel"); var keys = context.ParseResult.ValueForOption <string>("keys"); var targetKit = context.ParseResult.ValueForOption <int>("kit"); if (targetKit < 1 || targetKit + 1 > schema.Kits) { console.WriteLine($"Kit {targetKit} is out of range for {schema.Identifier.Name} for this command."); console.WriteLine("Note that one extra kit is required after the specified one."); return(1); } // Detect the current kit var currentKit = await device.GetCurrentKitAsync(CancellationToken.None); // Copy current kit to target kit and target kit + 1 var kit = await device.LoadKitAsync(currentKit, progressHandler : null, CreateCancellationToken()); var dataNode = new DataTreeNode(kit.Data, kit.KitRoot); await device.SaveDescendants(dataNode, schema.GetKitRoot(targetKit).Container.Address, progressHandler : null, CreateCancellationToken()); await device.SaveDescendants(dataNode, schema.GetKitRoot(targetKit + 1).Container.Address, progressHandler : null, CreateCancellationToken()); await device.SetCurrentKitAsync(targetKit, CancellationToken.None); var programChangeCommand = (byte)(0xc0 | (channel - 1)); // Now listen for the foot switch... client.MessageReceived += async(sender, message) => { if (message.Data.Length == 2 && message.Data[0] == programChangeCommand) { console.WriteLine("Turning the page..."); SendKeysUtilities.SendWait(keys); await device.SetCurrentKitAsync(targetKit, CancellationToken.None); } }; console.WriteLine("Listening for foot switch"); await Task.Delay(TimeSpan.FromHours(1)); } return(0); CancellationToken CreateCancellationToken() => new CancellationTokenSource(10000).Token; }