| File: System\Runtime\InteropServices\ComAwareEventInfo.cs | Web Access |
| Project: src\runtime\src\libraries\System.Runtime.InteropServices\src\System.Runtime.InteropServices.csproj (System.Runtime.InteropServices) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Runtime.Versioning; // This type is obsolete, and is expected to be used in very specific ways or it may // throw null reference exceptions. #pragma warning disable CS8610 namespace System.Runtime.InteropServices { [EditorBrowsable(EditorBrowsableState.Never)] [RequiresUnreferencedCode("Built-in COM support is not trim compatible", Url = "https://aka.ms/dotnet-illink/com")] public class ComAwareEventInfo : EventInfo { private readonly EventInfo _innerEventInfo; public ComAwareEventInfo([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents)] Type type, string eventName) { _innerEventInfo = type.GetEvent(eventName)!; } [SupportedOSPlatform("windows")] #pragma warning disable CS8765 // Nullability of parameters 'target' and 'handler' don't match overridden member public override void AddEventHandler(object target, Delegate handler) #pragma warning restore CS8765 { if (Marshal.IsComObject(target)) { // retrieve sourceIid and dispid GetDataForComInvocation(_innerEventInfo, out Guid sourceIid, out int dispid); ComEventsHelper.Combine(target, sourceIid, dispid, handler); } else { // we are dealing with a managed object - just add the delegate through reflection _innerEventInfo.AddEventHandler(target, handler); } } [SupportedOSPlatform("windows")] #pragma warning disable CS8765 // Nullability of parameters 'target' and 'handler' don't match overridden member public override void RemoveEventHandler(object target, Delegate handler) #pragma warning restore CS8765 { if (Marshal.IsComObject(target)) { // retrieve sourceIid and dispid GetDataForComInvocation(_innerEventInfo, out Guid sourceIid, out int dispid); ComEventsHelper.Remove(target, sourceIid, dispid, handler); } else { // we are dealing with a managed object - just add the delegate through reflection _innerEventInfo.RemoveEventHandler(target, handler); } } public override EventAttributes Attributes => _innerEventInfo.Attributes; public override MethodInfo? GetAddMethod(bool nonPublic) => _innerEventInfo.GetAddMethod(nonPublic); public override MethodInfo[] GetOtherMethods(bool nonPublic) => _innerEventInfo.GetOtherMethods(nonPublic); public override MethodInfo? GetRaiseMethod(bool nonPublic) => _innerEventInfo.GetRaiseMethod(nonPublic); public override MethodInfo? GetRemoveMethod(bool nonPublic) => _innerEventInfo.GetRemoveMethod(nonPublic); public override Type? DeclaringType => _innerEventInfo.DeclaringType; public override object[] GetCustomAttributes(Type attributeType, bool inherit) { return _innerEventInfo.GetCustomAttributes(attributeType, inherit); } public override object[] GetCustomAttributes(bool inherit) { return _innerEventInfo.GetCustomAttributes(inherit); } public override IList<CustomAttributeData> GetCustomAttributesData() => _innerEventInfo.GetCustomAttributesData(); public override bool IsDefined(Type attributeType, bool inherit) { return _innerEventInfo.IsDefined(attributeType, inherit); } public override int MetadataToken => _innerEventInfo.MetadataToken; public override Module Module => _innerEventInfo.Module; public override string Name => _innerEventInfo.Name; public override Type? ReflectedType => _innerEventInfo.ReflectedType; private static void GetDataForComInvocation(EventInfo eventInfo, out Guid sourceIid, out int dispid) { object[] comEventInterfaces = eventInfo.DeclaringType!.GetCustomAttributes(typeof(ComEventInterfaceAttribute), inherit: false); if (comEventInterfaces == null || comEventInterfaces.Length == 0) { throw new InvalidOperationException(SR.InvalidOperation_NoComEventInterfaceAttribute); } ComEventInterfaceAttribute interfaceAttribute = (ComEventInterfaceAttribute)comEventInterfaces[0]; if (comEventInterfaces.Length > 1) { throw new AmbiguousMatchException(SR.Format(SR.AmbiguousMatch_MultipleEventInterfaceAttributes, interfaceAttribute)); } Type sourceInterface = interfaceAttribute.SourceInterface; Guid guid = sourceInterface.GUID; MethodInfo methodInfo = sourceInterface.GetMethod(eventInfo.Name)!; Attribute? dispIdAttribute = Attribute.GetCustomAttribute(methodInfo, typeof(DispIdAttribute)); if (dispIdAttribute == null) { throw new InvalidOperationException(SR.InvalidOperation_NoDispIdAttribute); } sourceIid = guid; dispid = ((DispIdAttribute)dispIdAttribute).Value; } } }