c# - 使用 Fortran DLL 进行 NUnit 测试

标签 c# com nunit fortran

我有一个来自 Fortran 的 ServerCom DLL。我使用 tlbimp 从可以直接从 C# 引用的 ServerCom.dll 自动生成一个 MyFortran.dll。

在 C# 类库中,我引用了 MyFortran.dll。

我创建了一个使用 MyFortran.dll 的控制台应用程序并生成了正确的 list (以便拥有一个自由互操作的 COM 环境)。

它在控制台应用程序中完美运行。

现在,我编写了一个简单的 NUnit 测试并得到了一个 COM 异常。

System.Runtime.InteropServices.COMException : Retrieving the COM class factory for component with CLSID {0FB0F699-4EF8-4732-B98E-C088825E3912} failed due to the following error: 80040154 Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)).

我该如何解决这个问题?

谢谢, 阿德里安。

最佳答案

您可以使用 Activation Context API 来实现这一点。这blog post给出了所有的细节。

这是一个总结。

将以下代码粘贴到您的项目中(感谢 Spike McLarty):

/// <remarks>
/// Code from http://www.atalasoft.com/blogs/spikemclarty/february-2012/dynamically-testing-an-activex-control-from-c-and
/// </remarks>
class ActivationContext
{
    static public void UsingManifestDo(string manifest, Action action)
    {
        UnsafeNativeMethods.ACTCTX context = new UnsafeNativeMethods.ACTCTX();
        context.cbSize = Marshal.SizeOf(typeof(UnsafeNativeMethods.ACTCTX));
        if (context.cbSize != 0x20)
        {
            throw new Exception("ACTCTX.cbSize is wrong");
        }
        context.lpSource = manifest;

        IntPtr hActCtx = UnsafeNativeMethods.CreateActCtx(ref context);
        if (hActCtx == (IntPtr)(-1))
        {
            throw new Win32Exception(Marshal.GetLastWin32Error());
        }
        try // with valid hActCtx
        {
            IntPtr cookie = IntPtr.Zero;
            if (!UnsafeNativeMethods.ActivateActCtx(hActCtx, out cookie))
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }
            try // with activated context
            {
                action();
            }
            finally
            {
                UnsafeNativeMethods.DeactivateActCtx(0, cookie);
            }
        }
        finally
        {
            UnsafeNativeMethods.ReleaseActCtx(hActCtx);
        }
    }

    [SuppressUnmanagedCodeSecurity]
    internal static class UnsafeNativeMethods
    {
        // Activation Context API Functions
        [DllImport("Kernel32.dll", SetLastError = true, EntryPoint = "CreateActCtxW")]
        internal extern static IntPtr CreateActCtx(ref ACTCTX actctx);

        [DllImport("Kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool ActivateActCtx(IntPtr hActCtx, out IntPtr lpCookie);

        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool DeactivateActCtx(int dwFlags, IntPtr lpCookie);

        [DllImport("Kernel32.dll", SetLastError = true)]
        internal static extern void ReleaseActCtx(IntPtr hActCtx);

        // Activation context structure
        [StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Unicode)]
        internal struct ACTCTX
        {
            public Int32 cbSize;
            public UInt32 dwFlags;
            public string lpSource;
            public UInt16 wProcessorArchitecture;
            public UInt16 wLangId;
            public string lpAssemblyDirectory;
            public string lpResourceName;
            public string lpApplicationName;
            public IntPtr hModule;
        }

    }
}

每次需要创建 COM 对象(本例中为 COMObject)时,将创建它的调用包装在 lambda 函数中,并将其传递给 UsingManifestDo,如下所示:

object CreateManifestDependantCOMObject() 
{
   object myCOMObject = null;
   ActivationContext.UsingManifestDo(pathToManifestFile, () => myCOMObject = new COMObject());
   return myCOMObject;
}

关于c# - 使用 Fortran DLL 进行 NUnit 测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4935536/

相关文章:

c# - 检测 WCF 中的套接字断开连接

c# - 如何在 .NET Core 中使用 IUserIdProvider?

c++ - VB6 组件上的 QueryInterface 仅在调试器中返回 E_NOINTERFACE

c# - 包装静态类/方法以便对其进行单元测试?

c# - 在 Bamboo 中执行 NUnit 测试

c# - .NET 程序员的 JavaScript 编辑器

c# - 转换为双重转义字符串

visual-studio-2008 - 从命令行自动运行 NUnit 测试

com - 控制其他应用程序的音量

Python Win32Com & Excel.Application 无法保存在调度程序上