2

Context

I do understand, that PowerShell Core is based on .NET Core and not .NET Framework, so it is platform independent, so it have no Windows specific APIs like interop services, COM etc. built in

My following statement is working in PowerShell 5.x:

 $dte = [runtime.interopservices.marshal]::GetActiveObject("visualstudio.dte")

Question

So I am looking a workaround, can I still use some way to communicate with Windows, maybe via calling/remoting? a PowerShell 5.x script from my PowerShell Core 7.x script?

g.pickardou
  • 32,346
  • 36
  • 123
  • 268
  • Does this answer your question? [Is there a substitue for System.Runtime.InteropServices.Marshal.GetActiveObject() in .NET Core?](https://stackoverflow.com/questions/64823199/is-there-a-substitue-for-system-runtime-interopservices-marshal-getactiveobject) – Simon Mourier Dec 13 '21 at 08:25
  • Many thx, it is a great help. However I would not close this question, because porting that code to PowerShell is not trivial, especially in case if the reader have no C#/.NET knowledge. So this OP has use in it own right, if someone (or me) will post the PowerShell solution. – g.pickardou Dec 13 '21 at 08:57
  • The comment below my answer explains it all. – Simon Mourier Dec 13 '21 at 08:59
  • @SimonMourier: Yes I understand. I am not insisting to keep this question open, still I think a question tagged with .NET and COM is not searchable for PowerShell questions, It is not an accident that neither I, neither SO search engine, neither google did not find it. – g.pickardou Dec 13 '21 at 09:05

1 Answers1

2

based on Simon's comment and his answer here and Brett's comment there here is a working PowerShell solution.

To be short, the line:

$dte = [runtime.interopservices.marshal]::GetActiveObject("visualstudio.dte")

is changing to this:

$dte = $interop::GetActiveObject("visualstudio.dte")

Full code:

$methodDefinition = @'
[DllImport("ole32")]
private static extern int CLSIDFromProgIDEx([MarshalAs(UnmanagedType.LPWStr)] string lpszProgID, out Guid lpclsid);

[DllImport("oleaut32")]
private static extern int GetActiveObject([MarshalAs(UnmanagedType.LPStruct)] Guid rclsid, IntPtr pvReserved, [MarshalAs(UnmanagedType.IUnknown)] out object ppunk);
public static object GetActiveObject(string progId, bool throwOnError = false)
{
    if (progId == null)
        throw new ArgumentNullException(nameof(progId));

    var hr = CLSIDFromProgIDEx(progId, out var clsid);
    if (hr < 0)
    {
        if (throwOnError)
            Marshal.ThrowExceptionForHR(hr);

        return null;
    }

    hr = GetActiveObject(clsid, IntPtr.Zero, out var obj);
    if (hr < 0)
    {
        if (throwOnError)
            Marshal.ThrowExceptionForHR(hr);

        return null;
    }
    return obj;
}
'@
$interop = add-type -MemberDefinition $methodDefinition -Name "Interop" -Namespace "Interop" -PassThru

// All of above is for this:
$dte = $interop::GetActiveObject("visualstudio.dte")
Johan Lundberg
  • 26,184
  • 12
  • 71
  • 97
g.pickardou
  • 32,346
  • 36
  • 123
  • 268