Skip to content

Commit 323d816

Browse files
committed
LoadNotification events
1 parent 7cfd525 commit 323d816

File tree

2 files changed

+27
-7
lines changed

2 files changed

+27
-7
lines changed

Source/ExcelDna.IntelliSense/IntelliSenseProvider.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ interface IIntelliSenseProvider
3838
}
3939

4040
// Provides IntelliSense info for all Excel-DNA based .xll add-ins, using the built-in RegistrationInfo helper function.
41-
// TODO: Loader monitoring - LdrRegisterDllNotification / see http://stackoverflow.com/questions/4242469/detect-when-a-module-dll-is-unloaded
4241
class ExcelDnaIntelliSenseProvider : IIntelliSenseProvider
4342
{
4443
class XllRegistrationInfo
@@ -53,6 +52,12 @@ public XllRegistrationInfo(string xllPath)
5352
{
5453
_xllPath = xllPath;
5554
_dllLoadNotification = new LoaderNotification();
55+
_dllLoadNotification.LoadNotification += _dllLoadNotification_LoadNotification;
56+
}
57+
58+
private void _dllLoadNotification_LoadNotification(object sender, LoaderNotification.NotificationEventArgs e)
59+
{
60+
Debug.Print($"@>@>@>@> LoadNotification: {e.Reason} - {e.FullDllName}");
5661
}
5762

5863
// Called in a macro context

Source/ExcelDna.IntelliSense/LoaderNotification.cs

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
using System;
2-
using System.Diagnostics;
32
using System.Runtime.InteropServices;
43

54
namespace ExcelDna.IntelliSense
65
{
7-
// Also not LDR_MODULE infor here: http://stackoverflow.com/questions/4242469/detect-when-a-module-dll-is-unloaded
6+
// Also note LDR_MODULE info here: http://stackoverflow.com/questions/4242469/detect-when-a-module-dll-is-unloaded
87
class LoaderNotification : IDisposable
98
{
109
public enum Reason : uint
@@ -13,6 +12,15 @@ public enum Reason : uint
1312
Unloaded = 2
1413
}
1514

15+
public class NotificationEventArgs : EventArgs
16+
{
17+
public Reason Reason;
18+
public string FullDllName;
19+
}
20+
21+
public event EventHandler<NotificationEventArgs> LoadNotification;
22+
23+
#region PInvoke details
1624
// Helper for UNICODE_STRING type - couldn't figure out how to do it simply with Marshaling
1725
static class UnicodeString
1826
{
@@ -43,7 +51,6 @@ struct Data
4351
public uint SizeOfImage; // The size of the DLL image, in bytes.
4452
}
4553

46-
4754
enum NtStatus : uint
4855
{
4956
// Success
@@ -65,23 +72,31 @@ enum NtStatus : uint
6572
[DllImport("ntdll.dll")]
6673
static extern uint /*NtStatus*/ LdrUnregisterDllNotification(IntPtr cookie);
6774

75+
#endregion
76+
6877
IntPtr _cookie;
6978
LdrNotification _notificationDelegate;
7079

7180
public LoaderNotification()
7281
{
73-
IntPtr context = new IntPtr(12345);
82+
IntPtr context = IntPtr.Zero; // new IntPtr(12345);
7483
_notificationDelegate = Notification;
7584
var status = LdrRegisterDllNotification(0, _notificationDelegate, context, out _cookie);
85+
if (status != 0)
86+
{
87+
throw new InvalidOperationException($"Error in LdrRegisterDlLNotification. Result: {status}");
88+
}
7689
}
7790

7891
// WARNING! LoaderLock danger here
7992
void Notification(Reason notificationReason, IntPtr pNotificationData, IntPtr context)
8093
{
8194
IntPtr pFullDllName = Marshal.ReadIntPtr(pNotificationData, 4);
8295
string fullDllName = UnicodeString.ToString(pFullDllName);
83-
Debug.Print($"@@@@ LdrNotification: {notificationReason} - {fullDllName}");
84-
// Raise Event
96+
NotificationEventArgs args = new NotificationEventArgs { Reason = notificationReason, FullDllName = fullDllName };
97+
LoadNotification?.Invoke(this, args);
98+
99+
// Debug.Print($"@@@@ LdrNotification: {notificationReason} - {fullDllName}");
85100
}
86101

87102
#region IDisposable Support

0 commit comments

Comments
 (0)