It's Build Day! In honor, here's a tip to script Visual Studio with PowerShell
In a couple hours, Build 2014 will kick off. Everyone is focused, rightly so, on the keynotes and sessions, which you can catch here, https://channel9.msdn.com. here http://www.buildwindows.com/ and finally https://channel9.msdn.com/events/build/2014, so today, in honor of the many presenters, I'm going to highlight a tip from Stuart Leeks on how you can streamline presenting in Visual Studio...
In this post I’ll show a solution for automating tasks when opening a solution in Visual Studio.
NuGet brings PowerShell
In the grand scheme of things it hasn’t been that long since NuGet first arrived, but I can barely remember what I did without it! Aside from the standard benefits, one of the things I love about it is the Package Manager Console. Yes, I’m a keyboard fan and (having assigned a shortcut key for it) I can easily add packages without taking my hands of the keyboard. But the console also gives me PowerShell inside Visual Studio!
When running inside the console, you can invoke standard PowerShell cmdlets and aliases. For example, dir or Get-ChildItem will work (and you start in the solution directory which is convenient!). NuGet also adds additional cmdlets, e.g. Install-Package, Get-Project. Added to that, you get some extra context, so $dte will give you access to the top-level DTE instance for the Visual Studio automation API. So entering $dte.Solution.FullName will give you the full path to the currently open solution.
NuGet Package Scripts
When I’m creating demos I try to be reasonably disciplined and do things like
- create scripts that restore the demo folder to a clean state
- write demo notes that include what files to open for the demo, what pages on the site to open (I demo web stuff a lot!)
- create copy of the demo solution in final form – this is great for those days when nothing seems to go right and you just want to skip to the end and still have something to show!
I had a particular session a while back that I originally co-presented with a colleague, but subsequently ended up presenting it on my own. This was a bit of a challenge as some of the demos needed a few configuration steps after loading the solution to keep the flow of the session. When it was just me presenting there was no time to do that, so I pondered how to solve this. The solution? NuGet and PowerShell scripts!
Putting the bits together
The solution was actually quite simple: create a NuGet package with an Init.ps1 that runs when the solution loads and finds and executes a known script in the solution.
I’m not going to go into the implementation details in depth here as I think the concept is fairly simple once you know what the moving parts are. There are a couple of other things that I thought are worth mentioning.
Preventing _startup.ps1 from executing...
I found that there were a few common things that I wanted to do in my _startup.ps1 scripts, so I added them to the package as cmdlets. The DTE object model for Visual Studio is powerful, but not necessarily friendly
- Open-SolutionFile. Takes the filename to open. Normally my demo steps specify the files to open as part of the initialisation, so this is handy.
- Open-ProjectFile. Takes project name and filename and opens the file within that project. This simply saves a step of adding the project folder into the filename.
- Close-AllDocuments. If I’m going to open the files that I want then I don’t want any other files, so I call this first
- Invoke-SolutionBuild. Build the solution!
- Start-Solution. Build and run the solution
The Open-SolutionFile and Open-ProjectFile cmdlets both return an EnvDTE.Window object, so you can invoke methods on this, e.g.