// Called when the process exits private static void Release() { // Release the handles foreach (var pair in s_loadedLibs) { if (s_platform == PlatformOS.Windows) { // Twice is needed Kernel32.FreeLibrary(pair.Value); Kernel32.FreeLibrary(pair.Value); } else { // Twice is needed Dl.Close(pair.Value); Dl.Close(pair.Value); } } // Delete the extracted files foreach (var path in s_libPaths) { File.Delete(path); } }
// Unloads all of the loaded libraries // Note that each library needs to be freed twice, since their use counter is increased by 2 by the use of // both the manual loader, as well as DllImport. If the count was not increased by 2, then the second call // is not dangerous. public static void UnloadLibraries() { if (s_loadedLibs.Count == 0) { return; } if (s_platform == PlatformOS.Windows) { foreach (var pair in s_loadedLibs) { Kernel32.FreeLibrary(pair.Value); Kernel32.FreeLibrary(pair.Value); } } else { foreach (var pair in s_loadedLibs) { Dl.Close(pair.Value); Dl.Close(pair.Value); } } foreach (var pair in s_libPaths) { try { // This will sometimes throw an exception for reasons unknown, take a look at this later File.Delete(pair.Value); } catch (Exception e) { Logger?.Invoke($"Unable to clean native library '{pair.Key}' at '{pair.Value}'."); Logger?.Invoke($" Reason: {e.Message}."); } } s_loadedLibs.Clear(); s_libPaths.Clear(); }