如何在 PowerShell Core 中 [runtime.interopservices.marshal]::GetActiveObject("...")?
How to [runtime.interopservices.marshal]::GetActiveObject("...") in PowerShell Core?
上下文
我明白,PowerShell Core 基于 .NET Core 而不是 .NET Framework,因此它是独立于平台的,所以它没有 Windows 特定的 API,例如互操作服务、COM 等。内置
我的以下语句在 PowerShell 中有效 5.x:
$dte = [runtime.interopservices.marshal]::GetActiveObject("visualstudio.dte")
问题
所以我正在寻找解决方法,我是否仍可以使用某种方式与 Windows 通信,也许是通过 calling/remoting?来自我的 PowerShell Core 7.x 脚本的 PowerShell 5.x 脚本?
根据 Simon 的评论和 以及 Brett 的评论,这里有一个有效的 PowerShell 解决方案。
简而言之,行:
$dte = [runtime.interopservices.marshal]::GetActiveObject("visualstudio.dte")
正在更改为:
$dte = $interop::GetActiveObject("visualstudio.dte")
完整代码:
$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")
上下文
我明白,PowerShell Core 基于 .NET Core 而不是 .NET Framework,因此它是独立于平台的,所以它没有 Windows 特定的 API,例如互操作服务、COM 等。内置
我的以下语句在 PowerShell 中有效 5.x:
$dte = [runtime.interopservices.marshal]::GetActiveObject("visualstudio.dte")
问题
所以我正在寻找解决方法,我是否仍可以使用某种方式与 Windows 通信,也许是通过 calling/remoting?来自我的 PowerShell Core 7.x 脚本的 PowerShell 5.x 脚本?
根据 Simon 的评论和
简而言之,行:
$dte = [runtime.interopservices.marshal]::GetActiveObject("visualstudio.dte")
正在更改为:
$dte = $interop::GetActiveObject("visualstudio.dte")
完整代码:
$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")