Visual Studio 2022自定义扩展命令无法执行问题求助
问题描述
我正在开发首个Visual Studio 2022自定义扩展,目标是在调试时查看IEnumerable<double>类型变量,点击放大镜视图时生成画布绘制对应数值点。此前按微软教程完成的基础Hello World功能正常,但实现自定义逻辑后,命令按钮存在却无任何反应且无报错。添加MessageBox.Show()排查发现弹窗未弹出,推测ExecuteCommandAsync方法未被调用。
相关代码
Command.cs
using Microsoft; using Microsoft.VisualStudio.Extensibility; using Microsoft.VisualStudio.Extensibility.Commands; using Microsoft.VisualStudio.Extensibility.Shell; using System.Diagnostics; using System.Windows.Controls; using System.Windows.Shapes; using System.Windows; using System.Windows.Media; using System.Linq; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; namespace MTEnumVisualizer { /// <summary> /// Command1 handler. /// </summary> [VisualStudioContribution] internal class Command1 : Command { private readonly TraceSource logger; /// <summary> /// Initializes a new instance of the <see cref="Command1"/> class. /// </summary> /// <param name="traceSource">Trace source instance to utilize.</param> public Command1(TraceSource traceSource) { this.logger = Requires.NotNull(traceSource, nameof(traceSource)); } /// <inheritdoc /> public override CommandConfiguration CommandConfiguration => new("%MTEnumVisualizer.Command1.DisplayName%") { Icon = new(ImageMoniker.KnownValues.Extension, IconSettings.IconAndText), Placements = [CommandPlacement.KnownPlacements.ExtensionsMenu], }; /// <inheritdoc /> public override Task InitializeAsync(CancellationToken cancellationToken) { this.logger.TraceInformation("Command1 initialized."); return base.InitializeAsync(cancellationToken); } /// <inheritdoc /> public override async Task ExecuteCommandAsync(IClientContext context, CancellationToken cancellationToken) { this.logger.TraceInformation("ExecuteCommandAsync started."); Requires.NotNull(context, nameof(context)); // Retrieve debugger data var dataPoints = await GetDebuggerDataPointsAsync(context, cancellationToken); if (dataPoints is null || !dataPoints.Any()) { this.logger.TraceInformation("No data points were retrieved from the debugger."); return; } // Determine the highest value and calculate canvas height double maxValue = dataPoints.Max(); double canvasHeight = maxValue * 1.1; // Create window var window = new Window { Title = "Data Points Visualization", Width = 800, Height = 600 }; // Create canvas var canvas = new Canvas { Width = 800, Height = canvasHeight }; // Draw points on the canvas foreach (var point in dataPoints) { var ellipse = new Ellipse { Width = 5, Height = 5, Fill = Brushes.Black }; Canvas.SetLeft(ellipse, point * 100); // Example X-coordinate Canvas.SetTop(ellipse, canvasHeight - (point * 100)); // Example Y-coordinate canvas.Children.Add(ellipse); } // Add canvas to window window.Content = canvas; // Show message MessageBox.Show("The window will now be displayed."); // Display window window.ShowDialog(); } private async Task<IEnumerable<double>> GetDebuggerDataPointsAsync(IClientContext context, CancellationToken cancellationToken) { // This is where the code to retrieve data points from the debugger should go await Task.Delay(100); // Simulates an asynchronous operation // Example data points var dataPoints = new List<double> { 1.0, 2.5, 3.8, 4.2, 5.0 }; this.logger.TraceInformation($"Retrieved data points: {string.Join(", ", dataPoints)}"); return dataPoints; } } }
核心代码片段
public override async Task ExecuteCommandAsync(IClientContext context, CancellationToken cancellationToken) { this.logger.TraceInformation("ExecuteCommandAsync started."); Requires.NotNull(context, nameof(context)); // Retrieve debugger data var dataPoints = await GetDebuggerDataPointsAsync(context, cancellationToken); if (dataPoints is null || !dataPoints.Any()) { this.logger.TraceInformation("No data points were retrieved from the debugger."); return; } // Determine the highest value and calculate canvas height double maxValue = dataPoints.Max(); double canvasHeight = maxValue * 1.1; // Create window var window = new Window { Title = "Data Points Visualization", Width = 800, Height = 600 }; // Create canvas var canvas = new Canvas { Width = 800, Height = canvasHeight }; // Draw points on the canvas foreach (var point in dataPoints) { var ellipse = new Ellipse { Width = 5, Height = 5, Fill = Brushes.Black }; Canvas.SetLeft(ellipse, point * 100); // Example X-coordinate Canvas.SetTop(ellipse, canvasHeight - (point * 100)); // Example Y-coordinate canvas.Children.Add(ellipse); } // Add canvas to window window.Content = canvas; // Show message MessageBox.Show("The window will now be displayed."); // Display window window.ShowDialog(); } private async Task<IEnumerable<double>> GetDebuggerDataPointsAsync(IClientContext context, CancellationToken cancellationToken) { // This is where the code to retrieve data points from the debugger should go await Task.Delay(100); // Simulates an asynchronous operation // Example data points var dataPoints = new List<double> { 1.0, 2.5, 3.8, 4.2, 5.0 }; this.logger.TraceInformation($"Retrieved data points: {string.Join(", ", dataPoints)}"); return dataPoints; }
string-ressource.json
{ "MTEnumVisualizer.Command1.DisplayName": "IEnumerable<double> Visualizer" }
ExtensionEntrypoint.cs
using Microsoft.Extensions.DependencyInjection; using Microsoft.VisualStudio.Extensibility; namespace MTEnumVisualizer { /// <summary> /// Extension entrypoint for the VisualStudio.Extensibility extension. /// </summary> [VisualStudioContribution] internal class ExtensionEntrypoint : Extension { /// <inheritdoc/> public override ExtensionConfiguration ExtensionConfiguration => new() { Metadata = new( id: "MTEnumVisualizer.6a2dffe7-b3c6-418d-9e1d-d9aa1d933426", version: this.ExtensionAssemblyVersion, publisherName: "User", displayName: "MTEnumVisualizer", description: "Visualisierer um ENumerable<double> grafisch darzustellen"), }; /// <inheritdoc /> protected override void InitializeServices(IServiceCollection serviceCollection) { base.InitializeServices(serviceCollection); // You can configure dependency injection here by adding services to the serviceCollection. } } }
内容的提问来源于stack exchange,提问作者LMA
相关产品推荐
相关产品推荐

