microsoft / VSExtensibility

A repo for upcoming changes to extensibility in Visual Studio, the new extensibility model, and language server protocol.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Commands do not run until IDE is loaded for a while

awschristou opened this issue · comments

I'm woring with a sample hybrid/in-proc extension where I've added a simple Command (MyCommand below). When I debug the extension in the experimental instance of Visual Studio, if I click on the command's menu item shortly after the IDE's main window is showing, nothing happens.

I see the following errors in my debugger's output pane. It seems like one or more components are not ready in time for the VisualStudio.Extensibility's contribution points to run. (ICommandSetProvider is my guess)

RemoteCommandsLog Information: 0 : Attempting to load service 'ProtoHybridExt.ExtensionEntrypointCommandSet (2.0)' for command set 'ProtoHybridExt.ExtensionEntrypoint'
The thread '[Thread Destroyed]' (1316) has exited with code 0 (0x0).
RemoteCommandsLog Error: 0 : Failed to load service 'ProtoHybridExt.ExtensionEntrypointCommandSet (2.0)'

InternalErrorException: Cannot find an instance of the Microsoft.VisualStudio.RpcContracts.Commands.ICommandSetProvider service.

Microsoft.Assumes.Fail(String message)
Microsoft.Assumes.Present[T](T component)
Microsoft.VisualStudio.Commands.Client.Models.CommandSetModel.<EnsureCommandSetAsync>d__52.MoveNext()

HResult: 0x80131500

RemoteCommandsLog Error: 0 : Error executing command ProtoHybridExt.ExtensionEntrypoint:ProtoHybridExt.MyCommand (AAA - Hybrid Command)

InvalidOperationException: Failed to activate service for command execution.

Microsoft.VisualStudio.Commands.Client.Models.CommandSetModel.<>c__DisplayClass56_0.<<ExecuteCommandAsync>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.VisualStudio.Threading.ReentrantSemaphore.NotAllowedSemaphore.<>c__DisplayClass2_0.<<ExecuteAsync>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.VisualStudio.Threading.ReentrantSemaphore.NotAllowedSemaphore.<ExecuteAsync>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.VisualStudio.Commands.Client.Models.CommandSetModel.RemoteCommandModel.<ExecAsync>d__26.MoveNext()

HResult: 0x80131509

Is this expected behavior? The command's invocation has been cancelled, and never runs on its own. Sometimes I have to click the menu 2 or 3 times (or wait 20 seconds before clicking the menu) before the command runs successfully. I'm concerned that users would be confused and think the extension is broken if we used that in an extension.

In an ideal world, the menu items would either be non-visible, or visible and disabled until the VS.Extensibility prerequisites have been loaded.

For reference, I haven't tried to install this into my non-experimental instance of Visual Studio. I'm running 17.9.5, and use the following package references:

    <PackageReference Include="Microsoft.VisualStudio.SDK" Version="17.7.37357" ExcludeAssets="runtime">
        <IncludeAssets>compile; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
    <PackageReference Include="Microsoft.VisualStudio.Extensibility.Sdk" Version="17.9.2092" ExcludeAssets="runtime" />
    <PackageReference Include="Microsoft.VisualStudio.Extensibility.Build" Version="17.9.2092" ExcludeAssets="runtime" />
namespace ProtoHybridExt
{
    [VisualStudioContribution]
    internal class MyCommand : Command
    {

        ...

        public override CommandConfiguration CommandConfiguration => new("Hello Sample")
        {
            Icon = new(ImageMoniker.KnownValues.Extension, IconSettings.IconAndText),
            Placements = new[] {CommandPlacement.KnownPlacements.ExtensionsMenu},
        };

        public override async Task ExecuteCommandAsync(IClientContext context, CancellationToken cancellationToken)
        {
            var message = "Hello"
            await Extensibility.Shell().ShowPromptAsync(message, PromptOptions.OKCancel, cancellationToken);
        }
    }
}

This issue should be solved in the upcoming VS 17.10 Preview 3