2011-02-09 101 views
2

所以我试图手动执行AxImp的工作(我正在动态执行)。按类型名称获取GUID

我的产品是一个广泛发布的,被认可的“附加”到第三方产品。他们有一个OCX,我通过COM参考添加到我的表单中。但是,如果客户端已经(或安装)他们产品的更新版本,我的产品将无法再加载OCX。

因此,我试图加载他们的OCX动态。除了我需要其中一个OCX中的其中一个接口的GUID之外,我已经完成了所有工作。我知道类型名称是什么,并且系统上注册了OCX> <。我怎么才能从类型名称获取对象的GUID?

请注意,Assembly.LoadFrom()不起作用,因为OCX不是.NET,而是COM。

回答

4

由于您的评论让我们知道GUID在OCX找到,但HKEY_CLASSES_ROOT下没有登记,我们将不得不从类型库中读取数据:

0

不知道为什么你不能简单地将COM reference添加到您的项目的DLL。

Visual Studio会自动将.NET包装添加到以此方式引用的任何COM对象。

+0

因为如果第三方更新其OCX(更改GUID)我的程序将无法正常加载。 – 2011-02-09 22:25:04

+0

@Jordan - 不,没有删除/添加和重新编译。第三方应该真的使用稳定的GUID。 – Oded 2011-02-09 22:27:20

+0

@Oded绝对。相信我,我测试的第一件事是通过工作室添加COM参考。这只有在第三方更新他们的OCX然后崩溃之后才有效。我无法控制他们做什么或如何做。 – 2011-02-09 22:31:34

0

我不得不写类似的东西从COM迁移代码以C#

class GetGuid 
{ 
    [DllImport("oleaut32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)] 
    static extern int LoadTypeLib(string fileName, out ITypeLib typeLib); 

    public string SearchRegistry(string dllPath /* or ocx */) 
    { 
     var result = string.Empty; 
     ITypeLib tl; 
     if (LoadTypeLib(dllPath, out tl) == 0) 
     { 
      ITypeInfo tf; 
      tl.GetTypeInfo(0, out tf); 

      var ip = IntPtr.Zero; 
      tl.GetLibAttr(out ip); 

      if (ip != IntPtr.Zero) 
      { 
       var ta = (System.Runtime.InteropServices.ComTypes.TYPELIBATTR)Marshal.PtrToStructure(ip, typeof(System.Runtime.InteropServices.ComTypes.TYPELIBATTR)); 
       result = ta.guid.ToString(); 
      } 
     } 
     return result; 
    } 
}