Browse Source

Enable COM autimation only when dynamic code is disabled

pull/9480/head
Max Katz 4 years ago
parent
commit
d44b14126d
  1. 2
      src/Windows/Avalonia.Win32/Automation/AutomationNode.cs
  2. 2
      src/Windows/Avalonia.Win32/Automation/RootAutomationNode.cs
  3. 4
      src/Windows/Avalonia.Win32/Avalonia.Win32.csproj
  4. 4
      src/Windows/Avalonia.Win32/DataObject.cs
  5. 19
      src/Windows/Avalonia.Win32/Interop/Automation/UiaCoreTypesApi.cs
  6. 4
      src/Windows/Avalonia.Win32/NonPumpingSyncContext.cs
  7. 4
      src/Windows/Avalonia.Win32/OleDataObject.cs
  8. 9
      src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs

2
src/Windows/Avalonia.Win32/Automation/AutomationNode.cs

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
@ -16,6 +17,7 @@ using AAP = Avalonia.Automation.Provider;
namespace Avalonia.Win32.Automation namespace Avalonia.Win32.Automation
{ {
[ComVisible(true)] [ComVisible(true)]
[RequiresUnreferencedCode("Requires .NET COM interop")]
internal partial class AutomationNode : MarshalByRefObject, internal partial class AutomationNode : MarshalByRefObject,
IRawElementProviderSimple, IRawElementProviderSimple,
IRawElementProviderSimple2, IRawElementProviderSimple2,

2
src/Windows/Avalonia.Win32/Automation/RootAutomationNode.cs

@ -1,4 +1,5 @@
using System; using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using Avalonia.Automation.Peers; using Avalonia.Automation.Peers;
using Avalonia.Automation.Provider; using Avalonia.Automation.Provider;
@ -9,6 +10,7 @@ using Avalonia.Win32.Interop.Automation;
namespace Avalonia.Win32.Automation namespace Avalonia.Win32.Automation
{ {
[RequiresUnreferencedCode("Requires .NET COM interop")]
internal class RootAutomationNode : AutomationNode, internal class RootAutomationNode : AutomationNode,
IRawElementProviderFragmentRoot IRawElementProviderFragmentRoot
{ {

4
src/Windows/Avalonia.Win32/Avalonia.Win32.csproj

@ -21,8 +21,8 @@
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildThisFileDirectory)\..\..\..\build\System.Drawing.Common.props" /> <Import Project="$(MSBuildThisFileDirectory)\..\..\..\build\System.Drawing.Common.props" />
<Import Project="..\..\..\build\DevAnalyzers.props" /> <Import Project="..\..\..\build\DevAnalyzers.props" />
<Import Project="..\..\..\build\TrimmingEnable.props" />
<PropertyGroup Label="Warnings"> <PropertyGroup Label="Warnings">
<NoWarn Condition="'$(NoWarn)' == ''">CA1416</NoWarn> <NoWarn>$(NoWarn);CA1416</NoWarn>
<NoWarn Condition="'$(NoWarn)' != ''">$(NoWarn),CA1416</NoWarn>
</PropertyGroup> </PropertyGroup>
</Project> </Project>

4
src/Windows/Avalonia.Win32/DataObject.cs

@ -2,6 +2,7 @@
using System.Buffers; using System.Buffers;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
@ -291,13 +292,16 @@ namespace Avalonia.Win32
return WriteBytesToHGlobal(ref hGlobal, SerializeObject(data)); return WriteBytesToHGlobal(ref hGlobal, SerializeObject(data));
} }
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "We still use BinaryFormatter for WinForms dragndrop compatability")]
private static byte[] SerializeObject(object data) private static byte[] SerializeObject(object data)
{ {
using (var ms = new MemoryStream()) using (var ms = new MemoryStream())
{ {
ms.Write(SerializedObjectGUID, 0, SerializedObjectGUID.Length); ms.Write(SerializedObjectGUID, 0, SerializedObjectGUID.Length);
BinaryFormatter binaryFormatter = new BinaryFormatter(); BinaryFormatter binaryFormatter = new BinaryFormatter();
#pragma warning disable SYSLIB0011 // Type or member is obsolete
binaryFormatter.Serialize(ms, data); binaryFormatter.Serialize(ms, data);
#pragma warning restore SYSLIB0011 // Type or member is obsolete
return ms.ToArray(); return ms.ToArray();
} }
} }

19
src/Windows/Avalonia.Win32/Interop/Automation/UiaCoreTypesApi.cs

@ -1,4 +1,5 @@
using System; using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace Avalonia.Win32.Interop.Automation namespace Avalonia.Win32.Interop.Automation
@ -21,11 +22,15 @@ namespace Avalonia.Win32.Interop.Automation
internal const int UIA_E_NOCLICKABLEPOINT = unchecked((int)0x80040202); internal const int UIA_E_NOCLICKABLEPOINT = unchecked((int)0x80040202);
internal const int UIA_E_PROXYASSEMBLYNOTLOADED = unchecked((int)0x80040203); internal const int UIA_E_PROXYASSEMBLYNOTLOADED = unchecked((int)0x80040203);
private static bool? s_isNetComInteropAvailable;
internal static bool IsNetComInteropAvailable => s_isNetComInteropAvailable ??= GetIsNetComInteropAvailable();
internal static int UiaLookupId(AutomationIdType type, ref Guid guid) internal static int UiaLookupId(AutomationIdType type, ref Guid guid)
{ {
return RawUiaLookupId( type, ref guid ); return RawUiaLookupId( type, ref guid );
} }
[RequiresUnreferencedCode("Requires .NET COM interop")]
internal static object UiaGetReservedNotSupportedValue() internal static object UiaGetReservedNotSupportedValue()
{ {
object notSupportedValue; object notSupportedValue;
@ -33,6 +38,7 @@ namespace Avalonia.Win32.Interop.Automation
return notSupportedValue; return notSupportedValue;
} }
[RequiresUnreferencedCode("Requires .NET COM interop")]
internal static object UiaGetReservedMixedAttributeValue() internal static object UiaGetReservedMixedAttributeValue()
{ {
object mixedAttributeValue; object mixedAttributeValue;
@ -49,6 +55,19 @@ namespace Avalonia.Win32.Interop.Automation
Marshal.ThrowExceptionForHR(hr, (IntPtr)(-1)); Marshal.ThrowExceptionForHR(hr, (IntPtr)(-1));
} }
private static bool GetIsNetComInteropAvailable()
{
#if NET6_0_OR_GREATER
if (!System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported)
{
return false;
}
#endif
var comConfig = AppContext.GetData("System.Runtime.InteropServices.BuiltInComInterop.IsSupported");
return comConfig == null || bool.Parse(comConfig.ToString());
}
[DllImport("UIAutomationCore.dll", EntryPoint = "UiaLookupId", CharSet = CharSet.Unicode)] [DllImport("UIAutomationCore.dll", EntryPoint = "UiaLookupId", CharSet = CharSet.Unicode)]
private static extern int RawUiaLookupId(AutomationIdType type, ref Guid guid); private static extern int RawUiaLookupId(AutomationIdType type, ref Guid guid);

4
src/Windows/Avalonia.Win32/NonPumpingSyncContext.cs

@ -20,8 +20,10 @@ namespace Avalonia.Win32
public override void Post(SendOrPostCallback d, object state) => _inner.Post(d, state); public override void Post(SendOrPostCallback d, object state) => _inner.Post(d, state);
public override void Send(SendOrPostCallback d, object state) => _inner.Send(d, state); public override void Send(SendOrPostCallback d, object state) => _inner.Send(d, state);
#if !NET6_0_OR_GREATER
[PrePrepareMethod] [PrePrepareMethod]
#endif
public override int Wait(IntPtr[] waitHandles, bool waitAll, int millisecondsTimeout) public override int Wait(IntPtr[] waitHandles, bool waitAll, int millisecondsTimeout)
{ {
return UnmanagedMethods.WaitForMultipleObjectsEx(waitHandles.Length, waitHandles, waitAll, return UnmanagedMethods.WaitForMultipleObjectsEx(waitHandles.Length, waitHandles, waitAll,

4
src/Windows/Avalonia.Win32/OleDataObject.cs

@ -1,6 +1,7 @@
using System; using System;
using System.Buffers; using System.Buffers;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
@ -49,6 +50,7 @@ namespace Avalonia.Win32
return GetDataFromOleHGLOBAL(dataFormat, DVASPECT.DVASPECT_CONTENT); return GetDataFromOleHGLOBAL(dataFormat, DVASPECT.DVASPECT_CONTENT);
} }
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "We still use BinaryFormatter for WinForms dragndrop compatability")]
private unsafe object GetDataFromOleHGLOBAL(string format, DVASPECT aspect) private unsafe object GetDataFromOleHGLOBAL(string format, DVASPECT aspect)
{ {
var formatEtc = new Interop.FORMATETC(); var formatEtc = new Interop.FORMATETC();
@ -77,7 +79,9 @@ namespace Avalonia.Win32
{ {
ms.Position = DataObject.SerializedObjectGUID.Length; ms.Position = DataObject.SerializedObjectGUID.Length;
BinaryFormatter binaryFormatter = new BinaryFormatter(); BinaryFormatter binaryFormatter = new BinaryFormatter();
#pragma warning disable SYSLIB0011 // Type or member is obsolete
return binaryFormatter.Deserialize(ms); return binaryFormatter.Deserialize(ms);
#pragma warning restore SYSLIB0011 // Type or member is obsolete
} }
} }
return data; return data;

9
src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs

@ -21,6 +21,8 @@ namespace Avalonia.Win32
{ {
[SuppressMessage("Microsoft.StyleCop.CSharp.NamingRules", "SA1305:FieldNamesMustNotUseHungarianNotation", [SuppressMessage("Microsoft.StyleCop.CSharp.NamingRules", "SA1305:FieldNamesMustNotUseHungarianNotation",
Justification = "Using Win32 naming for consistency.")] Justification = "Using Win32 naming for consistency.")]
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "We do .NET COM interop availability checks")]
[UnconditionalSuppressMessage("Trimming", "IL2050", Justification = "We do .NET COM interop availability checks")]
protected virtual unsafe IntPtr AppWndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam) protected virtual unsafe IntPtr AppWndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
{ {
const double wheelDelta = 120.0; const double wheelDelta = 120.0;
@ -83,7 +85,10 @@ namespace Avalonia.Win32
case WindowsMessage.WM_DESTROY: case WindowsMessage.WM_DESTROY:
{ {
UiaCoreProviderApi.UiaReturnRawElementProvider(_hwnd, IntPtr.Zero, IntPtr.Zero, null); if (UiaCoreTypesApi.IsNetComInteropAvailable)
{
UiaCoreProviderApi.UiaReturnRawElementProvider(_hwnd, IntPtr.Zero, IntPtr.Zero, null);
}
// We need to release IMM context and state to avoid leaks. // We need to release IMM context and state to avoid leaks.
if (Imm32InputMethod.Current.HWND == _hwnd) if (Imm32InputMethod.Current.HWND == _hwnd)
@ -707,7 +712,7 @@ namespace Avalonia.Win32
break; break;
case WindowsMessage.WM_GETOBJECT: case WindowsMessage.WM_GETOBJECT:
if ((long)lParam == UiaRootObjectId) if ((long)lParam == UiaRootObjectId && UiaCoreTypesApi.IsNetComInteropAvailable)
{ {
var peer = ControlAutomationPeer.CreatePeerForElement((Control)_owner); var peer = ControlAutomationPeer.CreatePeerForElement((Control)_owner);
var node = AutomationNode.GetOrCreate(peer); var node = AutomationNode.GetOrCreate(peer);

Loading…
Cancel
Save