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

如何在Template Wizard中获取IVsPackageInstaller实现动态NuGet安装?

问题:IWizard中如何通过AutomationObject获取IVsPackageInstaller动态安装NuGet包

我有VS模板及模板向导,在IWizard的RunStarted实现里,Visual Studio提供了AutomationObject。现有方案都提到通过IComponentModel.GetService获取NuGet.VisualStudio的IVsPackageInstaller,但我无法获取IComponentModel引用,将automationObject强制转换为IComponentModel也失败了,请问怎么在IWizard实现中(通过automationObject)连接到IVsPackageInstaller来动态安装NuGet包?

补充代码

以下是Microsoft.VisualStudio.TemplateWizard程序集中的IWizard基础代码:

public class MyWizard : IWizard
{
    public DTE Application { get; private set; }

    public void RunStarted(object automationObject, Dictionary<string, string> replacementsDictionary, WizardRunKind runKind, object[] customParams)
    {
        this.Application = automationObject as DTE;
        replacementsDictionary["$safeitemname$"] = "newitemcode.cs";
    }

    public void ProjectFinishedGenerating(Project project)
    {
        /* n/a for item generation */
    }

    public void ProjectItemFinishedGenerating(ProjectItem projectItem)
    {
        IVsSolution sol = this.Application.Solution as IVsSolution;
        if (sol != null)
        {
            InstallNugetPackages();
        }
    }

    private void InstallNugetPackages()
    {
        IComponentModel host = this.Application as IComponentModel; //<-- 这里失败,host为null
        IVsPackageInstaller installer = host.GetService<IVsPackageInstaller>();
    }

    public bool ShouldAddProjectItem(string filePath)
    {
        throw new NotImplementedException();
    }

    public void BeforeOpeningFile(ProjectItem projectItem)
    {
        throw new NotImplementedException();
    }

    public void RunFinished()
    {
        throw new NotImplementedException();
    }
}

解决方案

核心思路

AutomationObject本质是DTE对象,无法直接转换为IComponentModel。需要通过DTE获取VS的服务容器,再从中获取IComponentModel实例,进而拿到IVsPackageInstaller。

步骤及修改后的代码

  1. 添加必要引用

    • 引用Microsoft.VisualStudio.Shell.Immutable.10.0(或更高版本)
    • 安装并引用NuGet.VisualStudio NuGet包
  2. 修改向导代码
    调整ProjectItemFinishedGenerating和InstallNugetPackages方法,正确获取服务并安装包:

using Microsoft.VisualStudio.Shell;
using NuGet.VisualStudio;
using Microsoft.VisualStudio.OLE.Interop;
// 保留原有其他引用

public class MyWizard : IWizard
{
    public DTE Application { get; private set; }

    public void RunStarted(object automationObject, Dictionary<string, string> replacementsDictionary, WizardRunKind runKind, object[] customParams)
    {
        this.Application = automationObject as DTE;
        replacementsDictionary["$safeitemname$"] = "newitemcode.cs";
    }

    public void ProjectFinishedGenerating(Project project)
    {
        /* n/a for item generation */
    }

    public void ProjectItemFinishedGenerating(ProjectItem projectItem)
    {
        // 直接从ProjectItem获取所属项目,无需转换IVsSolution
        if (projectItem?.ContainingProject != null)
        {
            InstallNugetPackages(projectItem.ContainingProject);
        }
    }

    private void InstallNugetPackages(Project targetProject)
    {
        // 通过DTE创建服务提供者
        var serviceProvider = new ServiceProvider((IServiceProvider)this.Application);
        
        // 获取IComponentModel实例
        IComponentModel componentModel = serviceProvider.GetService<SComponentModel, IComponentModel>();
        
        if (componentModel == null) return;
        
        // 获取IVsPackageInstaller
        IVsPackageInstaller installer = componentModel.GetService<IVsPackageInstaller>();
        
        // 示例:安装指定版本的Newtonsoft.Json包
        installer?.InstallPackage(
            sourceRepository: null, // 使用默认NuGet源
            project: targetProject,
            packageId: "Newtonsoft.Json",
            version: "13.0.3",
            ignoreDependencies: false
        );
    }

    public bool ShouldAddProjectItem(string filePath)
    {
        throw new NotImplementedException();
    }

    public void BeforeOpeningFile(ProjectItem projectItem)
    {
        throw new NotImplementedException();
    }

    public void RunFinished()
    {
        throw new NotImplementedException();
    }
}

注意事项

  • 确保向导项目的目标框架与Visual Studio版本兼容
  • 如果需要自定义NuGet源,可以修改InstallPackage方法的sourceRepository参数
  • 处理好异常情况(比如包不存在、网络问题等),避免向导崩溃

内容的提问来源于stack exchange,提问作者JaedenRuiner

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 20:38:32