Execute commands from c# code

Feb 18, 2011 at 9:56 PM

Hi,

I'm looking for a way to call "Install-Package" from a C# class. I've tried to call a PowerShell command but that didn't work as I'm not that familiar with PS.

How do you suggest that I do that?

Thanks a lot!

Developer
Feb 19, 2011 at 8:32 AM

You'd need to reference NuGet.Core and use the API. What are you trying to do?

Feb 21, 2011 at 6:28 PM
Edited Feb 21, 2011 at 7:35 PM

Hi, 

Thanks for the message. What I'm trying to do is to install a package from a class in visual studio. Following your recommendations, I've managed to initialize some objects and call InstallPackage.

The problem is that the nuget package gets copied to my project directory but not deployed as if I had ran Install-Package.

Here's my code :

var feedUrl = @"...\NuGetPackages\";
var packageDestination = @"...\ClassLibrary1\ClassLibrary1";
            
var packageRepositoryFactory = new PackageRepositoryFactory(); 
IPackageRepository packageRepository = packageRepositoryFactory.CreateRepository(feedUrl);
            
var packageManager = new PackageManager(packageRepository,
                                                    new DefaultPackagePathResolver(packageDestination),
                                                    new PhysicalFileSystem(packageDestination));
            
packageManager.InstallPackage("NuGetTest");

Thanks!

Feb 21, 2011 at 10:15 PM
Edited Feb 21, 2011 at 10:19 PM

Alright, I've traced the code and looked at NuGet source. 

Using the code above, my files got copied but in the folder SolutionFolder > Project Folder > PackageName >  (Here are the lib and content folder as well as the *.nupkg file)

Could someone please let me know what I'm doing wrong and how to fix it?

From what I understand, I'm running NuGet in a project on itself (the project). So the context is not Visual Studio but the project. Is that the problem ? My use case is to have a template that creates a project then that calls nuget packages to install them.

 

Thanks a lot!

Developer
Feb 21, 2011 at 10:22 PM

If you want to use NuGet inside visual studio then you're going about it the wrong way. The core has no knowledge of visual studio so files will be dropped on disk but not added to the project. Do you have a custom project template?

Feb 21, 2011 at 10:25 PM

 

Yes I have a custom project template. Is there a way then to call NuGet from code to install / update a project reference? 

I did a small NuGet package that adds 2 files, 1 reference and 1 folder and it all gets to my folder on install when I use the Package Manager window. Is there a way to replicate this behavior without user intervention?

Thanks!

Developer
Feb 22, 2011 at 12:00 AM

It's best if you wait for NuGet 1.2 to get his behavior since we're adding some logic specifically to handle this scenario. If you want to try it out today you can download the latest build:

http://ci.nuget.org:8080/guestAuth/repository/download/bt4/.lastSuccessful/VisualStudioAddIn/NuGet.Tools.vsix

In your project template, you can reference NuGet.VisualStudio (no need to reference core) 

In the new build you can write:

var componentModel = (IComponentModel)Package.GetGlobalService(typeof(SComponentModel));

var installer = componentModel.GetService<IVsPackageInstaller>();
installer.InstallPackage(@"c:\myPackages", project, id, version: null, ignoreDependencies: false);

project is a EnvDTE project instance. Does this help?

Feb 22, 2011 at 6:44 PM

Thanks again,

I tried to figure out how to use your code but where did you take the Package object in your example?

Developer
Feb 22, 2011 at 7:07 PM

id is the package id it would have been clearer if I used your example.

installer.InstallPackage(@"c:\myPackages", project, "NuGetTest", version: null, ignoreDependencies: false);

Feb 22, 2011 at 7:08 PM

Sorry, I meant the Package in the line : (IComponentModel)Package.GetGlobalService(typeof(SComponentModel));

Developer
Feb 22, 2011 at 7:10 PM

http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.shell.package.getglobalservice.aspx

http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.componentmodelhost.scomponentmodel.aspx

 

Mar 24, 2011 at 5:32 PM

Hi,

Is it possible to do this with nuget 1.1 ? because using this tip in a iwizard for a template project require the client to install nuget 1.2 at least.

Thx

Developer
Mar 24, 2011 at 6:35 PM

It's possible but we don't guarantee backwards compat.

May 25, 2011 at 3:50 PM

@dfowler Has this patch made it into the current version of NuGet? I.e. im running 1.3.20419.9007 and I am keen to get exactly the same as above to work - ie. install a package from an IWizard.

Developer
May 25, 2011 at 5:14 PM

Yes it's in 1.2 and 1.3 :)

May 25, 2011 at 5:46 PM

Sorry to be dense, but I cant find a NuGet.VisualStudio dll anywhere? Can you post a quick example, if you dont mind? :)

May 26, 2011 at 6:49 AM

C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\Extensions\Microsoft Corporation\NuGet Package Manager\1.3.20419.9007

Jun 7, 2011 at 1:53 PM

Hi again,

First off, thanks for everyone's help sofar,

I have the following code:

PackageRepositoryFactory fac = new PackageRepositoryFactory();
                IPackageRepository packageRepository = fac.CreateRepository(new PackageSource("http://packages.nuget.org"));
                FileInfo info = new FileInfo(project.FullName);
                DirectoryInfo directoryInfo = Directory.GetParent(info.DirectoryName);
                
                

                var pm = new PackageManager(packageRepository,
                                            new DefaultPackagePathResolver(Path.Combine(directoryInfo.FullName, "NuGet")),
                                            new PhysicalFileSystem(Path.Combine(directoryInfo.FullName, "NuGet")));

                IPackage package = packageRepository.FindPackage("MvcContrib");

                var componentModel = Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SComponentModel)) as IComponentModel;

                var installer = componentModel.GetService<IVsPackageInstaller>();
                installer.InstallPackage(Path.Combine(directoryInfo.FullName, "NuGet"), project, package.Id, version: null, ignoreDependencies: false);

which is running inside Microsoft.VisualStudio.TemplateWizard.IWizard's ProjectFinishedGenerating Method, but the line where it calls GetGlobalService, its returning null - any ideas?

Any and all help is greatly appreciated! Thanks!

Monty

PackageRepositoryFactory fac = new PackageRepositoryFactory();
                IPackageRepository packageRepository = fac.CreateRepository(new PackageSource("http://packages.nuget.org"));
                FileInfo info = new FileInfo(project.FullName);
                DirectoryInfo directoryInfo = Directory.GetParent(info.DirectoryName);
                
                
 
                var pm = new PackageManager(packageRepository,
                                            new DefaultPackagePathResolver(Path.Combine(directoryInfo.FullName, "NuGet")),
                                            new PhysicalFileSystem(Path.Combine(directoryInfo.FullName, "NuGet")));
 
                IPackage package = packageRepository.FindPackage("MvcContrib");
 
                var componentModel = Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SComponentModel)) as IComponentModel;
 
                var installer = componentModel.GetService<IVsPackageInstaller>();
                installer.InstallPackage(Path.Combine(directoryInfo.FullName, "NuGet"), project, package.Id, version: null, ignoreDependencies: false);
PackageRepositoryFactory fac = new PackageRepositoryFactory();
                IPackageRepository packageRepository = fac.CreateRepository(new PackageSource("http://packages.nuget.org"));
                FileInfo info = new FileInfo(project.FullName);
                DirectoryInfo directoryInfo = Directory.GetParent(info.DirectoryName);
                
                

                var pm = new PackageManager(packageRepository,
                                            new DefaultPackagePathResolver(Path.Combine(directoryInfo.FullName, "NuGet")),
                                            new PhysicalFileSystem(Path.Combine(directoryInfo.FullName, "NuGet")));

                IPackage package = packageRepository.FindPackage("MvcContrib");

                var componentModel = Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SComponentModel)) as IComponentModel;

                var installer = componentModel.GetService<IVsPackageInstaller>();
                installer.InstallPackage(Path.Combine(directoryInfo.FullName, "NuGet"), project, package.Id, version: null, ignoreDependencies: false);
Jun 8, 2011 at 9:17 AM

grab the service provider on RunStarted from the automationObject you receive: 

public void RunStarted(object automationObject, Dictionary<string, string> replacementsDictionary, WizardRunKind runKind, object[] customParams)
{
   this.services = new ServiceProvider(automationObject as Microsoft.VisualStudio.OLE.Interop.IServiceProvider);
} 

you will need Microsoft.VisualStudio.OLE.Interop,dll and Microsoft.VisualStudio.Shell.10.0.dll

Jul 12, 2011 at 9:02 PM

Thanks for the information on this post. I ended up using this as starter for implementing this into an AddIn for a team I'm working on. I had a couple of FYI things to share for those who may dig into this a bit deeper.

 

First off I cleaned up the method a bit and made it so one could pass in path.

        public void InstallNuGetPackageForProject(string packageID, string projectpath, Project project, string repositoryPath)
        {
            IComponentModel componentModel = Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SComponentModel)) as IComponentModel;

            var installer = componentModel.GetService<IVsPackageInstaller>();

            installer.InstallPackage(repositoryPath, project, packageID, null, false);
        }

Secondly, attempting to get all of the namespaces working I had to do some odd stuff.  I had to explictly install the VS 2010 SDK. then I had to add reference to 

Microsoft.VisualStudio.ComponentmodelHost

Microsoft.VisualStudio.OLE.Interop

Microsoft.VisualStudio.Shell.10.0

Microsoft.VisualStudio.Shell.Interop

Microsoft.VisualStudio.Shell.Interop.10.0

Microsoft.VisualStudio.Shell.Interop.9.0

Microsoft.VisualStudio.Shell.Interop.8.0

Wierd in the least, but it got it working. 

 

HTH for others.