问题
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:
You pinged me on a different answer, somewhat related to this. All I can suggest is to look how I did it about ten years ago here:
https://github.com/Pscx/Pscx/blob/master/Src/Pscx.Core/Interop/RunningObjectTable/RunningObjectTableHelper.cs
This code was originally on CodePlex.
So, if you run "install-module psx" you'll have a Get-RunningObjectTable for free already written.
来源:https://stackoverflow.com/questions/61106505/getting-dte-for-running-visual-studio-instances-from-powershell