You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 13:28:11