This project is read-only.

.NET equivalent of install.ps1, uninstall.ps1 and init.ps1


I think we should consider adding support for a .NET equivalent of the above PowerShells scripts. Although PowerShell is great and Oisin's upcoming PS helper library will help a lot, the truth is not all developers are comfortable writing
PS scripts (or at least they don't want to learn it to create a package.) So to reduce the "barrier to entry" for package authors, it'd be great to allow them to write .NET code for post-installation actions.

It could be as simple as a class in a specially-named assembly within the package, and the methods in it are decorated with [InstallAction], [UninstallAction], [InitAction] attributes respectively.



dotnetchris wrote Jun 10, 2011 at 3:14 PM

vote x1000

jstangroome wrote Aug 14, 2011 at 4:42 AM

You can embed C# directly in PowerShell in the mean time as a workaround:

dotnetjunky wrote Nov 10, 2011 at 5:46 PM

Digging this item back from the graveyard.

This has been voted 8 times. We should consider doing it.

JeffHandley wrote Jan 13, 2012 at 9:15 PM

Given the stance of using PowerShell, with the workarounds for embedding C#, this is not being considered at this time.

** Closed by JeffHandley 01/13/2012 1:15PM

SimonCropp wrote Jan 31, 2012 at 11:31 PM

please open this issue so people can vote on it. I would like to vote up. Also embedding c# in powershell is not an option fro linux and mac scenarios.

dotnetjunky wrote Jan 31, 2012 at 11:42 PM

Re-open due to Simon's request.

SimonCropp wrote Jan 31, 2012 at 11:45 PM

@dotnetjunky thanks

SimonCropp wrote Jan 31, 2012 at 11:47 PM

So my perspective is
Since powershell is unlikely to be ported to Mac and Linux any time soon (happy to be corrected here) would it be possible to also support a .net assembly for doing installs?

I am thinking that the functionality provided by the various power powershell scripts (Init.ps1, Install.ps1, Uninstall.ps1) could be done by loading a type with some kind of naming convention.

No need to "support and compile c#" just support a assembly with the required convention based type.

And no need to have a reference so attributes ([InstallAction], [UninstallAction], [InitAction]) can work. just do it by convention.

dmarsh wrote Feb 1, 2012 at 12:07 AM

It's a good idea, but I disagree with using attributes for implementation/detection. Why not use basic OO approach with base class where you override the install, uninstall and initialize methods. Then runtime can just scan assembly for all types that subclass, instantiate and invoke them for whatever particular activity is going on.

dahlbyk wrote Feb 1, 2012 at 3:17 AM

+1 for an option that doesn't involve PowerShell. +1 for convention over inheritance or attributes. You could easily check for an assembly named *.nuget.dll and expect a class named Package with static methods Install, Uninstall and Init.

SimonCropp wrote Feb 1, 2012 at 3:54 AM

+1 what @dahlbyk said

pranavkm wrote Feb 1, 2012 at 4:26 AM

An additional advantage of having managed code over powershell scripts is that we could make it work outside of VS (for instance from nuget.exe).

dotnetjunky wrote Feb 1, 2012 at 4:35 AM

@pranavkm: note that the managed code still needs to have reference to the DTE Project instance in order to do anything useful, so it is still tough for nuget.exe.

SimonCropp wrote Feb 1, 2012 at 5:27 AM

@dotnetjunky perhaps pass in objects or dynamic? no more or less type-safe than powershell

dahlbyk wrote Feb 1, 2012 at 5:42 AM

@SimonCropp I think what @dotnetjunky means is that the DTE instance is not available at all outside of Visual Studio.

I'm spiking this out now using dynamic for project...we'll see how it goes.

dotnetjunky wrote Feb 1, 2012 at 6:12 AM

It doesn't matter what type of objects we pass in. The class/object must be able to modify VS projects, and must support all properties that DTE support, which is impossible to implement outside of VS.

Perhaps we can provide a much simpler Project-like type for managed classes that we can implement outside of VS.

SimonCropp wrote Feb 1, 2012 at 6:23 AM

for most scenarios is it not sufficient to pass in the path to the solution and the path to the project?

dahlbyk wrote Feb 1, 2012 at 7:14 AM

So I have a spike working (Package class in *.nuget.dll) with methods taking string,string,dynamic,dynamic. dynamic works fine for package because it's a normal .NET object, but accessing members on the COM project instance fails with 'System.__ComObject' does not contain a definition for 'ProjectName'. Since a primary goal here is interop, I wonder if we just don't expose the project?

GregBielleman wrote Feb 1, 2012 at 7:35 AM

vote +1 for this
-1 for embedding C# directly in PowerShell

SimonCropp wrote Feb 1, 2012 at 9:20 AM

has any analysis been done on what DTE related properties and method existing nuget packages use?

pranavkm wrote Feb 1, 2012 at 3:27 PM

@dotnetjunky Agreed. I was assuming we would have some sort of compatibility layer so other IDEs would also work. Compiling against EnvDTE has the exact same cross-platform issues as Powershell today.

JeffHandley wrote Feb 8, 2012 at 10:48 PM

We will do a time-boxed investigation of this due to the high number of votes, but I'm still not sold on the ROI for this feature.

dotnetjunky wrote Jul 19, 2012 at 11:06 PM

assign to me to do investigation...

SimonCropp wrote Jul 20, 2012 at 2:31 AM

things I want to get out of this

-easier to unit test
-move close to the having full support on mono and other IDEs
-be able to select the .net language I use to do the install/uninstall/init
-not have to deal with the various qwerks of powershell eg

As for parameters being passed though
-$installPath a string will suffice
-$toolsPath a string will suffice
-$package a string will suffice
-$project this would need to be dynamic. allows easy unit testing and no need for a reference.

-$project and other IDEs: passing an EnvDTE.Project is a non starter for most other IDEs. Even making it dynamic pushes too much work back on the IDE developer as they would need to mock up and support all the behaviour of EnvDTE.Project. It would be interesting to know how many project actually use this and, of those, how many could make do with just a string containing the path to the project file. a string would be fine for all my uses. I just mod the project in xml and let VS re-load it anyway.

SimonCropp wrote Jul 20, 2012 at 2:33 AM

"$package a string will suffice" meant to say "$package a reference to the package object will suffice"

dotnetjunky wrote Jul 20, 2012 at 3:02 AM

A majority of packages that have PS scripts rely on the Project instance so that they can add/remove stuff to the projects. That's the main use case I believe. I'm interested to know what other scenarios you use the scripts for if you don't need the Project instance?

Implementation-wise, we will likely invoke your .net code in a separate AppDomain, which means we can't pass the Project instance directly because that type is not a MBRO. That's why I want to see if there are any use cases that do not require Project object.

DavidSchmitt wrote Jan 9, 2013 at 1:48 PM

I can load the project easily myself if need be in C#. Talking directly to the VS instance has strange side effects anyways, is not properly documented.

tilovell wrote Oct 25, 2013 at 6:31 PM

Can't you just have a small PS shim in Install.ps1 that calls into a Cmdlet in your install dll (also within the package)?

DarrellTunnell wrote Jun 29, 2014 at 6:55 PM

If NuGet ever plans to support other IDE's (?) perhaps it would be a good idea to abstract away from EnvDTE.Project? i.e so for the project paramater, you would pass in an abstraction that had methods for adding and removing content items, references etc etc. In that way, people's installation scripts wouldn't be tightly coupled to VS.