runtime: GetEnumerator() Fails on Some Interop w/netcoreapp2.0

Hey–

I’m working on porting a tool that interacts with the DIA SDK to the netcoreapp2.0 framework (https://github.com/Microsoft/binskim), and ran into an interesting exception/problem.

IDiaEnumTables’s System._ComObject representation exposes a GetEnumerator() function, which I assume probably winds up wrapping HRESULT get__NewEnum() (https://docs.microsoft.com/en-us/visualstudio/debugger/debug-interface-access/idiaenumtables-get-newenum) internally. However, calling that function in a netcoreapp2.0 version of our tool throws an exception about missing the CustomMarshallers library:

System.IO.FileNotFoundException occurred
  HResult=0x80070002
  Message=Could not load file or assembly 'CustomMarshalers, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The system cannot find the file specified.
  Source=<Cannot evaluate the exception source>
  StackTrace:
   at System.StubHelpers.StubHelpers.CreateCustomMarshalerHelper(IntPtr pMD, Int32 paramToken, IntPtr hndManagedType)
   at Dia2Lib.IDiaEnumTables.GetEnumerator()
   at Microsoft.CodeAnalysis.BinaryParsers.ProgramDatabase.Pdb.CreateDiaTable[T]() in ...\binskim\src\BinaryParsers\ProgramDatabase\Pdb.cs:line 234

This works if the main executable is using .NET 4.6.1–however I’m not able to find any documentation on how the interop services handle creating enumerators that suggests this isn’t supported in netcoreapp2.0.


This appears to be happening for a number of other DIA SDK enumeration objects. Other functionality on the objects (e.x. .Count, .Item(index), etc.) all seem to work as expected–it’s just the GetEnumerator() function that isn’t working.

Let me know if you need anything else–I can see about creating a minimal test case or similar if it’s necessary/helpful.

Thanks, Everett Maus

[edited by @danmosemsft for formatting]

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 1
  • Comments: 22 (11 by maintainers)

Most upvoted comments

@jjxtra To get the length you should allocate some memory before calling the method.

var bufferLengthPointer = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(Int32)));
enumVariant.Next(buffer.Length, buffer, bufferLengthPointer);
var len = Marshal.ReadInt32(bufferLengthPointer);
Marshal.FreeCoTaskMem(bufferLengthPointer);

Yeah this didn’t make the 3.0 Preview 1 deadline. I don’t think there’s a nightly build since the preview yet either. I’d suggest waiting until the next Preview release which should have these changes in. You could build from master, but it’s not straightforward to build a full dotnet.exe and runtime from the repos manually.

Custom marshalers are in scope for 3.0.

cc @AaronRobinsonMSFT

@falahati we are working through deeper Windows COM scenarios for .NET Core 3.0.

Is there any progress on this? Hitting this in .net core when trying to access com objects for iterating through the firewall rules on windows. There’s no way to workaround this, as INetFwRules.Item(string processName), gives the first rule for the process which is not what I want to check.

cc @luqunl

You can install bits from master though https://github.com/dotnet/core-sdk