Debugging Custom Actions
You can debug custom actions that are based on dynamic-link libraries by using Debugging Tools for Windows. It is not possible to use dynamic debugging with custom actions based on executable files or scripts.
The techniques described in this section can help you debug Windows Installer custom actions. See the Driver Development Tools section of the Windows Driver Kit (WDK) for information about Debugging Tools for Windows.
Windows Installer uses the MsiBreak environment variable to determine which custom action is to be debugged. If you have access to the custom action's source code, you may be able to use debugging without MsiBreak. To start debugging without MsiBreak, put a temporary message box at the beginning of the action's code. When the message box appears during the installation, attach the debugger to the process owning the message box. You can then set any necessary breakpoints and dismiss the message box to resume execution. It is not possible to debug the earlier portions of the custom action by this method.
To use the MsiBreak environment variable to debug the custom action, set MsiBreak to the custom action's name in the CustomAction table. MsiBreak can be either a system or a user environment variable. If the variable is set as a system variable, a restart of the system may be needed when the value is changed to detect the new value.
To use the MsiBreak environment variable to debug an embedded user interface, set the value of MsiBreak to MsiEmbeddedUI.
Windows Installer only checks the MsiBreak environment variable if the user is an Administrator. The installer ignores the value of MsiBreak if the user is not an Administrator, even if this is a managed application.
If you are debugging a custom action that runs with elevated (system) privileges in the execution sequence, attach the debugger to the Windows Installer service. When debugging a custom action that runs with impersonated privileges in the execution sequence, the system prompts with a dialog box that indicates which process should be debugged. The user is prompted with a dialog box indicating which process to debug. For more information about elevated custom actions, see Custom Action Security.
Once the debugger has been attached to the correct process, the installer triggers a debugger breakpoint immediately before calling the entry point of the DLL. At the breakpoint, your DLL is already loaded into the process and the entry point address determined. If your custom action DLL could not be loaded or the custom action entry point did not exist, no breakpoint is triggered. Because the breakpoint is triggered before calling the DLL function, once the breakpoint has been triggered you should use your debugger to step forward until your custom action entry point is called. Alternately, you can set a breakpoint anywhere in your custom action and resume normal execution.
The Windows Installer executes DLLs not stored in the Binary table directly from the DLL location. The installer does not know the original name of a DLL stored in the Binary table and runs the DLL custom action under a temporary file name. The form of the temporary file name is MSI?????.TMP. On Windows 2000 or Windows XP this temporary file is stored in a secure location, commonly <WindowFolder>\Installer.
Note that many DLLs created for debugging contain the name and path of the corresponding PDB file as part of the DLL itself. When debugging this type of DLL on a system where the PDB can be found at the location stored in the DLL, symbols may be loaded automatically by the debugger tool. In situations where the PDB cannot be found at the stored location, where the debugger does not support loading symbols from the stored location, or where the DLL was not built with debugging information, you may need to place your symbol files in the folder with the temporary DLL file.
The installer adds debugging information for custom action scripts to the installation log file.
There is a problem with this Windows Installer package. A script
required for this install to complete could not be run. Contact your
support personnel or package vendor. {Custom action [2] script error
[3], [4]: [5] Line [6], Column [7], [8] }
Send comments about this topic to Microsoft
Build date: 2/3/2012
- 10/1/2010
- Trancified
http://msdn.microsoft.com/en-us/library/kz0ke5xt(VS.80).aspx
See "How do I debug a custom action/installer class?"
· Add a call in your code to System.Diagnostics.Debugger.Launch. This method opens Just-In-Time debugging and allows you to attach a new debugger to your code.
· Add a call in your code to MessageBox.Show("Debug Me"). When the message box appears, use Visual Studio to attach to the MessageBox process. Then place breaks (for Visual C# projects) or stops (for Visual Basic projects) in the code.
· Set your debugging preferences to start InstallUtil.exe (which is located in \winnt\Microsoft.net\Framework\version) and pass it your assembly as a parameter. When you press F5, you hit your breakpoint. InstallUtil.exe will run your custom actions in the same way that MSI does.
Here's a blog posting "How To Read A Windows Installer Verbose Log"
http://blogs.technet.com/b/paulpaa/archive/2010/02/05/how-to-read-a-windows-installer-verbose-log.aspx
Here's some things I've discovered and solutions to errors or problems I've had...
The Visual Studio Setup & Deployment Projects are finicky beasts. If you have problems, try some of these workarounds:
- Close any extraneous VS windows and files, especially for S&D projects.
- Change the Configuration Manager and only try to build in "Release" mode.
- Check to see if you are trying to mix deployment of X64 & X32 assemblies.
- Delete any temporary files in the Setup subfolders.
“An error occurred while validating. HRESULT = ‘80004005’”
If you get an error similar to this while building a Setup project it is most likely due to a missing dependency in one of the projects that output is included for (don’t ask why the error doesn’t occur in THAT project…it compiles fine). Simply open the project/solution and fix/remove the bad references and build this step again.
“WARNING: Two or more objects have the same target location…”
If you get this warning when building a setup project the problem may be the following.
During setup, it appears that files to be installed to the GAC are uncompressed into a random temp folder under the Assembly folder
("C:\WINDOWS\assembly\tmp\Z01Q3ST6\<assembly_name>.dll").
Obviously, if there are multiple files in the setup package with the same name it can't uncompress both to the same folder and it throws an error
("Error writing to file" "Verify that you have access to that directory").
The problem occurs when a solution contains multiple projects where one or more projects contain references to each other. Each of the projects containing references to others ALSO include the output from the referenced projects in their project output.
Example:
Solution1
- Library_A
- Library_B - References Library_A
- Setup - Includes Project Output for both A & B
So, although the Setup already contains the Project Output for Library_A and Library_B projects, because Library_B contains a reference to Library_A, it's Project Output will ALSO add another instance of Library_A.dll to the Setup package. The solution is to edit the Project Output Properties for Library_B and add
"Library_A.dll" to the "ExcludeFilter".
"ERROR: Unrecoverable build error"
http://support.microsoft.com/kb/329214
Typically, this problem occurs because of one of the following:
· In the Visual Studio .NET development environment, you have multiple open windows.
· In your Visual Studio .NET project, multiple folders have the same name.
· Some interface registrations are missing from the registry.
· In the registry, Mergemod.dll is not registered or an incomplete version of Mergemod.dll is registered.
If you get an error like this “Could not load file or assembly…” during an installation that uses a Custom Action the problem may be related to any parameters passed into the custom action via the “CustomActionData” property. If a “\” is put in the wrong place it can cause a double-quote to be escaped. This can easily happen if you are unsure whether the data expanded from a property/name such as [TargetDir] ends in a “\” already or not. For instance if you pass /TargetPath="[TargetDir]\ (note the trailing “\” this error may occur, but removing the trailing slash like this "/TargetPath="[TargetDir]" will work. Unfortunately, it just takes experience and some trial and error.
- 8/17/2010
- emc3