如何在Outlook晚绑定场景下实现类型比较?
晚绑定Outlook时实现类型比较的方案
问题描述
我想将一段Outlook专属代码转换为晚绑定实现,但需要进行类型比较,不清楚如何在不提前加载DLL的情况下完成该操作。
现有代码如下:
var ol = (dynamic)Marshal.GetActiveObject("Outlook.Application"); dynamic windowType = ol.Application.ActiveWindow(); if (windowType is Microsoft.Office.Interop.Outlook.Explorer) { Console.WriteLine("success") }
如果不加载Outlook的Interop DLL,代码无法编译,因此必须添加:
using Microsoft.Office.Interop.Outlook
但我不想引入该命名空间,因为不确定目标机器上安装的Outlook具体版本,这也是我选择晚绑定的原因。
我尝试通过以下代码获取类型:
Console.WriteLine($"This is my type {windowType.GetType()}");
但结果仅为:
This is my type System.__ComObject
请问如何在晚绑定Outlook的同时实现类型比较?能否加载特定类型用于比较?
解决方案
方法1:通过COM接口的GUID或ProgID判断
COM对象的类型可通过其接口的GUID或ProgID识别,无需提前引入Interop DLL。你可以使用Type.GetTypeFromCLSID或Type.GetTypeFromProgID获取对应类型,再通过IsInstanceOfType方法判断:
使用GUID判断
using System; using System.Runtime.InteropServices; var ol = (dynamic)Marshal.GetActiveObject("Outlook.Application"); dynamic activeWindow = ol.ActiveWindow(); // Outlook Explorer接口的固定GUID Type explorerType = Type.GetTypeFromCLSID(new Guid("00063001-0000-0000-C000-000000000046")); if (explorerType.IsInstanceOfType(activeWindow)) { Console.WriteLine("success"); }
使用ProgID判断
using System; using System.Runtime.InteropServices; var ol = (dynamic)Marshal.GetActiveObject("Outlook.Application"); dynamic activeWindow = ol.ActiveWindow(); Type explorerType = Type.GetTypeFromProgID("Outlook.Explorer"); if (explorerType != null && explorerType.IsInstanceOfType(activeWindow)) { Console.WriteLine("success"); }
方法2:通过COM对象的Class属性判断
Outlook的COM对象支持Class属性,该属性返回固定的枚举值,不同版本的Outlook中这些值不会变动。比如Explorer对应的数值是34:
using System.Runtime.InteropServices; var ol = (dynamic)Marshal.GetActiveObject("Outlook.Application"); dynamic activeWindow = ol.ActiveWindow(); // 获取窗口类型的Class值,olExplorer对应34 int windowClass = (int)activeWindow.Class; if (windowClass == 34) { Console.WriteLine("success"); }
方法3:动态加载Interop DLL获取类型
如果一定要用Interop类型进行比较,可以在运行时动态加载Outlook的Interop DLL,再获取对应类型。但这种方法需要知道DLL的具体路径,不同Office版本路径可能不同,实用性稍差:
using System.Reflection; using System.Runtime.InteropServices; var ol = (dynamic)Marshal.GetActiveObject("Outlook.Application"); dynamic activeWindow = ol.ActiveWindow(); // 示例路径对应Office 2016及以后版本,需根据实际情况调整 Assembly outlookAssembly = Assembly.LoadFrom(@"C:\Program Files (x86)\Microsoft Visual Studio\Shared\Visual Studio Tools for Office\PIA\Office16\Microsoft.Office.Interop.Outlook.dll"); Type explorerType = outlookAssembly.GetType("Microsoft.Office.Interop.Outlook.Explorer"); if (explorerType.IsInstanceOfType(activeWindow)) { Console.WriteLine("success"); }
内容的提问来源于stack exchange,提问作者Silve2611
相关产品推荐
相关产品推荐

