Getting DTE for running Visual Studio instances from PowerShell

Viewed 232

Getting DTE for a single running Visual Studio with PowerShell is easy: Get a handle on the running Visual Studio instance (DTE) from powershell

Getting DTE for multiple instances with C# has been solved How do I get the DTE for running Visual Studio instance?

Now how do I get DTE for multiple VS instances with PowerShell? I'm trying to enable scripts to adjust VS configuration and start a build after a git pull, VM+XDE setup etc, all without having to open a new VS window if there's one already open.

Here's what I got:

$memberDefinitionGetRunningObjectTable = @'
[DllImport(@"ole32.dll",EntryPoint="GetRunningObjectTable",ExactSpelling=false)] 
public static extern int GetRunningObjectTable(
    int reserved,
    out IRunningObjectTable prot);
'@
$typeGetRunningObjectTable = Add-Type -MemberDefinition $memberDefinitionGetRunningObjectTable -Name "InteropGetRunningObjectTable" -PassThru -Using 'System.Runtime.InteropServices.ComTypes'

[System.Runtime.InteropServices.ComTypes.IRunningObjectTable]$runningObjects = $null
$ret = $typeGetRunningObjectTable::GetRunningObjectTable(0, [ref][System.Runtime.InteropServices.ComTypes.IRunningObjectTable] $runningObjects)
if ($ret -eq 0)
{
    if ($null -eq $runningObjects) { Write-Error "Failed to retrieve running COM objects"}
}

-- this does fail so it seems like forcing IRunningObjectTable type on the out parameter doesn't work and $runningObjects is $null

I tried this earlier:

$memberDefinitionGetRunningObjectTable = @'
[DllImport(@"ole32.dll",EntryPoint="GetRunningObjectTable",ExactSpelling=false)] 
public static extern int GetRunningObjectTable(
    int reserved,
    out IRunningObjectTable prot);
'@
$typeGetRunningObjectTable = Add-Type -MemberDefinition $memberDefinitionGetRunningObjectTable -Name "InteropGetRunningObjectTable" -PassThru -Using 'System.Runtime.InteropServices.ComTypes'

$memberDefinitionCreateBindCtx = @'
[DllImport("ole32.dll")]
public static extern int CreateBindCtx(
    int reserved,
    out IBindCtx ppbc); 
'@
$typeCreateBindCtx = Add-Type -MemberDefinition $memberDefinitionCreateBindCtx -Name "InteropCreateBindCtx" -PassThru -Using 'System.Runtime.InteropServices.ComTypes'

$runningObjects = $null
$ret = $typeGetRunningObjectTable::GetRunningObjectTable(0, [ref] $runningObjects)
if ($ret -eq 0)
{
    if ($null -eq $runningObjects) { throw "Failed to retrieve running COM objects"}

    $enumMoniker = $null
    $runningObjects.EnumRunning([ref] $enumMoniker)

    $typeCreateBindCtx::CreateBindCtx([ref] $enumMoniker)
}

That results in this error though:

Method invocation failed because [System.__ComObject] does not contain a method named 'EnumRunning'.
At line:6 char:5
+     $runningObjects.EnumRunning([ref] $enumMoniker)

I'm just a little bit stumped here. Is that __ComObject actually $null here as well?

1 Answers
Related