There have been
discussions about using
NuGet outside of Visual Studio as well as an
open work item
in the NuGet issue tracker. Outside of Visual Studio in this
context means using NuGet from the command line. There is support
for this already with NuGet.exe so let us take a quick look at what
is supported at the moment.
Currently you can use NuGet.exe to download packages without
having to use Visual Studio. You can download a single package:
nuget install nunit
You can point NuGet.exe to your packages.config and it will
download any missing packages:
nuget install packages.config
What NuGet.exe will not do is update your project file (.csproj)
nor will it run any PowerShell scripts that the package uses. Which
is OK in the majority of cases.
You can go further than this though. Since SharpDevelop supports
updating project files as a proof of concept we have used
SharpDevelop to extend NuGet further so now NuGet can support
everything it does from within Visual Studio but from the command
line. From the command line we are able to install a package, have
the project file updated with assembly references and any new
files, and finally have any PowerShell scripts included in the
NuGet package processed.
Since NuGet uses PowerShell the simplest approach was to extend
the existing PowerShell cmdlets included with SharpDevelop. Now you
can write a few lines of PowerShell script to install a NuGet
package into a project that has never had a NuGet package before,
have the project itself updated and any package PowerShell scripts
run. All this from the command line without Visual Studio open.
Setting Everything Up
Download the
zip file containing the cmdlets and extract the assemblies.
First you will need to modify the PowerShell configuration. By
default PowerShell will run under .NET 2.0 but we need it to run
under .NET 4.0 since the cmdlets use .NET 4.0. Create a
powershell.exe.config file in the
C:\Windows\System32\WindowsPowerShell\v1.0 folder with the
following contents:
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0.30319"/>
<supportedRuntime version="v2.0.50727"/>
</startup>
</configuration>
Note that if you are running Windows x64 then you should run the 32 bit version of PowerShell and create a powershell.exe.config file in the C:\windows\syswow64\WindowsPowerShell\v1.0 folder.
The useLegacyV2RuntimeActivationPolicy attribute is required.
For a great explanation of what this attribute is take a look at
What is useLegacyV2RuntimeActivationPolicy for? written by
Mark Miller.
To be able to run PowerShell scripts included with a NuGet
package the
execution policy will need to be changed:
Set-ExecutionPolicy RemoteSigned -Scope Process
Now import the Package Management Cmdlets assembly. The command
below assumes the assembly is in the current working directory
otherwise the full path to the assembly will be needed.
import-module PackageManagement.Cmdlets.dll
Now we are ready to use the cmdlets.
Installing a Package
First the install-package cmdlet has a new -solution parameter
to support specifying the solution.
install-package nunit -solution MySolution\MySolution.sln
If you do not specify the project name then the first project in
the solution will be used as the default project.
install-package nunit -solution MySolution.sln -projectname MyProject
Uninstalling a Package
To uninstall a package we can use the new -solution
parameter.
uninstall-package nunit -solution MySolution.sln -projectname MyProject
Updating a Package
Once again we can specify the solution filename when updating a
package.
update-package nunit -solution MySolution.sln -projectname MyProject
Ideally we would like to be able to update all projects in the
solution in one go however this is not currently implemented.
Setting a Default Project
Instead of specifying the solution when running each command you
can set a default project with the new Set-Project command.
set-project MyProject d:\Projects\MyProject\MySolution.sln
After setting the default project the other commands can be run
without the need to specify the -solution parameter or the name of
the project.
Package PowerShell Scripts
Since SharpDevelop has its own set of DTE objects any PowerShell
scripts in the package can be run. Each of the cmdlets described
above define the DTE variable before any Powershell scripts
included with the package are run.
Conclusion
So finally we can now use a single PowerShell script to install
packages into an empty project. As a simple example:
setup.ps1:
import-module d:\scripts\PackageManagement.Cmdlets.dll
$solution = "d:\Projects\MyProject\MyProject.sln"
set-project MyProject $solution
install-package nunit
To run this from the command line with PowerShell:
powershell -ExecutionPolicy RemoteSigned -File d:\projects\MyProject\setup.ps1
Issues
If you are using $host.Version then within the PowerShell this
will return the PowerShell host version and not the NuGet
PowerShell host version.
Several extra SharpDevelop assemblies are included in the zip
file. This could be reduced with some more work.
The formatting for NuGet packages is not defined so the output
is a list of properties for each package object.
Source Code
The
source code is available on github. It is not a part of
SharpDevelop since this was an prototype. So there are no unit
tests for the new code and core parts of SharpDevelop have been
changed to support the new PowerShell cmdlets.
[Update - Oct 16, 2012] - Added information on using 32 bit version of PowerShell if using Windows x64