solutionmoduleOne of the most hidden features of StudioShell is also one of the most useful: Solution Modules.

If you don’t already know, modules are PowerShell’s way of packaging functionality into reusable units.  For instance, the PSake build automation tool is a module.  From your PowerShell session, you yank in the PSake module as a single unit using the import-module cmdlet.  When you’re done, you can remove the PSake module from your PowerShell session using the remove-module cmdlet.

Solution Modules are the same idea.  The only difference is that a solution module lives inside of your Visual Studio solution, with your code.  StudioShell automatically recognizes these modules and imports them when the solution is loaded.  When the solution is closed, the module is removed.  This makes Solution Modules a perfect way to pack your Visual Studio modifications with your solution.

Quick Example

If you haven’t already, install StudioShell

Start Visual Studio and create a new empty solution.  Name it “ModuleSolutionExample”.

Add a new test file as a solution item, name it ModuleSolutionExample.psm1.  Your solution explorer window should look like this:

ss_modules_p1

Double-click the ModuleSolutionExample.psm1 file to open it in the Visual Studio editor.  Type in the following PowerShell code (without the line numbers):

1 "Loading Solution Module" | out-outputpane; 2 3 $m = $MyInvocation.MyCommand.ScriptBlock.Module; 4 $m.OnRemove = { 5 "Unloading Solution Module" | out-outputpane; 6 }

Save the file.  Close the solution.

Now open the StudioShell console and output window from the View menu.

With the output pane displayed, re-open the ModuleSolutionExample from your File > Recent Projects and Solutions menu.  You will see “Loading Solution Module” appear in the output window as the solution is being loaded:

ss_modules_p2

Now close the solution.  The string “Unloading Solution Module” will appear as the solution is unloaded [1].

Details

StudioShell has a few requirements for a solution module:

  1. the file must have a .psm1 (script module) or .psd1 (module definition file) extension;
  2. the file name must match the name of the solution;
  3. the file must reside in the same file system location as the .sln solution file.

Outside of that, the sky’s the limit.

A Detailed Example

The script module below should give you some idea of what’s possible.  This is part of a solution module I use for a project that builds using PSake.  The solution module modifies my build menu and adds a Build With PSake menu item to the build menu, and assigns it a key binding of CTRL+SHIFT+P:

1 import-module psake; 2 3 # mount the file system location of the solution 4 function mount-solutionFolder() 5 { 6 $path = ( get-item dte:/solution ).fullName; 7 $path | split-path | pushd; 8 } 9 10 # run psake, dump output to console 11 function start-psakeBuild() 12 { 13 mount-solutionFolder; 14 invoke-psake | out-host; 15 write-prompt; 16 popd; 17 } 18 19 # add a psake build item to the build menu 20 new-item commandbars:/menubar/build -name "PSake Build" -value { 21 start-psakeBuild 22 } -binding "CTRL+SHIFT+P"; 23 24 $MyInvocation.MyCommand.ScriptBlock.Module.OnRemove = { 25 if( test-path "commandbars:/menubar/build/PSake Build" ) 26 { 27 remove-item "commandbars:/menubar/build/PSake Build" 28 } 29 }

So, solution modules provide a great way to package StudioShell scripts you use for a solution with the solution itself.  Altering the build process, customizing the PowerShell session with custom functions, modifying the IDE, folding in outside tools, whatever you can think of… 

And the best part is that the scripts travel with the solution itself, keeping your tools close to your code.

Notes

[1] The scripts in the installer at the time this post was written contain a bug that prevent solution modules from unloading.  The TIP of the repository contains the fix.