diff --git a/src/System.Private.Windows.Core/src/Windows/Win32/System/Com/ComHelpers.cs b/src/System.Private.Windows.Core/src/Windows/Win32/System/Com/ComHelpers.cs index 556ab0ed442..33104a5b59d 100644 --- a/src/System.Private.Windows.Core/src/Windows/Win32/System/Com/ComHelpers.cs +++ b/src/System.Private.Windows.Core/src/Windows/Win32/System/Com/ComHelpers.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Runtime.InteropServices; +using System.Runtime.InteropServices.Marshalling; using Windows.Win32.System.Com; namespace Windows.Win32; @@ -98,15 +99,29 @@ internal static bool SupportsInterface(object? @object) where T : unmanaged, } else { - // Fall back to COM interop if possible. Note that this will use the globally registered ComWrappers - // if that exists (so it won't always fall into legacy COM interop). - try + if (BuiltInComSupported) { - ccw = (IUnknown*)Marshal.GetIUnknownForObject(@object); + // Fall back to COM interop if possible. Note that this will use the globally registered ComWrappers + // if that exists (so it won't always fall into legacy COM interop). + try + { + ccw = (IUnknown*)Marshal.GetIUnknownForObject(@object); + } + catch (Exception ex) + { + Debug.WriteLine($"Did not find IUnknown for {@object.GetType().Name}. {ex.Message}"); + } } - catch (Exception ex) + else { - Debug.WriteLine($"Did not find IUnknown for {@object.GetType().Name}. {ex.Message}"); + try + { + ccw = (IUnknown*)ComInterfaceMarshaller.ConvertToUnmanaged(@object); + } + catch (Exception ex) + { + Debug.WriteLine($"Did not find IUnknown for {@object.GetType().Name}. {ex.Message}"); + } } } diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/ActiveX/AxHost.ConnectionPointCookie.cs b/src/System.Windows.Forms/src/System/Windows/Forms/ActiveX/AxHost.ConnectionPointCookie.cs index 93adc705cce..2d0a549a803 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/ActiveX/AxHost.ConnectionPointCookie.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/ActiveX/AxHost.ConnectionPointCookie.cs @@ -22,7 +22,7 @@ public ConnectionPointCookie(object source, object sink, Type eventInterface) internal ConnectionPointCookie(object? source, object sink, Type eventInterface, bool throwException) { - if (source is not IConnectionPointContainer.Interface cpc) + if (!ComHelpers.SupportsInterface(source)) { if (throwException) { @@ -45,8 +45,10 @@ internal ConnectionPointCookie(object? source, object sink, Type eventInterface, IConnectionPoint* connectionPoint = null; try { + using var cpc = ComHelpers.GetComScope(source); + Guid riid = eventInterface.GUID; - HRESULT hr = cpc.FindConnectionPoint(&riid, &connectionPoint); + HRESULT hr = cpc.Value->FindConnectionPoint(&riid, &connectionPoint); } catch (Exception ex) { diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/ActiveX/AxHost.OleInterfaces.cs b/src/System.Windows.Forms/src/System/Windows/Forms/ActiveX/AxHost.OleInterfaces.cs index c8877145f1d..933437bc1d5 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/ActiveX/AxHost.OleInterfaces.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/ActiveX/AxHost.OleInterfaces.cs @@ -5,6 +5,7 @@ using System.ComponentModel.Design; using System.Drawing; using System.Runtime.InteropServices; +using System.Runtime.InteropServices.Marshalling; using Windows.Win32.System.Com; using Windows.Win32.System.Ole; using Windows.Win32.System.Variant; @@ -129,7 +130,15 @@ protected override unsafe HRESULT Invoke( object? ambient = _host.GetAmbientProperty(dispId); if (ambient is not null) { - Marshal.GetNativeVariantForObject(ambient, (nint)result); + if (ComHelpers.BuiltInComSupported) + { + Marshal.GetNativeVariantForObject(ambient, (nint)result); + } + else + { + *(ComVariant*)result = ComVariantMarshaller.ConvertToUnmanaged(ambient); + } + return HRESULT.S_OK; } diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/ActiveX/AxHost.cs b/src/System.Windows.Forms/src/System/Windows/Forms/ActiveX/AxHost.cs index 79ac2fb96e2..078cf9d463a 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/ActiveX/AxHost.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/ActiveX/AxHost.cs @@ -9,6 +9,7 @@ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Runtime.InteropServices.Marshalling; using Microsoft.VisualStudio.Shell; using Windows.Win32.System.Com; using Windows.Win32.System.Com.StructuredStorage; @@ -3464,7 +3465,15 @@ private void ReleaseAxControl() { if (_instance is not null) { - Marshal.ReleaseComObject(_instance); + if (_instance is ComObject) + { + // TODO: how to release a ComWrappers ComObject? + } + else + { + Marshal.ReleaseComObject(_instance); + } + _instance = null; DisposeHelper.NullAndDispose(ref _iOleInPlaceActiveObjectExternal); }