Skip to content

Instantly share code, notes, and snippets.

@Benshi
Created March 14, 2023 16:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Benshi/e26bbcdc50888ed8d68f7d89e4996e16 to your computer and use it in GitHub Desktop.
Save Benshi/e26bbcdc50888ed8d68f7d89e4996e16 to your computer and use it in GitHub Desktop.
[C#] .NET 6 で、現在開いている Word/Excel/PowerPoint を列挙する
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using Word = Microsoft.Office.Interop.Word;
using Excel = Microsoft.Office.Interop.Excel;
using PowerPoint = Microsoft.Office.Interop.PowerPoint;
if (!OperatingSystem.IsWindows()) { throw new PlatformNotSupportedException(); }
var objects = ROTManager.GetObjects();
foreach (var obj in objects)
{
// Console.WriteLine($"{obj.ClassID}, {obj.MonikerType}, {obj.DisplayName}");
if (obj.ComObject is Word.Document document)
{
Console.WriteLine($"Saved={document.Saved}, File={document.FullName}");
if (document.ActiveWindow is { } w)
{
Console.WriteLine($"\tHwnd=0x{w.Hwnd:X}, Caption={w.Caption}");
Marshal.ReleaseComObject(w);
}
}
else if (obj.ComObject is Excel.Workbook book)
{
Console.WriteLine($"Saved={book.Saved}, File={book.FullName}");
var app = book.Application!;
Console.WriteLine($"\tHwnd=0x{app.Hwnd:X}, Instance={app.HinstancePtr}");
if (app.ActiveWindow is { } w)
{
Console.WriteLine($"\tHwnd=0x{w.Hwnd:X}, Caption={w.Caption}");
Marshal.ReleaseComObject(w);
}
Marshal.ReleaseComObject(app);
}
else if (obj.ComObject is PowerPoint.Presentation presentation)
{
Console.WriteLine($"Saved={presentation.Saved}, File={presentation.FullName}");
var app = presentation.Application!;
if (app.ActiveWindow is { } w)
{
Console.WriteLine($"\tHWND=0x{w.HWND:X}, Caption={w.Caption}");
Marshal.ReleaseComObject(w);
}
Marshal.ReleaseComObject(app);
}
Marshal.ReleaseComObject(obj.ComObject);
}
public readonly record struct ActiveObject(object ComObject, SystemMoniker MonikerType, Guid ClassID, string DisplayName);
public enum SystemMoniker
{
None = 0,
GenericComposite = 1,
FileMoniker = 2,
AntiMoniker = 3,
ItemMoniker = 4,
PointerMoniker = 5,
UrlMoniker = 6,
ClassMoniker = 7,
ObjRefMoniker = 8,
SessionMoniker = 9,
LuaMoniker = 10,
}
public static class ROTManager
{
const int S_OK = 0;
[DllImport("ole32.dll", PreserveSig = false)]
private static extern IBindCtx? CreateBindCtx(uint reserved = 0u);
internal static ActiveObject[] GetObjects()
{
if (!OperatingSystem.IsWindows()) { throw new PlatformNotSupportedException(); }
var results = new List<ActiveObject>();
var (rot, enumMoniker) = (default(IRunningObjectTable), default(IEnumMoniker));
IBindCtx? ctx = CreateBindCtx();
ctx?.GetRunningObjectTable(out rot);
rot?.EnumRunning(out enumMoniker);
if (ctx is { } && rot is { } && enumMoniker is { })
{
while (true)
{
var monikers = new IMoniker[1];
if (enumMoniker.Next(1, monikers, IntPtr.Zero) != S_OK) { break; }
var moniker = monikers[0];
try
{
var monikerType = (moniker.IsSystemMoniker(out int pdwMksys) == S_OK) ? (SystemMoniker)pdwMksys : SystemMoniker.None;
moniker.GetDisplayName(ctx, moniker, out var displayName);
moniker.GetClassID(out var classID);
rot.GetObject(moniker, out object comObject);
results.Add(new ActiveObject(comObject, monikerType, classID, displayName));
}
finally
{
Marshal.FinalReleaseComObject(moniker);
moniker = null;
}
}
}
if (enumMoniker is not null) { Marshal.FinalReleaseComObject(enumMoniker); }
if (rot is not null) { Marshal.FinalReleaseComObject(rot); }
if (ctx is not null) { Marshal.FinalReleaseComObject(ctx); }
return results.ToArray();
}
}