【问题标题】:How to load a ModelingPackage (DSL-Tools) asynchronously in Visual Studio 2019?如何在 Visual Studio 2019 中异步加载 ModelingPackage(DSL 工具)?
【发布时间】:2019-08-24 11:11:45
【问题描述】:

我有一个 DSL 工具项目,我在其中使用 [ProvideAutoLoad],因为它向 Visual Studio 添加了一组菜单命令,以允许用户转换代码(我们有很多文本模板)以及其他一些东西。

由于 VS2019 支持not allow to autoload sync packages anymore,即使启用自动加载选项,我也会收到烦人的警告。

显然,Microsoft 没有计划提供 ModelingPackage 的异步版本(事实上,我开始质疑他们是否不会一起停止使用 DSL 工具)。

有人找到解决这个问题的方法吗?

我尝试使用另一个包 - 构建为 AsyncPackage - 这样就可以在 InitializeAsync() 上加载我的 DSL-tools 包,但我最终使用 IVsShell 服务会遇到各种异常。

protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress<VSShell.ServiceProgressData> progress)
{
    // Default behavior

    await base.InitializeAsync(cancellationToken, progress).ConfigureAwait(false);

    // Load the service designer package

    this.EnsureDesignerPackage();

    // Switche to the UI thread

    await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);

    // Menu commands

    this.InitializeMenuCommands();
}

private void EnsureDesignerPackage()
{
    // Package already loaded?

    if (!this.IsDesignerPackageLoaded())
    {
        this.LoadDesignerPackage();
    }
}

private bool IsDesignerPackageLoaded()
{
    // Package identifier

    Guid packageId = new Guid(GlobalConstants.ServiceDesignerPackageId);

    // Is loaded?

    IVsShell service = this.VsShellService;

    int hr = this.VsShellService.IsPackageLoaded(ref packageId, out IVsPackage package);
    if (ErrorHandler.Succeeded(hr) && package != null)
    {
        return true;
    }

    // Default result

    return false;
}

private void LoadDesignerPackage()
{
    // Package identifier

    Guid packageId = new Guid(GlobalConstants.ServiceDesignerPackageId);

    // Not loaded?

    int hr = this.VsShellService.IsPackageLoaded(ref packageId, out IVsPackage package);
    if (hr != VSConstants.S_OK || package == null)
    {
        // Load

        hr = this.VsShellService.LoadPackage(ref packageId, out package);
        if (ErrorHandler.Failed(hr))
        {
            string message = "Service designer loading failed: {0}.".Format().With(hr);
            this.ShowException(message);
        }
    }
}

【问题讨论】:

  • 恕我直言,DSL 工具一直处于被淘汰的边缘,随着每个 VS 的发布......这些年来我并没有真正进化,它只是继续工作,因为大多数 VS 仍然支持20 年前的界面。从长远来看,我肯定不会打赌,但你应该向微软询问(为什么不将 cmets 添加到 Mads Kristensen 的博客)

标签: vsix vs-extensibility vsx dsl-tools


【解决方案1】:

我今天早些时候碰巧让一位客户经历了同样的情况。不幸的是,上次我问到目前没有更新底层 DSL 框架以利用 AsyncPackage 或类似框架的计划。我看到你已经在dev community site 中记录了一个建议,并且刚刚投票并添加了我自己的 $.02。我会鼓励任何碰到这个问题的人投票支持上面链接的这个建议。

要向您的 DSL 包对象添加对异步加载的支持,您需要添加对 Microsoft.VisualStudio.Shell.Interop.14.0.DesignTime.dll 程序集的引用,然后编辑您的 Package.tt 文件,以添加一个 VSShell.PackageRegistration 属性并将 AllowsBackgroundLoading 设置为 true,并在同一类上实现 IAsyncLoadablePackageInitialize 接口。例如:

namespace <#= CodeGenerationUtilities.GetPackageNamespace(this.Dsl) #>
{
    /// <summary>
    /// Double-derived class to allow easier code customization.
    /// </summary>
    [VSShell::ProvideMenuResource("1000.ctmenu", 1)]
    [VSShell::ProvideToolboxItems(1)]
    [VSShell::PackageRegistration(AllowsBackgroundLoading = true)]
    [global::Microsoft.VisualStudio.TextTemplating.VSHost.ProvideDirectiveProcessor(typeof(global::<#= this.Dsl.Namespace #>.<#= directiveName #>DirectiveProcessor), global::<#= this.Dsl.Namespace #>.<#= directiveName #>DirectiveProcessor.<#= directiveName #>DirectiveProcessorName, "A directive processor that provides access to <#= directiveName #> files")]
    [global::System.Runtime.InteropServices.Guid(Constants.<#= dslName #>PackageId)]
    internal sealed partial class <#= dslName #>Package : <#= dslName #>PackageBase, VSShellInterop.IAsyncLoadablePackageInitialize
    {
        public VSShellInterop.IVsTask Initialize(VSShellInterop.IAsyncServiceProvider pServiceProvider, VSShellInterop.IProfferAsyncService pProfferService, VSShellInterop.IAsyncProgressCallback pProgressCallback)
        {
            // do async initialization here
            return null;
        }
    }
}

此致,

【讨论】:

  • 感谢您的想法!
猜你喜欢
  • 2019-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多