How to unload Interop DLL? - dll

I have a reference in C# project to Interop DLL. It gets loaded after a first function call. But I need to unload it then. How should I do it? It is listed in Process.GetCurrentProcess().Modules, but I cannot kill the module. I tried to use Marshal.ReleaseComObject but it is impossible for a ProcessModule.

Related

registering a dll on various OS

I have looked through countless threads on the error message
"the module was loaded but the entry-point dllregisterserver was not found make sure that is a valid DLL or OCX file"
I also tried regsvr32, and regsvr32 from syswow64...
I also tried registering it as name.ocx (per another threads suggestion).
Option Explicit On
Imports System
Public Class GenThis
Public Function rtnStr(Optional ByVal o As Object = Nothing) As String
Try
'do stuff
rtnStr = strTmp
Catch ex As Exception
Return "ERROR"
End Try
End Function
End Class
That is the class, being built on 2.0. When I add the dll as a reference in VS everything works fine. When I try to go in (same machine, Win7) to Excel Dev tab to try and add it there it does not exist. Also need to be bale to register it for our VB6 application.
I can't find any definitive answers or explanations on "what" this means. Can someone elaborate what is going on and what I am doing wrong?
Not all COM dlls are registerable. Sometimes the registration info sits in another dll. Programming languages use type libraries that may or may not be in the dll. Type libraries and registration is two seperate things.
.NET COM dlls aren't registerable in the normal way (it's the .NET framework that gets registered and it recieves calls and passes them to the .NET COM dll). For .NET use RegAsm, part of the .NET framework, which sets it up.

DLL unloading itself

Is it possible for a function that is inside a DLL to unload the DLL? I need to do this so I can make sure the DLL is not in use, then write to the DLL's file.
As I understand it, it CAN be done and is MEANT to be done sometimes (for example in case of dll injection by CreateRemoteThread and other methods). So,
FreeLibraryAndExitThread(hModule, 0)
will do precisely that.
On the other hand, calling
FreeLibrary(hModule)
will not do here - from MSDN: "If they were to call FreeLibrary and ExitThread separately, a race condition would exist. The library could be unloaded before ExitThread is called." As a remark, ExitThread does some bookkeeping besides just returning from the thread function.
All this assumes that Your Dll obtained the hModule itself by calling LoadLibrary from inside the loaded Dll, or rather, by calling from inside the loaded Dll the following function:
GetModuleHandleEx
(
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
(LPCTSTR)DllMain,
&hModule
)
This increments the reference count of the Dll so You know that if You free the library later using that handle and if the library is really unloaded then You had the last reference to it.
If You instead skip incrementing the Dll's reference count and obtain the hModule just from the argument to DllMain during DLL_PROCESS_ATTACH then You should not call FreeLibraryAndExitThread since the code that loaded the Dll is still using it and this module handle really isn't Yours to manage.
Use this when the dll has done it job:
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)FreeLibrary, &__ImageBase, 0, NULL);
// terminate if dll run in a separate thread ExitThread(0);
// or just return out the dll
And the __ImageBase is your dll's PE header structure:
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
If your asking if you can safely unload/unmap a DLL loaded in a process from code in the DLL itself, the answer is no - there isn't really a safe way to do this.
Think about it this way: Unloading a DLL is done by decrementing it's reference count using FreeLibrary(). The problem of course is that once the reference count of the DLL hits zero, the module is unmapped. Which means that the code in the DLL that called FreeLibrary() is gone.
Even if you could do this, you'd still need to ensure that there are no other threads executing any exported functions from the DLL.
I don't think it will work. Calling FreeLibrary with a handle from the outside (LoadLibrary would have been called from an area outside the DLL) as the code runs in a memory location that will not be valid anymore.
Even if this is possible, it smells like a bad design. Maybe you want to make some updater or alike. Explain a bit more what is the result you expect. Unloading a DLL from within itself is not the way to go.

How to force the unmanaged to managed calls to use the default appdomain?

I have been trying to fix this issue for quite sometime now. I have a C# user control wrapping an activex control (through wrappers created by RCW); This particular activex control loads MFC extension dll which has got C# WPF assembly dependant. This MFC extension dll calls C# WPF assembly through classes compiled as managed (using /clr compiler option).
The problem here is that - when my C# user control gets loaded in C#; It gets into the default app domain and everything seems to be working fine; but whenever a call is made from unmanaged part of MFC extension dll to the managed portion of it, it cramps to find the C# WPF assembly. I googled to find that there seems another appdomain getting created when a call is made from unmanaged portion of MFC extension dll to the managed portion. Right now, I am clueless about this one - How to force the unmanaged to managed calls to use the default appdomain?

Can I override _matherr in an C++/CLI dll?

I have an unmanaged c++ application that provides a custom _matherr handler. When this application loads and runs code in unmanaged DLLs, if there is a Math error ( e.g. asin( 100.0 ) ) the custom _matherr function is called and everything works.
However, I'm now trying to create a NUnit Test DLL in C++/CLI that loads the same unmanaged DLL and runs the same code as the application above. What I want to do is add the _matherr function to the C++/CLI dll such that when math errors occur I can perform some custom handler logic.
The C++/CLI dll compiles just fine with the _matherr function defined, but when I force a math error from the unmanaged dll, the _matherr function is not called.
Is this not supported by C++/CLI? The MSDN documentation seems to say _matherr is supported by all C Run times, (with a link to a list of runtimes including the /clr runtime. )
My experience is that defining _matherr does not work if done in a dll. It must be defined in the executable.
I've even seen compilers that when you try to add _matherr in a dll, will not link it in because they don't see anybody making a reference to it.
Maybe you need something like a proxy dll, passing through each function call to the original dll excepting those you want to be handled extra.

ActiveX Component Can't Create Object

I have VB6 ActiveXDLL called A.dll , I am referencing this DLL into my VB.Net Application.
Now I am calling a function of A.dll in this project. A.dll function is referring to the function of B.dll, C.dll, C.dll further referrer to Z.dll and so on.
when I am executing application it gives an error from B.dll that ActiveX component can't create an object.
My first thought would be to make sure all dlls are registered.
Assuming the ActiveX DLL is VB6 and you have access to the VB6 IDE, ensure the class's Instancing property is set to Multiuse.
Use OLE View (comes with visual studio) to browse ther TypeLib entry and check it has the correct GUID and that there is onely one registration. Can you create an object instance from the DLL with CreateObject? If not it is not registered correctly.
Also check any dependencies / references used by A.dllIf it can't find something then it's going to fail.These are the four common causes of the error:
1. You do not have a required TLB or ActiveX DLL/OCX file.
2. A TLB or ActiveX DLL/OCX needed by the project is present but not registered on your system.
3. The VB runtimes are an earlier version than the one you need to run the project.
4. A required TLB or ActiveX DLL/OCX file is corrupt.