IDS_EE_INVALIDCOMDEFITF "Type '%1' has an invalid default COM interface: '%2'."
IDS_EE_COMDEFITFNOTSUPPORTED "Type '%1' does not support the specified default COM interface: '%2'"
+ IDS_EE_CLASS_TO_VARIANT_TLB_NOT_REG "Type '%1' cannot be marshalled to a Variant. Type library is not registered."
IDS_EE_CANNOT_MAP_TO_MANAGED_VC "The specified record cannot be mapped to a managed value class."
IDS_EE_SAFEHANDLECLOSED "Safe handle has been closed"
#define IDS_EE_INVALIDCOMDEFITF 0x1a32
#define IDS_EE_COMDEFITFNOTSUPPORTED 0x1a33
+#define IDS_EE_CLASS_TO_VARIANT_TLB_NOT_REG 0x1a35
#define IDS_EE_CANNOT_MAP_TO_MANAGED_VC 0x1a36
#define IDS_EE_MARSHAL_UNMAPPABLE_CHAR 0x1a37
// Retrieve the ITypeInfo for the value class.
MethodTable *pValueClassMT = (*pBoxedValueClass)->GetMethodTable();
- IfFailThrow(GetITypeInfoForEEClass(pValueClassMT, &pTypeInfo, true /* bClassInfo */));
+ hr = GetITypeInfoForEEClass(pValueClassMT, &pTypeInfo, true /* bClassInfo */);
+ if (FAILED(hr))
+ {
+ if (hr == TLBX_E_LIBNOTREGISTERED)
+ {
+ // Indicate that conversion of the class to variant without a registered type lib is not supported
+ StackSString className;
+ pValueClassMT->_GetFullyQualifiedNameForClass(className);
+ COMPlusThrow(kNotSupportedException, IDS_EE_CLASS_TO_VARIANT_TLB_NOT_REG, className.GetUnicode());
+ }
+ else
+ {
+ COMPlusThrowHR(hr);
+ }
+ }
// Convert the ITypeInfo to an IRecordInfo.
hr = GetRecordInfoFromTypeInfo(pTypeInfo, &V_RECORDINFO(pRecHolder));
}
CONTRACTL_END;
- // If the module wasn't imported from COM, fail. In .NET Framework the runtime
- // would generate a ITypeLib instance, but .NET Core doesn't support that.
- if (!pAssembly->IsImportedFromTypeLib())
- return COR_E_NOTSUPPORTED;
-
HRESULT hr;
// Check for cached copy.
}
/// <summary>
- /// Look for typeinfo using IDispatch.GetTypeInfo
+ /// Look for type info using IDispatch.GetTypeInfo
/// </summary>
/// <param name="dispatch">IDispatch object</param>
/// <remarks>
- /// Some COM objects just dont expose typeinfo. In these cases, this method will return null.
- /// Some COM objects do intend to expose typeinfo, but may not be able to do so if the type-library is not properly
- /// registered. This will be considered as acceptable or as an error condition depending on throwIfMissingExpectedTypeInfo
+ /// Some COM objects just don't expose type info. In these cases, this method will return null.
+ /// Some COM objects do intend to expose type info, but may not be able to do so if the type library
+ /// is not properly registered. This will be considered an error.
/// </remarks>
/// <returns>Type info</returns>
internal static ComTypes.ITypeInfo GetITypeInfoFromIDispatch(IDispatch dispatch)
{
int hresult = dispatch.TryGetTypeInfoCount(out uint typeCount);
- Marshal.ThrowExceptionForHR(hresult);
- Debug.Assert(typeCount <= 1);
if (typeCount == 0)
{
+ // COM objects should return a type count of 0 to indicate that type info is not exposed.
+ // Some COM objects may return a non-success HRESULT when type info is not supported, so
+ // we only check the count and not the HRESULT in this case.
return null;
}
+ Marshal.ThrowExceptionForHR(hresult);
+ Debug.Assert(typeCount == 1);
+
IntPtr typeInfoPtr;
hresult = dispatch.TryGetTypeInfo(0, 0, out typeInfoPtr);
if (!ComHresults.IsSuccess(hresult))
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity
- type="win32"
+ type="win32"
name="COMDynamicTest"
version="1.0.0.0" />
<dependency>
<dependentAssembly>
- <!-- RegFree COM -->
+ <!-- RegFree COM to activate managed server -->
+ <assemblyIdentity
+ type="win32"
+ name="CoreShim.X"
+ version="1.0.0.0"/>
+ </dependentAssembly>
+ </dependency>
+ <dependency>
+ <dependentAssembly>
+ <!-- RegFree COM to activate native server-->
<assemblyIdentity
type="win32"
name="DynamicTestServer.X"
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+
+<assemblyIdentity
+ type="win32"
+ name="CoreShim.X"
+ version="1.0.0.0" />
+
+<file name="CoreShim.dll">
+ <!-- ConsumeNETServerTesting -->
+ <comClass
+ clsid="{DE4ACF53-5957-4D31-8BE2-EA6C80683246}"
+ threadingModel="Both" />
+</file>
+
+</assembly>
<OutputType>Exe</OutputType>
<ApplicationManifest>App.manifest</ApplicationManifest>
<IsManagedCOMClient>true</IsManagedCOMClient>
+ <UseManagedCOMServer>true</UseManagedCOMServer>
<!-- This test is very slow under some GCStress variations, especially with COMPlus_HeapVerify=1, so disable it under GCStress to avoid test timeouts in the CI.
Issue: https://github.com/dotnet/runtime/issues/39584
-->
<Compile Include="CollectionTest.cs" />
<Compile Include="EventTest.cs" />
<Compile Include="ParametersTest.cs" />
+ <Compile Include="NETServerTest.cs" />
<Compile Include="Program.cs" />
<Compile Include="ServerGuids.cs" />
+ <Compile Include="../ServerContracts/ServerGuids.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="CoreShim.X.manifest">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="Server/CMakeLists.txt" />
<ProjectReference Include="$(TestSourceDir)Common/CoreCLRTestLibrary/CoreCLRTestLibrary.csproj" />
+ <ProjectReference Include="../NETServer/NETServer.csproj">
+ <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+ <OutputItemType>Content</OutputItemType>
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </ProjectReference>
</ItemGroup>
</Project>
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace Dynamic
+{
+ using System;
+ using System.Runtime.InteropServices;
+ using TestLibrary;
+
+ internal class NETServerTest
+ {
+ public void Run()
+ {
+ Console.WriteLine($"Running {nameof(NETServerTest)}");
+
+ // Initialize CoreShim and hostpolicymock
+ HostPolicyMock.Initialize(Environment.CurrentDirectory, null);
+ Environment.SetEnvironmentVariable("CORESHIM_COMACT_ASSEMBLYNAME", "NETServer");
+ Environment.SetEnvironmentVariable("CORESHIM_COMACT_TYPENAME", "ConsumeNETServerTesting");
+
+ using (HostPolicyMock.Mock_corehost_resolve_component_dependencies(
+ 0,
+ string.Empty,
+ string.Empty,
+ string.Empty))
+ {
+ Type t = Type.GetTypeFromCLSID(Guid.Parse(Server.Contract.Guids.ConsumeNETServerTesting));
+ dynamic obj = Activator.CreateInstance(t);
+
+ try
+ {
+ Assert.IsTrue(obj.EqualByCCW(obj));
+ Assert.IsTrue(obj.NotEqualByRCW(obj));
+ }
+ finally
+ {
+ obj.ReleaseResources();
+ }
+ }
+ }
+ }
+}
new CollectionTest().Run();
new EventTest().Run();
new ParametersTest().Run();
+ new NETServerTest().Run();
}
catch (Exception e)
{