11using System ;
2- using System . Diagnostics ;
32using System . Runtime . InteropServices ;
43
54namespace 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