获取第一个运行的COM应用程序实例

1 using System; 2 using System.Collections.Generic; 3 using System.Runtime.InteropServices; 4 using System.Runtime.InteropServices.ComTypes; 5 6 /// <summary> 7 /// 提供查询运行中COM对象的改进方案 8 /// </summary> 9 public static class ComObjectQuery 10 { 11 [DllImport("ole32.dll")] 12 private static extern int GetRunningObjectTable(int reserved, out IRunningObjectTable prot); 13 14 /// <summary> 15 /// 获取当前运行中指定类型的COM对象实例 16 /// </summary> 17 /// <typeparam name="T">要查询的COM接口类型</typeparam> 18 /// <returns>找到的COM对象列表,如果没有找到则返回空列表</returns> 19 public static IReadOnlyList<T> GetRunningObjects<T>() 20 { 21 var instances = new List<T>(); 22 23 try 24 { 25 // 获取运行对象表 26 if (GetRunningObjectTable(0, out var rot) != 0 || rot == null) 27 { 28 return instances; 29 } 30 31 try 32 { 33 // 枚举运行中的对象 34 rot.EnumRunning(out var monikerEnum); 35 if (monikerEnum == null) 36 { 37 return instances; 38 } 39 40 try 41 { 42 monikerEnum.Reset(); 43 var moniker = new IMoniker[1]; 44 var fetched = IntPtr.Zero; 45 46 // 遍历所有运行中的对象 47 while (monikerEnum.Next(1, moniker, fetched) == 0) 48 { 49 try 50 { 51 // 获取对象实例 52 rot.GetObject(moniker[0], out var comObject); 53 if (comObject is T typedObject) 54 { 55 instances.Add(typedObject); 56 } 57 else if (comObject != null) 58 { 59 Marshal.ReleaseComObject(comObject); 60 } 61 } 62 catch (Exception ex) 63 { 64 // 记录错误但继续处理其他对象 65 System.Diagnostics.Trace.WriteLine($"获取COM对象时出错: {ex.Message}"); 66 } 67 } 68 } 69 finally 70 { 71 Marshal.ReleaseComObject(monikerEnum); 72 } 73 } 74 finally 75 { 76 Marshal.ReleaseComObject(rot); 77 } 78 } 79 catch (Exception ex) 80 { 81 System.Diagnostics.Trace.WriteLine($"查询运行COM对象时发生错误: {ex.Message}"); 82 } 83 84 return instances; 85 } 86 87 /// <summary> 88 /// 获取第一个匹配的COM对象实例 89 /// </summary> 90 /// <typeparam name="T">要查询的COM接口类型</typeparam> 91 /// <returns>找到的第一个COM对象,如果没有找到则返回null</returns> 92 public static T GetFirstRunningObject<T>() 93 { 94 var objects = GetRunningObjects<T>(); 95 return objects.Count > 0 ? objects[0] : default; 96 } 97 }
调用方法:
// 获取所有运行的Excel应用程序实例 var excelApps = ComObjectQuery.GetRunningObjects<Microsoft.Office.Interop.Excel.Application>();// 获取第一个运行的Word应用程序实例 var wordApp = ComObjectQuery.GetFirstRunningObject<Microsoft.Office.Interop.Word.Application>();