.NET Core调用.NET Framework DLL时Marshal.GetActiveObject方法缺失求助
解决方案
方案1:修复.NET Framework DLL的调用问题
如果坚持用.NET Framework 4.8.1编写的DLL,需要确保.NET Core项目正确加载并使用DLL中的封装方法,而非尝试解析Core runtime中的Marshal类:
在.NET Framework DLL中封装Marshal.GetActiveObject为独立方法,不要直接暴露Marshal的调用:
// .NET Framework 4.8.1 类库代码 using System; using System.Runtime.InteropServices; namespace SolidEdgeInterop { public static class EdgeConnector { public static object GetActiveEdgeInstance() { return Marshal.GetActiveObject("SolidEdge.Application"); } } }在.NET Core 7项目中添加对该DLL的引用,确保:
- 引用的
Copy Local属性设置为True - 在.NET Core项目的
runtimeconfig.template.json中添加Framework兼容配置:{ "configProperties": { "Microsoft.NETCore.EnableRuntimeCompatibility": true } }
- 引用的
调用时直接使用封装的方法:
// .NET Core 7项目代码 var edgeApp = SolidEdgeInterop.EdgeConnector.GetActiveEdgeInstance();
方案2:直接在.NET Core中实现ROT访问(推荐)
既然.NET Core原生不支持Marshal.GetActiveObject,可以直接通过P/Invoke调用Windows OLE API操作运行对象表(ROT),完全绕过Framework依赖:
实现代码
using System; using System.Runtime.InteropServices; public static class RotHelper { [DllImport("ole32.dll")] private static extern int GetRunningObjectTable(int reserved, out IRunningObjectTable rot); [DllImport("ole32.dll")] private static extern int CreateBindCtx(int reserved, out IBindCtx ctx); [DllImport("ole32.dll", CharSet = CharSet.Unicode)] private static extern int CLSIDFromProgID(string progId, out Guid clsid); [ComImport] [Guid("00000001-0000-0000-C000-000000000046")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] private interface IRunningObjectTable { int EnumRunning(out IEnumMoniker enumMoniker); int GetObject(IMoniker moniker, out object obj); int Register(int flags, object obj, IMoniker moniker); int Revoke(int dwRegister); int IsRunning(IMoniker moniker); } [ComImport] [Guid("00000102-0000-0000-C000-000000000046")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] private interface IEnumMoniker { int Next(int celt, IMoniker[] rgelt, out int pceltFetched); int Skip(int celt); int Reset(); int Clone(out IEnumMoniker ppenum); } [ComImport] [Guid("0000000f-0000-0000-C000-000000000046")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] private interface IMoniker { int GetDisplayName(IBindCtx pbc, IMoniker pmkToLeft, out string ppszDisplayName); int BindToObject(IBindCtx pbc, IMoniker pmkToLeft, ref Guid riidResult, out object ppvResult); int BindToStorage(IBindCtx pbc, IMoniker pmkToLeft, ref Guid riid, out object ppvObj); int Reduce(IBindCtx pbc, int dwReduceHowFar, ref IMoniker ppmkToLeft, out IMoniker ppmkReduced); } [ComImport] [Guid("0000000e-0000-0000-C000-000000000046")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] private interface IBindCtx { int RegisterObjectBound(object punk); int GetRunningObjectTable(out IRunningObjectTable prot); } public static object GetActiveObject(string progId) { if (CLSIDFromProgID(progId, out Guid clsid) != 0) throw new COMException($"无效的ProgID: {progId}"); IRunningObjectTable rot = null; IEnumMoniker enumMoniker = null; try { if (GetRunningObjectTable(0, out rot) != 0) throw new COMException("无法访问运行对象表(ROT)"); if (rot.EnumRunning(out enumMoniker) != 0) throw new COMException("无法枚举ROT中的对象"); enumMoniker.Reset(); var monikers = new IMoniker[1]; int fetched; while (enumMoniker.Next(1, monikers, out fetched) == 0 && fetched == 1) { if (CreateBindCtx(0, out var bindCtx) != 0) { Marshal.ReleaseComObject(monikers[0]); continue; } monikers[0].GetDisplayName(bindCtx, null, out string displayName); if (displayName.Contains(clsid.ToString("B")) || displayName.Contains(progId)) { rot.GetObject(monikers[0], out object targetObj); Marshal.ReleaseComObject(bindCtx); Marshal.ReleaseComObject(monikers[0]); return targetObj; } Marshal.ReleaseComObject(bindCtx); Marshal.ReleaseComObject(monikers[0]); } } finally { enumMoniker?.ReleaseComObject(); rot?.ReleaseComObject(); } throw new COMException($"未找到ProgID为{progId}的活动实例"); } }
使用方式
直接调用获取Solid Edge实例:
var solidEdgeApp = RotHelper.GetActiveObject("SolidEdge.Application"); // 转换为强类型(需添加Solid Edge互操作引用) var edgeApp = (SolidEdgeFramework.Application)solidEdgeApp;
方案3:使用Windows兼容性包
通过安装官方兼容性包,在.NET Core中获得Marshal.GetActiveObject的兼容实现:
- 在.NET Core 7项目中安装NuGet包:
Microsoft.Windows.Compatibility - 直接调用
Marshal.GetActiveObject("SolidEdge.Application")
问题原因说明
你遇到的MissingMethodException是因为:.NET Core运行时会优先加载自身的System.Runtime.InteropServices.Marshal类,而该类没有GetActiveObject方法。即使调用.NET Framework DLL中的代码,CLR在解析方法引用时仍会绑定到Core版本的Marshal,导致找不到目标方法。
内容的提问来源于stack exchange,提问作者ampu
相关产品推荐
相关产品推荐

