Home > database >  How to use Nuget.VisualStudio.IVsPackageInstaller?
How to use Nuget.VisualStudio.IVsPackageInstaller?

Time:01-23

I am looking everywhere and nothing works, nor is it complete enough to use.

I want to dynamically install packages from a Custom Template. I have already used the element of the vsTemplate file, but I would like to be able to use the NuGet API to do it more dynamically.

This is my set up, and for now it HAS to stay this way.

  • Visual Studio 2019 Enterprise
  • EnvDTE (8.0.1)
  • EnvDTE80 (8.0.1)
  • Nuget.VisualStudio (5.11.3)
  • VSLangProj (7.0.3300)

With that, I have the following methods on the IWizard

public DTE2 Application {get;set;}
public Project Project { get; private set; }

public void RunStarted(object automationObject, Dictionary<string, string> replacementsDictionary, WizardRunKind runKind, object[] customParams)
{
   this.Application = (DTE2)automoationObject;
}

public void ProjectItemFinishedGenerating(ProjectItem projectItem)
{
  this.Project = projectItem?.ContainingProject;
}

public void RunFinished() 
{
    IVsPackageInstaller installer;
    
    //Get Nuget Package Installer

    installer.InstallPackage(null, this.Project, "MyCustomPackage", "1.0.0", false);
}

Where i put "get nuget package installer" what do i put in there?
Everywhere i search i get this "GetService" but not where that method lives, or how to access it, at the Nuget.VisualStudio version 5.11.3. I Cannot update to later versions at this time, but so far every suggestion I find on the net doesn't work.

CodePudding user response:

From some public projects using this, I found them Call GetService() from the IComponentModel, just like this:

using System;

namespace FrameworkInstallPackage
{
    using Microsoft.VisualStudio.ComponentModelHost;
    using NuGet.VisualStudio;
    using TPL = System.Threading.Tasks;
    using Microsoft.VisualStudio.Shell;
    using EnvDTE;

    internal interface IPackageHandler
    {
        /// <summary>
        /// Gets the VS package
        /// </summary>
        AsyncPackage Package { get; } //the root class AsyncPackage comes from Microsoft.VisualStudio.Shell

        /// <summary>
        /// Executes the function
        /// </summary>
        /// <param name="project">The project to peform actions on</param>
        /// <returns>A task that executes the function</returns>
        TPL.Task Execute(Project project);
    }
    internal abstract class BasePackageHandler : IPackageHandler
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="BasePackageHandler"/> class.
        /// </summary>
        /// <param name="successor">The successor</param>
        protected BasePackageHandler(IPackageHandler successor)
        {
            this.Successor = successor ?? throw new ArgumentNullException(nameof(successor));
            if (successor.Package == null)
            {
                throw new ArgumentException("successor.Package must not be null");
            }

            this.Package = this.Successor.Package;
        }

        /// <summary>
        /// Gets the VS package
        /// </summary>
        public AsyncPackage Package { get; }

        /// <summary>
        /// Gets the successor handler
        /// </summary>
        protected IPackageHandler Successor { get; }

        /// <inheritdoc/>
        public abstract TPL.Task Execute(Project project);
    }
    /// <summary>
    /// Installs the latest SlowCheetah NuGet package
    /// </summary>
    internal class NugetInstaller : BasePackageHandler
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="NugetInstaller"/> class.
        /// </summary>
        /// <param name="successor">The successor with the same package</param>
        public NugetInstaller(IPackageHandler successor)
            : base(successor)
        {
        }

        /// <inheritdoc/>
        public override async TPL.Task Execute(Project project)
        {
            var componentModel = (IComponentModel)await this.Package.GetServiceAsync(typeof(SComponentModel));
            IVsPackageInstaller packageInstaller = componentModel.GetService<IVsPackageInstaller>();
        }
    }
}

CodePudding user response:

You can use the IVsPackageInstallerServices interface to install packages dynamically using the NuGet API in Visual Studio. To get an instance of this interface, you can use the GetService method provided by the IServiceProvider interface. The IServiceProvider interface can be obtained from the DTE2 object that you have access to in the RunStarted method of your wizard.

Here's an example of how you can use the GetService method to get an instance of the IVsPackageInstallerServices interface:

 public void RunFinished() 
{
    IVsPackageInstallerServices installerServices = (IVsPackageInstallerServices)this.Application.DTE.GetService(typeof(SVsPackageInstallerServices));
    IVsPackageInstaller installer = installerServices.CreateInstaller();
    installer.InstallPackage(null, this.Project, "MyCustomPackage", "1.0.0", false);
}

You can use this IVsPackageInstaller to install packages.

Also, please make sure to add Microsoft.VisualStudio.Shell.Interop.11.0 reference to your project to access SVsPackageInstallerServices class.

  • Related