As promised, I’ve pushed a simple example of using StudioShell.Provider as a Nuget package dependency.  You can pull the StudioShell.DependencyExample for the code.  At the moment this package does one thing – it adds a Solution Module to your current solution if one is not already present.

Let’s take a closer look at what this package actually does and how it does it…

The Nuspec File

Inside of the StudioShell.DependencyExample nuspec file, I’ve listed StudioShell.Provider as a dependency package:

<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
  <metadata>
    <id>StudioShell.DependencyExample</id>
    <version>1.0</version>
    <authors>beefarino</authors>
    <owners>beefarino</owners>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>A simple demonstration of using StudioShell.Provider automation features from your Nuget packages</description>
    <tags>VisualStudio StudioShell DTE automation nuget</tags>
    <dependencies>
      <dependency id="StudioShell.Provider" version="1.6.2" />
    </dependencies>
  </metadata>
</package>

This ensures that the StudioShell PSDTE provider is loaded into the package manager console session before installing my example package.  This will allows me to leverage the DTE drive from my package scripts.

The Init.ps1 File

The init.ps1 files makes use of the DTE drive to spelunker the solution, project items, and folders.

The first few lines of the init.ps1 file get the currently open Visual Studio solution.  The $slnName variable is set to the “name” of the solution, which is determined as the filename without the .sln extension.  The $modulePath variable is set to the location of the solution module for this solution. 

#
#   Copyright (c) 2014 Code Owls LLC, All Rights Reserved.
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.
#
param($installPath, $toolsPath, $package, $project)

# add a new StudioShell solution module to the solution if one does not already exist

$sln = get-item dte:/solution;
$slnName = ( $sln.FullName | split-path -leaf ) -replace '\..+$','';
$modulePath = $sln.FullName -replace '\.sln$','.psm1';
#...

Next we check if a solution module does not already exist at this path; if we find one, we simply return out of the script:

#...
if( test-path $modulePath )    
{
  return;
}
#...

And if no solution file exists, we go ahead and create one using a little powershell here-string magic:

#...
@"
# Example StudioShell solution module for ${slnName}
# 

`$menuItems = @(
    # list any menu items your module adds here
    #
    # e.g.:
    new-item 'dte:/commandbars/menu bar/help' `
	 -name 'about my module' `
	-value { 'Module ${slnName}' | `
    out-outputpane; invoke-item dte:/windows/output; }
);

# this function is called automatically when your solution is unloaded
function unregister-${slnName}
{
    # remove any added menu items;
    `$menuItems | remove-item;
}
"@ | out-file -filepath $modulePath;
#...

Once the solution module file is created, we add it to the current solution items.  First we create a Solution Items folder if one does not yet exist:

#...
#create a solution items project folder if necessary
if( -not ( test-path 'dte:/solution/projects/solution items' ) )
{
    new-item -path 'dte:/solution/projects/solution items' -type folder;
}
#...

After we ensure we have a Solution Items folder, we simply add the existing file to it:

#...
#add the solution module to the solution items project folder
new-item -path 'dte:/solution/projects/solution items' -filepath $modulePath;

Looking Ahead

I’ll keep updating the StudioShell.DependencyExample package as I find new and interesting things to do with StudioShell and Nuget.  If you come up with your own, please let me know about them!