Skip to content

Instantly share code, notes, and snippets.

@kyle-herzog
Created March 13, 2014 20:33
Show Gist options
  • Save kyle-herzog/9536407 to your computer and use it in GitHub Desktop.
Save kyle-herzog/9536407 to your computer and use it in GitHub Desktop.
Get Visual Studio Instances
param
(
[Parameter(Mandatory=$true)][string] $solutionFullName
)
function Register-CSharpCode ([string] $code, $FrameworkVersion="v2.0.50727", [Array]$References)
{
#
# Get an instance of the CSharp code provider
#
$cp = new-object Microsoft.CSharp.CSharpCodeProvider
#
# Build up a compiler params object...
$framework = Join-Path $env:windir "Microsoft.NET\Framework\$FrameWorkVersion"
$refs = New-Object Collections.ArrayList
$refs.AddRange( @("${framework}\System.dll",
"C:\Program Files (x86)\Common Files\microsoft shared\MSEnv\PublicAssemblies\envdte.dll",
"${framework}\system.windows.forms.dll",
"${framework}\System.data.dll",
"${framework}\System.Drawing.dll",
"${framework}\System.Xml.dll"))
if ($references.Count -ge 1)
{
$refs.AddRange($References)
}
$cpar = New-Object System.CodeDom.Compiler.CompilerParameters
$cpar.GenerateInMemory = $true
$cpar.GenerateExecutable = $false
$cpar.OutputAssembly = "custom"
$cpar.ReferencedAssemblies.AddRange($refs)
$cr = $cp.CompileAssemblyFromSource($cpar, $code)
if ( $cr.Errors.Count)
{
$codeLines = $code.Split("`n");
foreach ($ce in $cr.Errors)
{
write-host "Error: $($codeLines[$($ce.Line - 1)])"
$ce |out-default
}
Throw "INVALID DATA: Errors encountered while compiling code"
}
}
$code = @'
using System;
using System.Collections;
using System.Runtime.InteropServices;
using EnvDTE;
using Microsoft.Win32;
namespace PInvoke
{
public class VisualStudioInstances
{
[DllImport("ole32.dll")]
public static extern int GetRunningObjectTable(int reserved, out UCOMIRunningObjectTable prot);
[DllImport("ole32.dll")]
public static extern int CreateBindCtx(int reserved, out UCOMIBindCtx ppbc);
public static Hashtable GetRunningObjectTable()
{
Hashtable result = new Hashtable();
int numFetched;
UCOMIRunningObjectTable runningObjectTable;
UCOMIEnumMoniker monikerEnumerator;
UCOMIMoniker[] monikers = new UCOMIMoniker[1];
GetRunningObjectTable(0, out runningObjectTable);
runningObjectTable.EnumRunning(out monikerEnumerator);
monikerEnumerator.Reset();
while (monikerEnumerator.Next(1, monikers, out numFetched) == 0)
{
UCOMIBindCtx ctx;
CreateBindCtx(0, out ctx);
string runningObjectName;
monikers[0].GetDisplayName(ctx, null, out runningObjectName);
object runningObjectVal;
runningObjectTable.GetObject( monikers[0], out runningObjectVal);
result[ runningObjectName ] = runningObjectVal;
}
return result;
}
public static Hashtable GetIDEInstances( bool openSolutionsOnly )
{
Hashtable runningIDEInstances = new Hashtable();
Hashtable runningObjects = GetRunningObjectTable();
IDictionaryEnumerator rotEnumerator = runningObjects.GetEnumerator();
while ( rotEnumerator.MoveNext() )
{
string candidateName = (string) rotEnumerator.Key;
if (!candidateName.StartsWith("!VisualStudio.DTE"))
continue;
_DTE ide = rotEnumerator.Value as _DTE;
if (ide == null)
continue;
if (openSolutionsOnly)
{
try
{
string solutionFile = ide.Solution.FullName;
if (solutionFile != String.Empty)
{
runningIDEInstances[ candidateName ] = ide;
}
}
catch {}
}
else
{
runningIDEInstances[ candidateName ] = ide;
}
}
return runningIDEInstances;
}
public static EnvDTE.DTE GetIDEInstance( string solutionFile )
{
Hashtable runningInstances = GetIDEInstances( true );
IDictionaryEnumerator enumerator = runningInstances.GetEnumerator();
while ( enumerator.MoveNext() )
{
try
{
_DTE ide = (_DTE) enumerator.Value;
if (ide != null)
{
if (ide.Solution.FullName == solutionFile)
{
return (EnvDTE.DTE) ide;
}
}
}
catch{}
}
return null;
}
}
}
'@
Add-Type -AssemblyName "EnvDTE"
Register-CSharpCode $code
$vsInstances = [PInvoke.VisualStudioInstances]::GetIDEInstances($true)
$vsInstances.Keys | Foreach-Object `
{
$vs = $vsInstances.Item($_)
if($vs)
{
Write-Host "$($vs.Solution.FullName)"
}
}
$vsInstance = [PInvoke.VisualStudioInstances]::GetIDEInstance($solutionFullName)
if($vsInstance)
{
$dte = $vsInstance.DTE
$solution = $dte.Solution
$solution.Projects | Foreach-Object `
{
Write-Host "Project - $($_.Name)"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment