Hi,
I’ve got a .net host with delphi plugins.
When I do not load my plugins, my application closes well. But when I load my plugins and close my application, it’s process hangs.
I tried removing the plugins with ModuleManager.Plugins.Remove and I tried to unload the modules with ModuleManager.Modules.Unload. In windows 7, it seems to do the job by just to unloading the modules, but in windows Vista, I get an access violation “Attempted to read or write protected memory” in my form Dispose.
Am I unloading my modules in the wrong way, or is it just an issue?
Thanks!
In general there should be no need to manually unload modules, .net should take care about this manually.
As for your problem, there can be couple reasons:
You leave reference to a plugin instance alive, so when .net tries to release them you will get an exception because dll already unloaded.
Same problem inside our library. I’ve logged this for review.
Anyway, here is the code that you use, it will release all the resources:
using System.Runtime.InteropServices;
private void UnloadAll()
{
//You need to manually release plugin reference before unload module
/*Here should be your code (you need to release plugin from host panel (if any)
and also release reference to an instance, for example:
pnl_Host.UnhostPlugin(); //release plugin from host panel
//release reference
if ((fCurrentPlugin != null) && (Marshal.IsComObject(fCurrentPlugin)))
{
Marshal.FinalReleaseComObject(fCurrentPlugin);
fCurrentPlugin = null;
}
*/
//After that you can unload everything
LoadedModule[] Modules = new LoadedModule[moduleManager.Modules.Count];
moduleManager1.Modules.CopyTo(Modules, 0);
foreach (LoadedModule Module in Modules)
{
//Here is the code that will force resource release from a unmanaged module
if (Module is LoadedUnmanagedModule)
{
LoadedUnmanagedModule Unmanaged = (Module as LoadedUnmanagedModule);
if ((Unmanaged.ModuleController != null) && (Marshal.IsComObject(Unmanaged.ModuleController)))
{
Marshal.FinalReleaseComObject(Unmanaged.ModuleController);
}
if ((Unmanaged.UnmanagedModule != null) && (Marshal.IsComObject(Unmanaged.UnmanagedModule)))
{
Marshal.FinalReleaseComObject(Unmanaged.UnmanagedModule);
}
foreach (UnmanagedPluginDescriptor Descriptor in Module.Plugins)
{
if ((Descriptor.UnmanagedPluginDescriptor != null) && (Marshal.IsComObject(Descriptor.UnmanagedPluginDescriptor)))
Marshal.FinalReleaseComObject(Descriptor.UnmanagedPluginDescriptor);
}
}
moduleManager.UnloadModule(Module);
}
}
Please remember to modify it’s first part and add code that will release your references to a plugin.