Why is my DLL failing to register? - c++

I am building a project in VS2005 and several of my DLLs are failing to register. The error message I am getting in Visual Studio is:
Project : error PRJ0019: A tool returned an error code from "Registering ActiveX Control..."
which is nicely vague. When I register the DLL manually through the command line (using regsv32.exe, I get the following error:
LoadLibrary("test.ocx") failed - This application has failed to start because the application configuration is incorrect. Reinstalling the application may fix the problem.
I ran Dependency Walker (depends.exe) on the culprit .ocx file but it isn't showing any obvious problems.
I have also done a re-build but I'm still getting the same problem.
Any suggestions as to how I could determine the cause of this failure to register?

Microsoft had recently released a Security Update for ATL (KB971090). It is un update on top of MSVS2005sp1 and it's both compilate-time and runtime compatibility breaker. Check if your building environment has this patch.
References:
ATL Security Update:
http://msdn.microsoft.com/en-us/visualc/ee309358.aspx
Breaking changes in ATL:
http://msdn.microsoft.com/de-de/library/ms235654.aspx
And this is a must read:
http://tedwvc.wordpress.com/2009/08/10/avoiding-problems-with-vc2005-sp1-security-update-kb971090/

Most probable is because the embedded manifests. You should take a resource explorer application and check your DLLs for the embedded manifests. It might be that one of the dependent DLLs (or your DLL) require some versions of other DLLs which don't exists.
I got this message: "This application has failed to start because the application configuration is incorrect." in case of embedded manifest mistmatches.

Probably the easiest way to troubleshoot this whole category of problem is to install Process Monitor from microsoft.com.
Process Montior lets you observe the system calls processes are making, and in this case you will be able to see if some system call is failing. For example, if you are lacking a dependency, then a CreateFile() call will be seen failing with a DLL, OCX, etc. as the filename.
Launch procmon and configure the filter to exclude events other than from regsvr32.exe, reproduce your test case, and then check the log. Look for NAME_NOT_FOUND errors in the return value column.

Do you have the C++ Redistributable Package Installed?

There are several things you can try:
try regsvr32 w/ fusion log enabled (fuslogvw.exe - it works for unmanaged dlls as well). This would give you a bit more information than depends on what external dependencies are loaded, where are they loaded from and what errors were hit.
copy the .ocx and its dependencies to the root or a first level folder and try registering from there. I don't remember details, but there was an old problem with registering a COM dll from within too deep of a path.
run regsvr32 under WinDbg. Set a breakpoint DllMain and see if it does anything funky.
If you never break on DllMain in WinDbg, set a breakpoint on module load for your dll and once it's hit, you can either step through LoadLibrary, or just set a generic load library breakpoint and check every dll after that.

Related

CPP DLL CustomAction code is not executing during installation

I have a Basic MSI project,in that I'm calling CPP Custom Action from DLL. But it's failing with following error.
CustomAction returned actual error code 1157 (note this may not
be 100% accurate if translation happened inside sandbox)
When I checked in EventViewer, I got the following error.
DCOM was unable to communicate with the computer using
any of the configured protocols; requested by PID 94c
(C:\Windows\system32\ServerManager.exe)
I'm suspecting it's an issue with DCOM or VC++ redistributables. I enabled the DCOM rules from firewall as well, but still installation is failing with above error. Is this issue because of some corruption of system DLLs? How I can find the root cause and solution for this issue.
1157 is a dependency issue, and one of the easiest ways to get a complete list of dependent Dlls is the get the dependency walker program and run it on your Dll.
http://www.dependencywalker.com/
You might have a dependency on the Universal C runtime, which I believe is separate from the VC++ runtimes. It seems to be a common problem because it varies depending on the OS and what updates have been installed.

LoadLibrary Error 126 dependent on user rights

I have a strange issue, where my application that runs at my place doesn't work somewhere at customers place.
In my application I try to load another dll with LoadLibrary() from within the same folder.
If the application is run as normal user a 126 error is returned. If the same application is started with Admin rights the dll is loaded correctly.
It's hard to diagnose because I cannot reproduce the error at my machine.
Any ideas?
EDIT
OK, it was a dependency: the dll was a Debug-Build and the MSVCP120D.dll and MSVCR120D.dll could not be found. I could tell this by a Process Monitor-Log.
BUT: I have a log as normal user and a log as Admin and in both cases the dependencies cannot be found. Why does LoadLibrary work in case of Admin-rights??
That is ERROR_MOD_NOT_FOUND, which is pretty self-explanatory. Either the DLL you are loading, or one of its dependencies, cannot be found. Perhaps you failed to install the necessary dependencies, e.g. the MSVC runtime. Or perhaps it is something else.
You'll need to do some debugging and investigation. I would start by profiling the DLL load using Dependency Walker.

Using custom DLL with Inno-Setup

I am having trouble getting Inno-Setup to load my DLL.
I have looked at similar posts, but none of the solutions offered in those seem to help.In particular, this post came very close, but does not seem to be quite the same issue.
My installer runs just fine on my test system. My DLL is written in C++, using VS 2010. There is a DEF file. I have been successful using the VS debugger to attach to the installer's thread and step through my code. Everything is good. The release version runs just fine on my test system with no debuggers involved. Setup calls my DLL and it works.
Then I take my installer to a different, pristine system to try it out. Every time, when I launch the installer, it starts off with the usual UAC prompt: "Do you want to allow the following program from an unknown publisher to make changes to this computer?" And I say "Yes." Then I get a beep and an alert that says:
Runtime Error (at -1:0):
Cannot import
dll:<utf8>C:\Users\Logicrat\AppData\Local\Temp\is-4E245\MyDLL.dll
In my setup script I have
[Files]
Source: "MyDLL.dll"; DestDir: "{app}"; Flags : dontcopy
and
function MyFunc(hWnd: Integer; lpText, lpCaption: AnsiString; uType: Cardinal): Integer;
external 'MyFunc#files:MyDLL.dll stdcall setuponly';
According to the Inno documentation, the dontcopy flag is appropriate if the DLL is not needed for uninstall, which it is not.
I suspect the problem lies in designating exactly where the DLL is supposed to be, as I my script calls for it to be in the {app} directory, yet the error message refers to a temp directory. I've tried a number of variations of the script, all with the same results.
Both my development/test system and my pristine target system are Windows 7 (32-bit). I have been banging on this for weeks with no visible progress. Any suggestions will be most welcome.
Problem solved, thanks to the suggestion by TLama about checking dependencies. When I had initially created the new project for my DLL in MS Visual Studio 2010, I had selected the option to "Use MFC in a shared library." That turned out to be the source of the problem, as the DLL itself was then dependent on mfc100u.dll and msvcr100.dll, which were not present on the target system I used to test my installer. I fixed it by changing the project preference to "Use MFC in a static library." That made the DLL larger, but it also made it work. Then, after I first rebuilt the DLL and then rebuilt the installer that used it, everything was fine.
It might have been nice if the error message I got the first time around named the DLL it was looking for instead of the DLL that tried to call the missing one.

MS Visual C++ Runtime Library error on launch - any debugging tricks?

When launching my app, I'm getting the below error dialog. I understand this indicates a problem loading the runtime library. The problem is, I'm not seeing any way to get more specific info. Which library? What was the exact problem it had when loading? etc.. System event viewer doesn't have any entries for it. Are there any tricks to finding out exactly which library it was trying to load when it hit the error and what the specific problem was?
Microsoft Visual C++ Runtime Library
Runtime Error!
Program: exe path
R6034
An application has made an attempt to load the C runtime library incorrectly.
Please contact the application's support team for more information.*
My current approach for dealing with runtime lib dependencies is to scan the install directory, extracting out the embedded manifests for the .dll and .exe files and then generating .config and .2.config files to re-direct to the minor versions of the runtime lib I'm shipping with. In the past this has always gotten things working. Not so in this case.
This might be complicated somewhat by the fact that the calling code is native C++ but some of the DLLs use .NET. I'm calling a C++ API, but under the hood it ends up utilizing some DLLs which themselves use .NET.
Use SysInternals Process Monitor to monitor file system access. Filter on process name and operation (CreateFile) to see what DLLs the process can't locate.
It could indicate a wrong version of msvcr*.dll.
You could try Dependency Walker (http://www.dependencywalker.com/) to find out where it's being linked.
Make sure you have a debug version of the code you're trying to attach to. On the Debug menu, select Attach to Process. Use processID -
Also check this -http://support.microsoft.com/kb/235434
Resolution 1
You should be able to attach to the process using Task Manager:
Enable just-in-time debugging (JIT):
In Visual C++, on the Tools menu, click Options.
On the Debug tab, make sure that Just-in-time debugging is selected.
Run Task Manager and select the process to attach to. Right-click and select Debug.
Resolution 2
Run Task Manager and get the process ID for the process you want to debug.
At a command prompt enter the following:msdev -p
This will start Visual C++ and will attach to the process specified.

C++ Linking and COM Registration issue

I've added a new library to my application (multiple projects-DLLs) - SQLite, to perform some in memory caching. There is just one library/project that is affected by this change - Lib1.
A build goes through fine. All libraries are built successfully and no errors are reported, including a couple of Com Objects.
If I try to register the com objects, I get the The DLL could not be loaded. Check to make sure all required application runtime files and other dependent DLLs are available in the component DLL's directory or the system path. message. But all the libs are at the same place. And all are in the path. A copy of this project builds and registers fine (without the few changes made for SqlLite ofcourse). Dependency walker reports no issues
Oddly, if I try to register the DLL of the com object (using regsvr32) it works fine. Also, I have another library, which is dependant on Lib1 (not on SqlLite) which also cannot be loaded.
Any ideas?
Thanks,
A'z
You can use Process Monitor (http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx) set to filter process name regsvr32.exe in order to see all file and registry access.
Always use full path to your-com-dll when you issue regsvr32 commands, if you have the same dll somewhere else in path (for example c:\windows\system32) regsvr32 will use the other dll and not the one in your current directory.
Another trick would be to use "rundll32 your-com-dll,DllRegisterServer". In case of missing dlls it will tell which dll is missing instead of just saying that LoadLibrary failed.
Edit:
What do you mean by "If I try to register the com objects"? How are you doing this? I'm asking because you say that regsvr32 on the dll which actually implements these com object works fine.
Use the dependency walker tool to figure out what other dlls the COM server relies on. Then check the executable paths that is set in Visual Studio (Tools -> Options -> Projects -> Directories (I think)). Note that VS does not use the system PATH environment variable - it uses what is set in the options page so if the path to the dependencies is not listed there, the registration would fail, even though if you used regsvr32 from the command line it would succeed.
And so, the plot thickens!!!!
I've actually narrowed down the to the line of code that causes this linking problem.
In the modified library (LIB1) I've added a new class A1 which inherits from an existing class A.
When I change an existing class B which used to inherit from A to now inherit from A1 - this is when the problem is caused. Class B is in a lib3.
I've verified that just when I change the inheritance, only then the problem occurs!!!
I've used file-mon on regsvr32 when loading successfully and when failing. I stuggle to find the difference! Tomorrow morning I'll try Process Monitor and see if it helps.
Still desperate for help,
A'z
hmm... as Christian asks, how else are you attempting to register the objects if regsvr32.exe succeeds?
the rundll32.exe advice is also good. have you tried stepping through DllRegisterServer in a debugger to see precisely when it's failing? this sounds like a potential runtime failure if depends.exe isn't revealing anything.
btw, when i google for that exact error text i see: http://social.msdn.microsoft.com/forums/en-US/sqldataaccess/thread/402c1767-cf1d-42f0-aec9-e0169dbf1083/, but I assume you've probably already done this search and found it not helpful :)