【问题标题】:Trouble calling C# 32 bit Com from 64 bit C# application无法从 64 位 C# 应用程序调用 C# 32 位 Com
【发布时间】:2021-03-06 19:47:16
【问题描述】:

首先,我知道有几篇关于做我想做的事的文章。这没什么特别的。但是我在这里和其他地方阅读了许多文章并阅读了多个示例,我似乎得到了相互矛盾的信息以及非常平庸的成功。我要求熟悉 COM 的人耐心等待并帮助第一次接触 COM 的人。

我将根据我的研究解释我认为需要做什么,并请知识渊博的人指出我做错了什么并帮助我填补知识空白。我的应用程序使用第三方 32 位 DLL 和 64 位 DLL。有一堆 64 位的,只有一个 32 位的。这就是我使用 64 位应用程序的原因。如果有人在乎,那就是 Minolta kmsecs200.dll。该网站清楚地表明它们没有 64 位版本。

第一步是创建 32 位 COM 包装器。此时,我的示例代码不包含任何内容。它只有一个简单的功能。以下是我创建 DLL 的步骤:

新建C#、windows、类库(.Net Framework)、.NET Framework 4

将项目命名为“SimpleCom”,将类和CS文件重命名为“JustOne”

在项目属性中: 在 Application 选项卡上:单击“Assembly Information”并设置“Make assembly COM-Visible” 在构建选项卡上:将平台目标设置为 x86 在签名选项卡上:选择“签署程序集”并创建一个名为“StrongSimpleCom”的新强名称密钥文件,无密码保护

这是 JustOne.cs 代码:

using System.Runtime.InteropServices;

namespace SimpleCom
{
  [Guid("EAA4976A-45C3-4BC5-BC0B-E47474C3C83F")]
  public interface IJustOne
  {
    [DispId(1)]
    string AddName(string name);
  }

  [Guid("0D53A3E8-E51A-49C7-BC0B-E47474C3C83F"),
      ClassInterface(ClassInterfaceType.None)]
  public class JustOne : IJustOne
  {
    public JustOne() { }

    public string AddName(string name)
    { return "My name is: " + name; }

  }
}

在目标机器上注册 32 位程序集: 从管理命令提示符导航到 DLL 文件夹 C:\Windows\Microsoft.NET\Framework\v4.0.30319\regasm.exe SimpleCom.dll /codebase /tlb:myTlb.tlb 我使用 /codebase 是因为如果我将我的 DLL 放在 GAC 中,我还不知道如何调用第三方 DLL。我真的不明白注册后的 tlb 文件是什么。我想知道是否有人可以告诉我。 此时,COM 对象出现在 Visual Studio 中,但我不能这样称呼它,我理解这一点。它只是告诉我它至少在某种意义上是注册的。 所以我认为我应该能够调用我从 32 位 C# 应用程序编写的 32 位 C# DLL。但我就是不知道该怎么做。我似乎找不到使用调用的好例子。我非常感谢有关如何在一个简单的应用程序中调用“IJustOne”的帮助。

一旦成功,我可以添加一些注册表项以使其脱离进程并将 32 位应用程序变为 64 位应用程序。这是我听到的修改注册表以使进程的 32 位 COM oup 并使用 DLLhost 作为代理的方法之一。

2009 年的 Techtalk.gfi.com 方法* 导航到:HKEY_CLASSES_ROOT\WOW6432Node\CLSID{EAA4976A….} • 添加“AppID”并将值设置为 Guid 导航到:HKEY_CLASSES_ROOT\WOW6432Node\AppID • 使用 Guid 作为名称创建新密钥 • 在键中,添加没有值的“DllSurrogate” 导航到:HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID • 使用 Guid 作为名称创建一个新密钥

再次,我很难找到关于如何调用 COM 对象的简单直接的示例。我创建了一个 C# DLL 包装器,我可以直接将其包含在一个简单的 C# 32 位应用程序中,因此我对包装非托管的第 3 方 DLL 感到满意。我想知道如何确保我的包装 DLL 可以找到他们的 DLL。

我不知道我在注册 DLL 时做错了什么,也不知道如何在 64 位应用程序或 32 位应用程序中调用它。我感谢任何帮助。我花了几天时间试图追查这个问题,但最后,我的知识基础还不够强大。但回顾一下大局: 我正在使用第三部分 32 位非托管 DLL。我需要从我的 64 位 C# 应用程序中调用它。我相信这样做的方法是将其包装在托管的 C# 32 位 DLL 包装器中,并使其成为使用 DLLhost 作为代理的进程外 COM 对象。

再次感谢,

戴夫

【问题讨论】:

  • 您真的必须在您的 64 位应用程序和 32 位助手进程之间使用 COM 吗?使用其他一些 RPC 机制可能会更简单。
  • 我建议您使用组件服务,而不是“手动”代理,它更容易设置并且具有更多功能。这里有一个例子:stackoverflow.com/questions/52601470/… 虽然 dll 是用 C++ 编写的,但原理完全相同(请注意,这一切都可以在 UI 之外进行编程以自动设置)。否则:1)您不需要 GAC,这可能会很痛苦,只需 /codebase 2)TLB 为任何想要使用您的对象(.NET、C++、Delphi、脚本等)的 COM 客户端定义您的对象元数据.) 或用于组件服务注册
  • 我根本没有和 COM 结婚。在 Microsoft 网站上搜索信息时,我遇到了这个说要使用 COM:docs.microsoft.com/en-us/windows/win32/winprog64/… 但如果这不是最好的方法,我愿意以不同的方式来做。我将查看 Simon 提供的链接,看看我能找到什么。谢谢。
  • Klaus Gutter,如果您有比 COM 更好的建议,我绝对有兴趣听听。您有可以向我展示另一种方式的建议和链接吗?
  • Simon,按照您提供的示例代码链接的说明,我确实运行了 COM+ 应用程序并创建了一个新应用程序并添加了我的组件。因为我之前在我的包装 DLL 上调用了 regasm,所以我的组件在列表中。当我创建一个新的 C# 应用程序并去添加一个 COM 对象时,它说无法添加对“SimpleCom”的引用。 ActiveX 类型库是从 .NET 程序集导出的,我应该将其添加为 .NET 程序集。但它不在程序集列表中。我是否需要以不同的方式执行此操作,因为我的包装 DLL 它是一个 .NET DLL?

标签: c# .net dll com


【解决方案1】:

Simon 在上面指出了我正确的方向。我的 DLL 注册得很好。我通过组件服务将它添加为组件,之后一切正常。谢谢你,西蒙。

【讨论】:

    猜你喜欢
    • 2020-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-24
    • 1970-01-01
    • 1970-01-01
    • 2021-07-31
    相关资源
    最近更新 更多