c# - 通过 PIA 接口(interface)类型获取 CLSID

标签 c# com

编辑: 看起来 Jon Skeet 有一些类似的问题:How does the C# compiler detect COM types?

如何获取主互操作程序集中给定接口(interface)的 CLSID?这就是我要说的:

// The c# compiler does some interesting magic.
// The following code ...
var app = new Microsoft.Office.Interop.Outlook.Application();

// ... is compiled like so (disassembled with Reflector):
var app =((Microsoft.Office.Interop.Outlook.Application)
  Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid("0006F03A-0000-0000-C000-000000000046"))));


Microsoft.Office.Interop.Outlook.Application 是一个接口(interface),因此不能直接实例化。这里有趣的是,c# 允许您将这些 COM 接口(interface)视为可以使用 new 关键字实例化的类。

我想知道的是,给定接口(interface)的 System.Type,我如何才能获得 CLSID?

注意:我最终希望能够在给定接口(interface)的 System.Type 的情况下创建实例 - 我真的不在乎如何创建。我在这里假设最简单的方法是在给定类型的情况下获取 CLSID,就像 C# 编译器所做的那样。

最佳答案

这是我目前的解决方案:

// Get the PIA assemby name, using the GUID of the typlib
string asmName;
string asmCodeBase;
var conv = new System.Runtime.InteropServices.TypeLibConverter();
conv.GetPrimaryInteropAssembly(new Guid("00062FFF-0000-0000-C000-000000000046"), 9, 3, 0, out asmName, out asmCodeBase);

// Load the PIA, and get the interface type
var assembly = System.Reflection.Assembly.Load(asmName);
var type = assembly.GetType("Microsoft.Office.Interop.Outlook.Application");

// Get the coclass
var coClassAttr = (System.Runtime.InteropServices.CoClassAttribute)
    type.GetCustomAttributes(typeof(System.Runtime.InteropServices.CoClassAttribute), false)[0];
var coClass = coClassAttr.CoClass;

// Instantiate the coclass
var app = Activator.CreateInstance(coClassAttr.CoClass);

// If needed, the CLSID is also available:
var clsid = coClass.GUID;

我通过分解 GAC 的 PIA 解决了这个问题。我注意到 Outlook.Application 装饰有 CoClassAttribute,如下所示:

[ComImport, Guid("00063001-0000-0000-C000-000000000046"), CoClass(typeof(ApplicationClass))]
public interface Application : _Application, ApplicationEvents_11_Event
{
}

ApplicationClass 看起来像:

[ComImport, ClassInterface((short) 0), ComSourceInterfaces("Microsoft.Office.Interop.Outlook.ApplicationEvents_11\0Microsoft.Office.Interop.Outlook.ApplicationEvents\0Microsoft.Office.Interop.Outlook.ApplicationEvents_10\0"), Guid("0006F03A-0000-0000-C000-000000000046"), TypeLibType((short) 11)]
public class ApplicationClass : _Application, Application, ApplicationEvents_11_Event, ApplicationEvents_Event, ApplicationEvents_10_Event
{
    //...
}

让我知道你们的想法,这样我就可以决定是否将其标记为已选答案。

关于c# - 通过 PIA 接口(interface)类型获取 CLSID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2634528/

相关文章:

c# - 如何使用 asp.net mvc 在模态中插入 json 消息

c# - ASCII.GetString() 在空字符处停止

c# - LINQ 与常规枚举

c++ - 如何确定 SystemTime 值是否为 UTC

com - 在 64 位组件中注册 32 位 COM 类

delphi - 通过 IDispatch Invoke 实现识别 COM 事件的调用者

internet-explorer - IE COM 的 querySelectorAll 在 IE 8 中不起作用

c++ - 从 win32 应用程序使用 Excel 2007

C# Post 请求被破坏

c# - C#中的INSERT INTO语句中的语法错误OleDb异常无法发现错误