You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Core调用.NET Framework DLL时Marshal.GetActiveObject方法缺失求助

解决方案

方案1:修复.NET Framework DLL的调用问题

如果坚持用.NET Framework 4.8.1编写的DLL,需要确保.NET Core项目正确加载并使用DLL中的封装方法,而非尝试解析Core runtime中的Marshal类:

  1. 在.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");
            }
        }
    }
    
  2. 在.NET Core 7项目中添加对该DLL的引用,确保:

    • 引用的Copy Local属性设置为True
    • 在.NET Core项目的runtimeconfig.template.json中添加Framework兼容配置:
      {
        "configProperties": {
          "Microsoft.NETCore.EnableRuntimeCompatibility": true
        }
      }
      
  3. 调用时直接使用封装的方法:

    // .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的兼容实现:

  1. 在.NET Core 7项目中安装NuGet包:Microsoft.Windows.Compatibility
  2. 直接调用Marshal.GetActiveObject("SolidEdge.Application")
问题原因说明

你遇到的MissingMethodException是因为:.NET Core运行时会优先加载自身的System.Runtime.InteropServices.Marshal类,而该类没有GetActiveObject方法。即使调用.NET Framework DLL中的代码,CLR在解析方法引用时仍会绑定到Core版本的Marshal,导致找不到目标方法。

内容的提问来源于stack exchange,提问作者ampu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 15:58:15