Solved

Delay-Load Dll Not Being Found During XP Install

Posted on 2010-11-22
21
800 Views
Last Modified: 2012-06-27
I have an MSI installation with a deferred custom action that is written in a dll (called CustomAction.dll) which gets installed in the same program folder as the main application. CustomAction.dll relies on a third-party dll (called ThirdParty.dll) which ALSO gets installed in the same folder as the application. The third-party dll is linked with a delay-load setting so that it doesn't get loaded until it is needed. Because the custom action doesn't get invoked until AFTER all of the files have been copied into the application folder, the system normally has no problems loading the dependent dlls. It simply searches the various paths for ThirdParty.dll according to the rules outlined here:

  http://msdn.microsoft.com/en-us/library/ms682586(VS.85).aspx

I have used this installer on countless systems (XP, Vista, W7) without a problem. Now, I have one Windows XP Home computer on which the installer is not working. After a lot of diagnostic work I've determined the following:
 - The custom action is triggering exception code 0xC06D007E (which indicates a delay-load failure) at the time it tries to utilitize the functionality in the third-party dll.
 - At the time of the error, both CustomAction.dll and ThirdParty.dll are in the same application folder.
 - A walk-through of the dll dependencies with depends.exe on the target system at the time of the error shows nothing missing or problematic. (A couple of delay-load dlls used by Vista are missing, but that is to be expected since the OS is XP.)
 - There do not appear to be any file permission problems with any of the dlls.
 - A log of all of the activities of msiexec.exe with ProcessMonitor.exe shows that the system attempts to load ThirdParty.dll from a number of paths, NONE of which are the original path from which CustomAction.dll was loaded.

This is the only system on which I've ever seen this behavior. Incidentally, this system had other problems including a corrupt installation of MSXML6 which required correction in order to successfully install SQL Server 2005 Express. Furthermore, when I attemtped to install LogMeIn on this machine so that I could do some remote troubleshooting later on, that installation also failed. However, I was able to successfully install GoToMyPC. So I suspect that my problem is due to something being corrupt or misconfigured with the system. But I don't have a clue what kind of problem would cause the path search mechanism to ignore the directory from which CustomAction.dll loaded when looking for ThirdParty.dll.

Any ideas?

-- Daryl Shockey
0
Comment
Question by:dshockey
21 Comments
 
LVL 40

Expert Comment

by:Vadim Rapp
ID: 34196550
Have you checked the exceptions from the link that you provided? Namely KnownDLLs , SafeDllSearchMode  , also possibly SetDllDirectory that might be issued by the calling DLL in some special circumstances.

Also, I would check the version of Installer itself.

Also, when both dll's are already in the folder, what if you try the same "manually".
0
 
LVL 47

Expert Comment

by:dbrunton
ID: 34199298
Wild suggestion

What happens if you drop both DLLs into the Windows folder?  I mean surely that would have to be searched.
0
 
LVL 1

Author Comment

by:dshockey
ID: 34222603
Thanks for the suggestions. None of the exceptions detailed in the Microsoft link apply to this installer. Specifically, there are no calls to SetDllDirectory and the dll is not being loaded with the LOAD_WITH_ALTERED_SEARCH_PATH flag. Therefore, only the "Standard Search Order" would apply. In this mode, both with and without SafeDllSearchMode enabled, the first place that the system looks is the directory from which the application loaded. Since CustomAction.dll and ThirdParty.dll are in the same folder, this is where the system should find ThirdParty.dll.

I was able to get the installer to work on the problem computer by including the installation location of the application in the PATH variable prior to running the installation. However, I still don't know why this was necessary on just this one computer.

I don't know the version of the Windows Installer, but I can find out on Monday. However, should that make any difference in this operation?
0
 
LVL 40

Expert Comment

by:Vadim Rapp
ID: 34227349
KnownDLLs and SafeDllSearchMode apply not to installation but to the target system.


Note also that "directory from where application is launched" can be windows\system32, since "the application" is msiexec.exe, strictly speaking.

> should that make any difference in this operation?

if we knew for sure what has made the difference, there would be not question...
0
 
LVL 40

Expert Comment

by:Vadim Rapp
ID: 34227357
would be not question... -> would be no question...
0
 
LVL 1

Author Comment

by:dshockey
ID: 34235689
I have two important updates.

First, I noticed something that I had failed to report earlier. In the custom action (which is written in C++) within the original dll (CustomAction.dll), it sets the current directory to be the install location via a call to SetCurrentDirectory(...) prior to utilizing the third party API. This means that ThirdParty.dll should be located by virtue of existing in the CURRENT directory, NOT the directory from which the application loaded. (As pointed out earlier, the original application directory would be windows\system32 where msiexec.exe is located.

I have a pseudocode example attached here.

Second, I added better error reporting and subsequently got a report from somebody who downloaded my software and experienced the same error.

I have conducted numerous tests both before this error was discovered and in the past few days. I have not been able to reproduce this error on any of my computers. (I've even done tests of virgin computers with nothing but a fresh install of Windows XP with service pack 3.) As I noted earlier, I got the installation to work on the original computer that was experiencing this problem by adding the install location to the system path. So I can no longer test on that computer. I don't have access to the other computer that has experienced the problem.

Apparently this problem has the potential to show anywhere and I don't know how to troubleshoot or fix it since I can't recreate it.

Any help here is GREATLY appreciated. Thank you!

-- Daryl Shockey
TCHAR szOrig[512];

GetCurrentDirectory(sizeof(szOrig) / sizeof(TCHAR), szOrig);

SetCurrentDirectory(INSTALLDIR);



ThirdPartyFunction();  // <-- Exception from Delay Load Error!



SetCurrentDirectory(szOrig);

Open in new window

0
 
LVL 40

Expert Comment

by:Vadim Rapp
ID: 34236238
1. you still don't say if you checked KnownDLLs and SafeDllSearchMode, and Installer's version.

Further ideas:

2. if the code is indeed using property INSTALLDIR, note that deferred custom action does not have access to it.

3. deferred custom action can run outside of user's security context.

> I got the installation to work on the original computer that was experiencing this problem by adding the install location to the system path. So I can no longer test on that computer

Can't you remove installation directory from the path and have the problem back, for the sake of testing?
0
 
LVL 1

Author Comment

by:dshockey
ID: 34243429
1.) The Windows Installer version is 4.5.6001 with a platform ID of 2. I'm still looking into the KnownDLLs hive as well as SafeDllSearchMode. However, based on the documentation, I don't see how either of these things would cause the OS to not look in the current directory for a delay-loaded dll.

2.) The code doesn't reference INSTALLDIR directly because, as you pointed out, it's not accessible to a deferred custom action. Instead, the value of INSTALLDIR is written to the custom action's default property  during the earlier processing of one of the immediate custom actions. This enables the deferred custom action to later reference the information via its default property.

3.) If the problem was security-related, shouldn't the attempt to load the dll from the appropriate folder have shown up in the ProcessMonitor logs?

I'd love to remove the installation directory from the path and resume testing. However, the installation has already been completed and the computer on which this error occurred (which prompted this inquiry) is now making use of my software. So I can't just go in and take off all the software in order to test the installer.

When I first got around the problem, I thought it was a one-time error caused by a corrupt or misconfigured system. However, having now learned of a second instance on a computer that I can't access, I have to assume that this is a problem with my installer that could show up at any time. However, I've not yet been able to recreate it on any of my computers.

So.... the search continues. (THANK YOU for your help thus far!...)

-- Daryl Shockey
0
 
LVL 40

Expert Comment

by:Vadim Rapp
ID: 34243937
advice: don't concentrate on how it should work; assume that this is a bug, undocumented feature, mystery, etc., and concentrate on finding what's unique for this machine, possibly against all logic. There must be something unique. If possible, make full backup of the machine, restore it to your testing machine (virtual?) and reproduce.
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 1

Author Comment

by:dshockey
ID: 34253721
I have FINALLY been able to recreate the problem on my test computer! The problem is related to the version of Windows Installer that is running. The error occurs with Installer version 4.5.6001.

When I run the installer on an XP system with Windows Installer version 3.1..4001, I have no problems. When I run the same installer on the same system after upgrading the Installer to v. 4.5.6001, I get the delay-load failure exception.

I've also tightened up the code within the custom action to verify that the current directory modification is successful (and it is successful) before attempting to invoke the third party function.

So, does anybody know what changed with version 4.5(.6001) of the Windows Installer that would cause a problem like this? I've tried googling various keywords related to this issue to no avail.

-- Daryl Shockey
TCHAR szOrig[512];

if ((!GetCurrentDirectory(sizeof(szOrig) / sizeof(TCHAR), szOrig)

    || (!SetCurrentDirectory(INSTALLDIR)))

  return ERROR_INSTALL_FAILURE;



ThirdPartyFunction();  // <-- Exception from Delay Load Error with Installer v. 4.5.6001!



SetCurrentDirectory(szOrig);

Open in new window

0
 
LVL 40

Expert Comment

by:Vadim Rapp
ID: 34254572
At this point, your only option is to open paid support incident with Microsoft. If you have demonstrated that this did not happen with Installer 3.1 but does happen with Installer 4.5, then it's a bug only Microsoft can fix. Once they confirm it, they will refund the $99 support fee.

The following will help:

1. create sample project with the very minimum of files, that will still demonstrate the problem. Better yet, create also sample thirdparty.dll.
2. modify your customaction.dll so that before calling thirdpartydll it writes to the log, or shows the message, what is the current directory, to be 100% sure that the directory with thirdparty.dll is indeed the current directory at the time when it's called.
3. verify that this is happening in Windows 7 (thus Installer 5), and open the incident against Windows 7. The more current is Windows where this is happening, the more inclined Microsoft will be to fix it.
4. when the result of #1 above is ready, upload it here so I verify myself, before opening the incident.

0
 
LVL 1

Author Comment

by:dshockey
ID: 34263238
Well, some frustrating news.

#1.) The problem occurs only on XP with installer 4.5. It does NOT happen with an earlier version of the installer, nor does it happen on Vista or Windows 7 running installer 5.

#2.) I have added lots of debugging code to the custom action dll to ensure that the current directory is properly set. I even make a call to GetCurrentDirectory(...) and show the result prior to using the third party API. Furthermore, when I tried to load the dll manually via a call to LoadLibrary(...), I got a last-error code of 0x7E (ERROR_MOD_NOT_FOUND) indicating that the module could not be found. Again, I used debug message dialogs to ensure that my string values were all correct and to give me the opportunity to manually verify that the files were indeed where they ought to be.

#3.) When I attempted to create a simple test installer that did the same thing, I got no error.

So all I have is the original MSI with which the error is occurring. Given all of the debug messages that I've used, coupled with the fact that it works on older AND newer installers, I tend to think that this is a bug with version 4.5 of the Windows installer. However, I don't know what underlying issue is causing it and how to get around it. (Rearrange the order of events perhaps?)

I'm sure it's within the capabilities of the folks at Microsoft to analyze the MSI and determine whether or not the failure is because of their system. However, when I went to the Microsoft Support site, I couldn't even find what product an issue like this would be opened under.

Help? Ideas?

-- Daryl Shockey
0
 
LVL 40

Accepted Solution

by:
Vadim Rapp earned 500 total points
ID: 34266167
when I went to the Microsoft Support site, I couldn't even find what product an issue like this would be opened under.

Windows.

when I attempted to create a simple test installer that did the same thing, I got no error.

This is probably the most important fact, and removes Microsoft support from the options.

When such thing happens, the tried method is start removing things from the MSI with the problem, until the problem disappears. Any custom actions, files, everything that makes the difference between the sample MSI and the real one.
0
 
LVL 1

Author Comment

by:dshockey
ID: 34273820
I've found the cause of the issue. My software utilizes an instance of Microsoft SQL Server 2005 Express (with SP3) which it installs via a custom action during the installation UI sequence (prior to the execution sequence).

Running the SQL Server installation during the UI sequence subsequently leads to the delay-load failure in the deferred custom action during the execution sequence. I've tried virtually everything else, and nothing else makes a difference with this error. When the SQL Server installation occurs, the delay-load error always occurs. When the SQL Server installation does not occur, the delay-load error never occurs.

So, I still think this is a demonstrable bug in version 4.5 of the Windows Installer. (Bear in mind, it does not occur with earlier AND later versions of Windows Installer.) I'm currently working on a simple installation projection that will install SQL Server during the UI sequence, then carry out a deferred custom action with a delay-load dependency during the execution sequence.

If I can recreate the error in this project, I will have eliminated all other variables.

My question is, would Microsoft be willing to look at and fix this? (An MSI file is basically a series of attached files and tables directing the Windows Installer in what to do.) Or would they bluntly say that they don't support fixes for SQL Server 2005 on Windows XP and tell me to use SQL Server 2008?

I'm using SQL Server 2005 at this time because I don't want to drop support for Windows 2000, and I would have to do that if I moved to SQL Server 2008.

As an aside, the installer for SQL Server 2005 has been the bane of my existence on previous occasions. I first learned that attempting to install SQL Server with the command line arguments from the original executable led to miscellaneous errors for which there was no fix. Many others had experienced this and found there was no ultimate solution. The workaround was to first extract the installer and then run setup with command line arguments from the extraction folder. (Which of course necessitated cleaning up the extraction folder after setup.) I then learned from testing that if you install SQL Server 2005 Express Edition SP3 on a 64 bit computer with Vista service pack 1, the system encounters an error immediately after installation when starting the main service that leads to an infinite cycle of system reboots. Uninstalling SQL Server would not fix it either. You had to wipe the drive and reinstall the OS.

-- Daryl Shockey
0
 
LVL 40

Expert Comment

by:Vadim Rapp
ID: 34273894
If you send me your installation (the best would be to create a sample one, with one dummy file and that sql server installation), I can send a bug to Microsoft SQL Server team, and they will look. They usually reply within a week, and very competently. (and it's exactly basing on their answers I still stay with sql server 2000 ;-)

Would be even better if you actually tried the same with SQL Server 2008, and had the same problem.

Microsoft itself, as well as many other vendors, don't have a problem to have the installation checking for prerequisites, and then saying something like "sql server express (or .net framework, or...)  not found; please go to <url>, download and install, then repeat this installation". On the other hand, historically, the attempts to pack many installations in one package usually result in later writing multi-page articles "How to Uninstall" and busy support. Visual Studio, the same SQL Server, and many others are examples.

Installer 4.5+ supports installation transactions, i.e. several independent installations can be run as one transaction. It's another option that is probably better than wrapping everything in one installer.

Finally, yet another (probably very distant) option would be to use Microsoft Access, i.e. Jet database.

0
 
LVL 1

Author Comment

by:dshockey
ID: 34306612
Hi vadimrapp1! First of all, thank you so much for your help and efforts in resolving this issue.

Over the weekend I figured out a trick to get around the issue for now. I simply made the custom action copy the third party dlls into the system32 folder before using the required APIs. It then deletes the copied files upon completion.

However, I am still working on getting a simple demonstration installer with which you could show the problem to the folks at Microsoft. (including all source code)

Once I have this completed, how should I contact you?

-- Daryl Shockey
0
 
LVL 40

Expert Comment

by:Vadim Rapp
ID: 34307104
>  how should I contact you?

start by clicking on my name here, or search on google (w/o 1 in the end)
0
 
LVL 40

Expert Comment

by:Vadim Rapp
ID: 34464183
Accept http:#34266167 - the author followed the recommendation to remove everything extra, and found that the problem was created by nested SQL Server installation, in combination with Windows Installer 4.5 .
0
 
LVL 53

Expert Comment

by:Dhaest
ID: 34618141
This question has been classified as abandoned and is being closed as part of the Cleanup Program.  See my comment at the end of the question for more details.
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Suggested Solutions

A short article about a problem I had getting the GPS LocationListener working.
Entering a date in Microsoft Access can be tricky. A typo can cause month and day to be shuffled, entering the day only causes an error, as does entering, say, day 31 in June. This article shows how an inputmask supported by code can help the user a…
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

25 Experts available now in Live!

Get 1:1 Help Now