【问题标题】:Interop DLL returning member not found未找到互操作 DLL 返回成员
【发布时间】:2012-06-21 21:48:41
【问题描述】:

好的,这是在黑暗中拍摄的,因为我已经束手无策了。我有两个第三方 DLL,它们在 VB6 中运行良好,但在 VB.NET 或 C# 中运行不佳。

在 VB6 中,以下工作正常:

Dim oApplication As Object
Dim oSession As Object
Dim vRetCode As Variant

Set oApplication = CreateObject("OAPPLICA.OAPPLICA")
Set oSession = CreateObject("OSESSION.OSESSION")

oApplication.PROGRAMDRIVE = "\\dev\data\"
oApplication.WORKAREADRIVE = "\\dev\data\workarea\"
oApplication.DATADRIVE = "\\dev\data\"
oApplication.IMAGEDRIVE = "\\dev\data\image\"

oSession.MYAPPLICATION = oApplication
vRetCode = oSession.LOGIN("USER1", "PASSWORD1") 'Returns zero if successful

MsgBox (vRetCode)

当我在 VB.NET 中运行这组完全相同的代码时,我在“oSession.MYAPPLICATION = oApplication”行上得到“未找到成员。(HRESULT 异常:0x80020003 (DISP_E_MEMBERNOTFOUND))”。

我也尝试在 VB.NET 和 C# 中进行早期绑定,但最终在不同的行上出现相同的错误。我在“oApplication.set_PROGRAMDRIVE("\\dev\lifepro\data\");”上得到了相同的错误行。

private OAPPLICA.OAPPLICA oApplication = new OAPPLICA.OAPPLICA();
private OSESSION.OSESSION oSession = new OSESSION.OSESSION();
Int64 iReturnCode;

oApplication.set_PROGRAMDRIVE("\\\\dev\\data\\");
oApplication.set_WORKAREADRIVE("\\\\dev\\data\\workarea\\");
oApplication.set_DATADRIVE("\\\\dev\\data\\");
oApplication.set_IMAGEDRIVE("\\\\dev\\data\\image");

m_oSession.set_MYAPPLICATION(m_oApplication);
iReturnCode = Convert.ToInt64(m_oSession.LOGIN("USER1", "PASSWORD1"));

如前所述,这两个 DLL(OAPPLICA.dll 和 OSESSION.dll)是第三方的,允许进入第三方遗留系统的入口点。由于它是遗留的,我无法再访问第三方,我的任务是尝试将现有的 Windows VB6 应用程序原型转换为 .NET Web 应用程序。我的预感是 .NET 在解释两个 COM 对象的互操作 DLL 时遇到问题,但我一直无法找到任何可以为我指明方向的东西。

【问题讨论】:

  • 您是如何将这两个 dll 添加到您的项目中的?右键单击,“添加引用”和“COM”选项卡?
  • 这两个 DLL 完全按照您的描述添加。
  • 方法.set_Application是否出现在intellisense中,我问的原因是因为错误消息是Member Not Found...并且VB6代码不使用.set_Application method,它分配给 MYAPPLICATION Property
  • 是的,.set_Application 出现在智能感知中。最初的属性方法并没有像 VB6 中那样出现,因为我试图设置应用程序属性,所以我认为这就是互操作 DLL 解释该功能的方式。
  • @Chris,你有 .Net Reflector 吗?如果没有,请检查一下。 27.am/posts/how-to-download-net-reflector-6-for-free 。一旦你有了它,我们就可以查看互操作程序集,也许看看为什么找不到这些方法。

标签: c# vb.net dll interop


【解决方案1】:

我的猜测是这段代码在 WinForms 应用程序中运行良好,你试过吗?

VB6 和大多数设计用于 VB6 的 COM 组件将要求您在 STA 线程上运行才能正常工作。您的 Web 代码可能在 MTA 线程上运行。

【讨论】:

  • 是的,试过了。我切换到一个 WinForms 应用程序只是为了看看我是否可以得到一些工作并且我遇到了同样的问题。
  • 至少排除了一件事。我会坚持通过 WinApp 进行挖掘,这样您一次只与一件事作斗争。
  • 我已经走得更远了。我在 Windows XP(32 位)/VS2010 环境中重新创建了所有内容,并且运行良好。因此,在 Windows 7(64 位)/VS2010 环境中,我得到了讨论的行为。由于某种原因,64 位 Windows 环境不喜欢注册的 COM DLL。打算做更多的研究,但我可能最终会打开 Microsoft 支持票。
  • 啊,没想到你是 64 位的。将您的 .Net 编译为 x86 而不是 Any
  • 你用什么来注册 COM 组件?尝试使用 C:\Windows\SysWOW64 中的版本。仔细检查工作系统上 COM 组件的注册表条目,并与非工作系统进行比较。最后,使用 ProcessMonitor 作为代码执行,看看是否真的在读取正确的 reg 键并定位 COM dll。
【解决方案2】:

终于明白了。出于某种原因,.NET 在运行时将属性解释为只读(对于 C# 和 VB.NET 以及对于 web 和 windows),即使在设计时有 get 和 set 选项。 VB6 在运行时和设计时都将属性解释为 get 和 set,所以你可以想象我的困惑。我以前从未遇到过这样的事情。无论如何,我开始在第三方 DLL 周围放置一个 VB6 包装器,然后让 .NET 引用 VB6 包装器 DLL。工作得很好,让我可以继续开发,但仍然想消除额外的 VB6 层。我们的一位 COBOL 开发人员最终能够模仿/重写旧版 DLL。我讨厌在这样的废话上浪费时间,但我很高兴它已经完成了。

【讨论】:

  • VB6 wrapper 是什么意思?
【解决方案3】:

如果@tcarvin 是正确的,而且他可能是正确的,您可以通过使用“AspCompat=true”页面指令来强制 ASP.net 应用成为 STA - msdn.microsoft.com/en-us/library/zwk9h2kb.aspx

【讨论】:

    猜你喜欢
    • 2012-04-30
    • 2013-12-16
    • 1970-01-01
    • 2014-06-20
    • 2014-08-02
    • 1970-01-01
    • 2015-12-26
    • 1970-01-01
    • 2022-12-13
    相关资源
    最近更新 更多