Repository navigation
Expand file tree
/
Copy pathAdvancedConfigurationCommand.cs
More file actions
153 lines (133 loc) · 6 KB
/
Copy pathAdvancedConfigurationCommand.cs
File metadata and controls
153 lines (133 loc) · 6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
namespace UserPromptSample;
using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using Microsoft;
using Microsoft.VisualStudio.Extensibility;
using Microsoft.VisualStudio.Extensibility.Commands;
using Microsoft.VisualStudio.Extensibility.Shell;
/// <summary>
/// AdvancedConfigurationCommand handler.
/// </summary>
[VisualStudioContribution]
internal class AdvancedConfigurationCommand : Command
{
private readonly TraceSource logger;
/// <summary>
/// Initializes a new instance of the <see cref="AdvancedConfigurationCommand"/> class.
/// </summary>
/// <param name="traceSource">Trace source instance to utilize.</param>
public AdvancedConfigurationCommand(TraceSource traceSource)
{
// This optional TraceSource can be used for logging in the command. You can use dependency injection to access
// other services here as well.
this.logger = Requires.NotNull(traceSource, nameof(traceSource));
}
internal enum Systems
{
CoreSystem,
AuxiliarySystem,
MonitoringSystem,
}
/// <inheritdoc />
public override CommandConfiguration CommandConfiguration => new(displayName: "%UserPromptSample.AdvancedConfigurationCommand.DisplayName%")
{
Placements = [CommandPlacement.KnownPlacements.ToolsMenu],
Icon = new(ImageMoniker.KnownValues.Extension, IconSettings.IconAndText),
};
/// <inheritdoc />
public override Task InitializeAsync(CancellationToken cancellationToken)
{
// Use InitializeAsync for any one-time setup or initialization.
return base.InitializeAsync(cancellationToken);
}
/// <inheritdoc />
public override async Task ExecuteCommandAsync(IClientContext context, CancellationToken cancellationToken)
{
const string Title = "Configuration Assistant";
ShellExtensibility shell = this.Extensibility.Shell();
// Show a prompt that accepts string input from the user, with a custom title.
string? projectName = await shell.ShowPromptAsync(
"Enter the name of the project to configure?",
InputPromptOptions.Default with
{
Title = Title,
Validation = new InputValidation(
@"^[A-Za-z][A-Za-z0-9_-]*$",
"Start with a letter; use only letters, numbers, hyphens, or underscores."),
ValidationCallback = async (input, token) =>
{
// Simulate an asynchronous lookup without relying on an external service.
await Task.Delay(150, token);
return string.Equals(input, "CON", StringComparison.OrdinalIgnoreCase)
? "CON is a reserved Windows name; choose another project name."
: null;
},
},
cancellationToken);
if (string.IsNullOrEmpty(projectName))
{
this.logger.TraceInformation("User did not provide project name.");
// Show a confirmation prompt (one 'OK' button) with error icon and title.
await shell.ShowPromptAsync(
"Project name is required to proceed. Exiting the configuration process.",
PromptOptions.ErrorConfirm with { Title = Title },
cancellationToken);
return;
}
// Show a prompt that accepts one of a predefined set of choices from the user, with a custom title and icon.
Systems selectedSystem = await shell.ShowPromptAsync(
"Select the system to configure:",
new PromptOptions<Systems>
{
Choices =
{
{ "Core", Systems.CoreSystem },
{ "Auxiliary", Systems.AuxiliarySystem },
{ "Monitoring", Systems.MonitoringSystem },
},
DismissedReturns = Systems.CoreSystem,
Title = Title,
Icon = ImageMoniker.KnownValues.Settings,
},
cancellationToken);
// Show a prompt that accepts a boolean response from the user ('OK' or 'Cancel'), with a custom title and icon.
bool confirmConfiguration = await shell.ShowPromptAsync(
$"The selected system ({selectedSystem}) may require additional resources. Do you want to proceed?",
PromptOptions.OKCancel with
{
Title = Title,
Icon = ImageMoniker.KnownValues.StatusSecurityWarning,
},
cancellationToken);
if (!confirmConfiguration)
{
this.logger.TraceInformation($"User canceled configuration for project ({projectName}) system ({selectedSystem}).");
await shell.ShowPromptAsync(
"Configuration process canceled.",
PromptOptions.ErrorConfirm with { Title = Title },
cancellationToken);
return;
}
// Show a confirmation prompt with an alert icon and title.
await shell.ShowPromptAsync(
"Configuration completed successfully! Thank you for using the Configuration Assistant.",
PromptOptions.AlertConfirm with { Title = Title },
cancellationToken);
const string feedbackPrompt = "Everything looks great!";
// Show a prompt that accepts string input from the user, with a default value, custom title and custom icon.
string? feedback = await shell.ShowPromptAsync(
$"Thank you for configuring {projectName}. Do you have any feedback?",
new InputPromptOptions
{
DefaultText = feedbackPrompt,
Icon = ImageMoniker.KnownValues.Feedback,
Title = Title,
},
cancellationToken);
this.logger.TraceInformation($"Feedback received: {feedback}");
}
}