diff --git a/src/libraries/System.ComponentModel.TypeConverter/ref/System.ComponentModel.TypeConverter.cs b/src/libraries/System.ComponentModel.TypeConverter/ref/System.ComponentModel.TypeConverter.cs
index 5b3f3fdef12ff4..d0a52930a2c88c 100644
--- a/src/libraries/System.ComponentModel.TypeConverter/ref/System.ComponentModel.TypeConverter.cs
+++ b/src/libraries/System.ComponentModel.TypeConverter/ref/System.ComponentModel.TypeConverter.cs
@@ -1411,9 +1411,17 @@ public sealed partial class TypeDescriptor
         internal TypeDescriptor() { }
         [System.Diagnostics.CodeAnalysis.DisallowNullAttribute]
         [System.ObsoleteAttribute("TypeDescriptor.ComNativeDescriptorHandler has been deprecated. Use a type description provider to supply type information for COM types instead.")]
-        public static System.ComponentModel.IComNativeDescriptorHandler? ComNativeDescriptorHandler { get { throw null; } set { } }
+        public static System.ComponentModel.IComNativeDescriptorHandler? ComNativeDescriptorHandler {
+            [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("COM type descriptors are not trim-compatible.")]
+            get { throw null; }
+            [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("COM type descriptors are not trim-compatible.")]
+            set { }
+        }
         [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
-        public static System.Type ComObjectType { [return: System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] get { throw null; } }
+        public static System.Type ComObjectType {
+            [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("COM type descriptors are not trim-compatible.")]
+            [return: System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] get { throw null; }
+        }
         [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
         public static System.Type InterfaceType { [return: System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] get { throw null; } }
         public static event System.ComponentModel.RefreshEventHandler? Refreshed { add { } remove { } }
diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/ILLink/ILLink.Suppressions.LibraryBuild.xml b/src/libraries/System.ComponentModel.TypeConverter/src/ILLink/ILLink.Suppressions.LibraryBuild.xml
index 00f9036918d63d..aac20beb79bab5 100644
--- a/src/libraries/System.ComponentModel.TypeConverter/src/ILLink/ILLink.Suppressions.LibraryBuild.xml
+++ b/src/libraries/System.ComponentModel.TypeConverter/src/ILLink/ILLink.Suppressions.LibraryBuild.xml
@@ -15,5 +15,12 @@
       M:System.ComponentModel.Design.DesigntimeLicenseContextSerializer.DeserializeUsingBinaryFormatter(System.ComponentModel.Design.DesigntimeLicenseContextSerializer.StreamWrapper,System.String,System.ComponentModel.Design.RuntimeLicenseContext)
       This warning is left in the product so developers get an ILLink warning when trimming an app with System.ComponentModel.TypeConverter.EnableUnsafeBinaryFormatterInDesigntimeLicenseContextSerialization=true.
     
+    
+        ILLink
+        IL2026
+        member
+        M:System.ComponentModel.TypeDescriptor.NodeFor(System.Object,System.Boolean)
+        This warning is left in the product so developers get an ILLink warning when trimming an app with System.ComponentModel.TypeDescriptor.IsComObjectDescriptorSupported=true.
+    
   
 
diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/Resources/Strings.resx b/src/libraries/System.ComponentModel.TypeConverter/src/Resources/Strings.resx
index 6930398b398144..d8cae9370aa81b 100644
--- a/src/libraries/System.ComponentModel.TypeConverter/src/Resources/Strings.resx
+++ b/src/libraries/System.ComponentModel.TypeConverter/src/Resources/Strings.resx
@@ -166,6 +166,9 @@
   
     An array of tab type names or tab types must be specified
   
+  
+    COM object type descriptor functionality has been disabled in the app configuration and is not supported.
+  
   
     (Default)
   
diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/TypeDescriptor.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/TypeDescriptor.cs
index 0e5bba3b7486e4..cfe4517188bb9a 100644
--- a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/TypeDescriptor.cs
+++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/TypeDescriptor.cs
@@ -22,6 +22,12 @@ public sealed class TypeDescriptor
         internal const DynamicallyAccessedMemberTypes ReflectTypesDynamicallyAccessedMembers = DynamicallyAccessedMemberTypes.PublicParameterlessConstructor | DynamicallyAccessedMemberTypes.PublicFields;
         internal const string DesignTimeAttributeTrimmed = "Design-time attributes are not preserved when trimming. Types referenced by attributes like EditorAttribute and DesignerAttribute may not be available after trimming.";
 
+        [FeatureSwitchDefinition("System.ComponentModel.TypeDescriptor.IsComObjectDescriptorSupported")]
+        [FeatureGuard(typeof(RequiresUnreferencedCodeAttribute))]
+#pragma warning disable IL4000 // MSBuild logic will ensure that the switch is disabled in trimmed scenarios.
+        internal static bool IsComObjectDescriptorSupported => AppContext.TryGetSwitch("System.ComponentModel.TypeDescriptor.IsComObjectDescriptorSupported", out bool isEnabled) ? isEnabled : true;
+#pragma warning restore IL4000
+
         // Note: this is initialized at class load because we
         // lock on it for thread safety. It is used from nearly
         // every call to this class, so it will be created soon after
@@ -1556,11 +1562,19 @@ private static TypeDescriptionNode NodeFor(object instance, bool createDelegator
 
                 if (type.IsCOMObject)
                 {
+                    if (!IsComObjectDescriptorSupported)
+                    {
+                        throw new NotSupportedException(SR.ComObjectDescriptorsNotSupported);
+                    }
                     type = ComObjectType;
                 }
                 else if (OperatingSystem.IsWindows()
                     && ComWrappers.TryGetComInstance(instance, out nint unknown))
                 {
+                    if (!IsComObjectDescriptorSupported)
+                    {
+                        throw new NotSupportedException(SR.ComObjectDescriptorsNotSupported);
+                    }
                     // ComObjectType uses the Windows Forms provided ComNativeDescriptor. It currently has hard Win32
                     // API dependencies. Even though ComWrappers work with other platforms, restricting to Windows until
                     // such time that the ComNativeDescriptor can handle basic COM types on other platforms.
@@ -2338,6 +2352,7 @@ public static void Refresh(Assembly assembly)
         [EditorBrowsable(EditorBrowsableState.Advanced)]
         public static Type ComObjectType
         {
+            [RequiresUnreferencedCode("COM type descriptors are not trim-compatible.")]
             [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
             get => typeof(TypeDescriptorComObject);
         }
@@ -2385,6 +2400,7 @@ public static Type ComObjectType
         [DisallowNull]
         public static IComNativeDescriptorHandler? ComNativeDescriptorHandler
         {
+            [RequiresUnreferencedCode("COM type descriptors are not trim-compatible.")]
             get
             {
                 TypeDescriptionNode? typeDescriptionNode = NodeFor(ComObjectType);
@@ -2397,6 +2413,7 @@ public static IComNativeDescriptorHandler? ComNativeDescriptorHandler
                 while (typeDescriptionNode != null && comNativeDescriptionProvider == null);
                 return comNativeDescriptionProvider?.Handler;
             }
+            [RequiresUnreferencedCode("COM type descriptors are not trim-compatible.")]
             set
             {
                 TypeDescriptionNode? typeDescriptionNode = NodeFor(ComObjectType);
@@ -2850,6 +2867,11 @@ private sealed class ComNativeDescriptorProxy : TypeDescriptionProvider
 
             public ComNativeDescriptorProxy()
             {
+                if (!IsComObjectDescriptorSupported)
+                {
+                    throw new NotSupportedException(SR.ComObjectDescriptorsNotSupported);
+                }
+
                 Type realComNativeDescriptor = Type.GetType("System.Windows.Forms.ComponentModel.Com2Interop.ComNativeDescriptor, System.Windows.Forms", throwOnError: true)!;
                 _comNativeDescriptor = (TypeDescriptionProvider)Activator.CreateInstance(realComNativeDescriptor)!;
             }