I have a buggy third-party DLL files that, after some time of execution, starts throwing the access violation exceptions. When that happens I want to reload that DLL file. How do I do that?
Asked
Active
Viewed 2.6k times
12
-
2How about loading the dll into a proxy process and terminate the whole process? Usually a process is considered broken after access violations. – CodesInChaos Jun 23 '11 at 11:03
-
How to do that? I heard very little about AppDomains. Can you please post some example? – Poma Jun 23 '11 at 11:15
-
2Since it's a native dll AppDomains won't help you. You need to have a second process that loads the dll and then uses some form of inter process communication to transfer calls between processes. .net remoting might be one way. But I haven't done that myself. – CodesInChaos Jun 23 '11 at 11:17
-
Looks like Stecya's solution is much simpler. – Poma Jun 23 '11 at 11:36
-
3Expecting a clean unload and reload from a dll that already has corrupted the memory so much that it throws access violation is not something I like. The dll lost track of which of its pointers are still valid. How should it free its memory cleanly on unload? – CodesInChaos Jun 23 '11 at 11:53
-
2Access violation errors are fatal in nature. I doubt you can catch them using try catch handlers and then take some corrective measure. – RBT Feb 09 '17 at 03:37
3 Answers
24
Try this
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr LoadLibrary(string libname);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern bool FreeLibrary(IntPtr hModule);
//Load
IntPtr Handle = LoadLibrary(fileName);
if (Handle == IntPtr.Zero)
{
int errorCode = Marshal.GetLastWin32Error();
throw new Exception(string.Format("Failed to load library (ErrorCode: {0})",errorCode));
}
//Free
if(Handle != IntPtr.Zero)
FreeLibrary(Handle);
If you want to call functions first you must create delegate that matches this function and then use WinApi GetProcAddress
[DllImport("kernel32.dll", CharSet = CharSet.Ansi)]
private static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);
IntPtr funcaddr = GetProcAddress(Handle,functionName);
YourFunctionDelegate function = Marshal.GetDelegateForFunctionPointer(funcaddr,typeof(YourFunctionDelegate )) as YourFunctionDelegate ;
function.Invoke(pass here your parameters);
-
And how to call my dll functions? When I declare them as `DllImport` this approach doesn't work – Poma Jun 23 '11 at 11:14
-
1Did you resolve this? can you provide some code snippe of the native code? how should the native code be declared and how does the delegate look? Thanks – freshWoWer Aug 05 '11 at 18:16
-
@Poma Did you get this working ? Can you please tell me how to get the GetDelegateForFunctionPointer working ? – GuidoG Jan 26 '18 at 07:46
0
Load the dll, call it, and then unload it till it's gone.
I've adapted the following code from the VB.Net example here.
[DllImport("powrprof.dll")] static extern bool IsPwrHibernateAllowed(); [DllImport("kernel32.dll")] static extern bool FreeLibrary(IntPtr hModule); [DllImport("kernel32.dll")] static extern bool LoadLibraryA(string hModule); [DllImport("kernel32.dll")] static extern bool GetModuleHandleExA(int dwFlags, string ModuleName, ref IntPtr phModule); static void Main(string[] args) { Console.WriteLine("Is Power Hibernate Allowed? " + DoIsPwrHibernateAllowed()); Console.WriteLine("Press any key to continue..."); Console.ReadKey(); } private static bool DoIsPwrHibernateAllowed() { LoadLibraryA("powrprof.dll"); var result = IsPwrHibernateAllowed(); var hMod = IntPtr.Zero; if (GetModuleHandleExA(0, "powrprof", ref hMod)) { while (FreeLibrary(hMod)) { } } return result; }

aboy021
- 2,096
- 2
- 23
- 23
0
Create a worker process that communicates via COM or another IPC mechanism. Then when the DLL dies, you can just restart the worker process.

Ben
- 34,935
- 6
- 74
- 113