Registering DLLs/OCXs that have integrated MSLU
(Originally posted 29 Dec 2002)
If you are using MSLU with a file other than an EXE that requires registration, you may run into a problem. Lets say that it is a DLL
named foo.dll. You may receive the following error when you attempt to register the DLL with regsvr32.exe on Win9x:
The reason for this error is a failure to load MSLU, and has to do with the way Windows and the MSLU loader work.
If you do not specify a loader override
for UnicoWS.dll, then the MSLU loader will simply attempt to load it with a call to LoadLibrary(). Ordinarily this would work quite well,
but it will fail when attempting to run regsrv32.exe, because that file is in the $(WinSys) directory and regsvr32.exe does not use the
directory in which the DLL/OCX is contained to search for dependent DLLs such as UnicoWS.dll. One could consider this a limitation of
regsvr32.exe, but at this point its as bit too late to get that issue fixed for Win9x, so you will have to
use one of the workarounds below to get your DLL/OCX registration to work properly (any of them will work):
- You can specify a loader override. It is
important to do more than the sample on that page does, since a simple call to LoadLibrary will not work in this case (you will fail in
the same way that the MSLU loader is failing!). You must specify a full path and file to where MSLU is located in order to properly load
UnicoWS.dll, for example the way that the MSLU sample does. This shows the general principle:
if regsvr32.exe can find UnicoWS.dll, then the MSLU loader will be able to.
- Mohammed can come to the mountain. You can copy regsvr32.exe to your application directory that contains both your DLL/OCX and
UnicoWS.dll -- this can be tricky since although it is easy to do, it is hard to help the user run this copy of regsvr32.exe rather
than the one in the path.
- If Mohammed won't come to the mountain, then the mountain will have to come to Mohammed! You can add a copy of UnicoWS.dll to the
$(WinSys) directory. This will allow the registration to work (since the MSLU loader will be able to find UnicoWS.dll), but this will
require you to keep two copies of Unicows.dll on the machine (the MSLU loader will not allow you to store the DLL in $(WinSys) unless your
component is also there). This solution is really not recommended since it can lead to the type of DLL Hell problem that the $(WinSys)
directory restriction attempts to avoid.
- Mohammed can build his own mountain! All that regsvr32.exe does is (1) call LoadLibrary on the file you specify, (2) call
GetProcAddress on a function named DllRegisterServer, and then (3) call that function. You can write your own registration routine to perform
these three steps, either in your own custom registration EXE located in your application directory, or in your actual application.
Now, for the record this is not a case of me (or Microsoft!) being difficult. Its one of those limitations in the architecture of how
LoadLibrary searches for the file it is
asked to load and the limitation in Windows that keeps the MSLU loader from knowing the directory in which it sits when it is integrated in
a DLL or OCX whose name it does not know (if it knew the name, it could use
GetModuleFileName to retrieve the
path). The idea of adding a global that could contain the name or the path (just as a global contains the loader override now) was considered
and then rejected since
- the loader override is already the preferred answer to many other questions;
- the override is such an effective solution when done properly;
- the MSLU loader and UnicoWS.dll are not always in the same directory.
Any questions? Probably a good idea to ask in the MSLU newsgroup, available via both
Problems with this site? Please contact the
with your comments, questions, or suggestions.