-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathRunningObjectTable.cs
104 lines (88 loc) · 2.9 KB
/
RunningObjectTable.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
namespace OutOfProcDemo
{
using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
/// <summary>
/// Wrapper for the COM Running Object Table.
/// </summary>
/// <remarks>
/// See https://docs.microsoft.com/en-us/windows/desktop/api/objidl/nn-objidl-irunningobjecttable.
/// </remarks>
internal class RunningObjectTable : IDisposable
{
private readonly IRunningObjectTable rot;
private bool isDisposed = false;
public RunningObjectTable()
{
Ole32.GetRunningObjectTable(0, out this.rot);
}
public void Dispose()
{
if (this.isDisposed)
{
return;
}
Marshal.ReleaseComObject(this.rot);
this.isDisposed = true;
}
/// <summary>
/// Attempts to register an item in the ROT.
/// </summary>
public IDisposable Register(string itemName, object obj)
{
IMoniker moniker = CreateMoniker(itemName);
const int ROTFLAGS_REGISTRATIONKEEPSALIVE = 1;
int regCookie = this.rot.Register(ROTFLAGS_REGISTRATIONKEEPSALIVE, obj, moniker);
return new RevokeRegistration(this, regCookie);
}
/// <summary>
/// Attempts to retrieve an item from the ROT.
/// </summary>
public object GetObject(string itemName)
{
IMoniker mk = CreateMoniker(itemName);
int hr = this.rot.GetObject(mk, out object obj);
if (hr != 0)
{
Marshal.ThrowExceptionForHR(hr);
}
return obj;
}
private void Revoke(int regCookie)
{
this.rot.Revoke(regCookie);
}
private IMoniker CreateMoniker(string itemName)
{
Ole32.CreateItemMoniker("!", itemName, out IMoniker mk);
return mk;
}
private class RevokeRegistration : IDisposable
{
private readonly RunningObjectTable rot;
private readonly int regCookie;
public RevokeRegistration(RunningObjectTable rot, int regCookie)
{
this.rot = rot;
this.regCookie = regCookie;
}
public void Dispose()
{
this.rot.Revoke(this.regCookie);
}
}
private static class Ole32
{
[DllImport(nameof(Ole32))]
public static extern void CreateItemMoniker(
[MarshalAs(UnmanagedType.LPWStr)] string lpszDelim,
[MarshalAs(UnmanagedType.LPWStr)] string lpszItem,
out IMoniker ppmk);
[DllImport(nameof(Ole32))]
public static extern void GetRunningObjectTable(
int reserved,
out IRunningObjectTable pprot);
}
}
}