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?
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")