PCError

Just another WordPress weblog

Recently, while attempting to build a Japanese MSI using WiX v3.0, I received an error message that looked like the following:

light.exe : error LGHT0217 : An unexpected external UI message was received: ????????????????????????????????????????????????????????????? ???? 2738 ???

I wanted to see the full text of this error message, so I temporarily changed the product language setting in my WXS file from 1041 (the LCID for Japanese) to 1033 (the LCID for English) and re-ran the build. When I did that, the error message was more readable:

light.exe : error LGHT0217 : An unexpected external UI message was received: The installer has encountered an unexpected error installing this package. This may indicate a problem with this package. The error code is 2738.

This message made more sense to me, so from there, I looked at the Windows Installer Error Messages reference for error code 2738 and found the following:

Could not access VBScript run time for custom action [2].

While attempting to narrow down this error further, I found a couple of useful blog posts. As described in this blog post by Heath Stewart, error code 2738 can occur on Windows Vista systems (like the one I was using in the above scenario) if an MSI contains a script-based custom action and the VBScript runtime is registered in the HKEY_CURRENT_USER hive instead of or in addition to the HKEY_LOCAL_MACHINE hive. Also, as described in this blog post by Bob Arnson, four of the Windows Installer Internal Consistency Evaluators (ICEs) are implemented in VBScript. The offending ICEs are ICE08, ICE09, ICE32 and ICE61.

In my build output, I noticed that light.exe had reported some warnings for ICE03 before displaying this 2738 error. From this, I made an educated guess that it was probably failing while running one of these four ICEs. Then, I used some of the advice that I listed in one of my previous blog posts to unregister vbscript.dll and jscript.dll from HKEY_CURRENT_USER to resolve this error:
Click on the Start menu, choose Run, type cmd and click OK
To unregister the VBScript engine, run this command: reg delete “HKCU\SOFTWARE\Classes\CLSID\{B54F3741-5B07-11CF-A4B0-00AA004A55E8}” /f
To unregister the JScript engine, run this command: reg delete “HKCU\SOFTWARE\Classes\CLSID\{F414C260-6AC0-11CF-B6D1-00AA00BBBB58}” /f

Once I did that, my build started working as expected. I still do not know how this information ended up in HKEY_CURRENT_USER on my system, particularly because the same build worked correctly on the same machine a couple of days ago. However, I am now back into a state where I can build successfully, and I know of a possible workaround to try if I end up with similar build issues in the future.

One of the difficult things about programming in Windows, and especially with COM, is that when you receive an error code, it can be difficult to find the message that goes with it. I was writing some new LDAP code today against Active Directory, and got this message:
Couldn’t read LDAP property member: COM exception 0×80005010

What does it mean? The “Couldn’t read LDAP property member” was my text, the 0×80005010 part is the HRESULT. Our error handling code tries to find a text message, but it couldn’t, and so made do with just the hex. I fired up errlook, the Microsoft error code lookup tool, but it couldn’t find a message either. Using DevStudio, I searched all of the include files for “80005010″. It found this section of adserr.h:
//
// MessageId: E_ADS_COLUMN_NOT_SET
//
// MessageText:
//
// The specified column in the directory was not set.
//
#define E_ADS_COLUMN_NOT_SET _HRESULT_TYPEDEF_(0×80005010L)

OK, now I knew what the error meant, and I had a symbol to use in my code if I wanted to handle it specially. But I’d like to display error messages at run time. How can I get that text message automatically? The errlook tool couldn’t find the message, so it was natural that my application couldn’t, but could I look further?

Windows stores error messages in DLLs, and the FormatMessage function can take an explicit module handle to a module containing error messages. My application already has a list of modules it searches when looking for error messages. If I could find the DLL with this message, I could get a nice message next time.

To find the error message, I resorted to the blunt instrument of the command line tool strings. It searches binary files for printable strings. Here I’ve told it to search the entire file (rather than interpret the executable format), look for a minimum string length of 10, print the file name along with each string, and look for little-endian 16-bit characters:
$ cd c:\windows\system32
$ strings -a -n 10 -f -e l *.dll | grep “specified column”
activeds.dll: The specified column in the directory was not set.
$

Aha! ActiveDS.DLL is my guy. I registered it into my application’s search list of error modules, ran the app again, and got a nice error message:
Couldn’t read LDAP property member: COM exception 0×80005010:
The specified column in the directory was not set.

Bliss.

UPDATE - So a few people have asked me what to do when you are running a 64bit version of Windows. I have now updated this to display both!

With last weeks Apple’s WWDC keynote, Steve Jobs announce a public beta of Safari 3, but this time for Windows as well. It was pretty freaky, because just that morning we were looking for ways to check the way WebKit renders HTML on a PC.

When I went to install this on my Windows Vista laptop, I kept getting an error (Number 273 when trying to do the install. Checking around online, it took a few minutes, but I found this KB article on Apple’s site (they have since updated the KB article since I first started this post).

What happens is that on some machines, VBScript isnt registered with the machine correctly.

If you are running a 32-bit version of Windows, running the ‘regsvr32 vbscript.dll’ solves the problem, and you dont have to reboot either.

If you are running a 64-bit version of Windows, you need to run this from a different folder. In a command prompt, do ‘cd \windows\syswow64′, and then run ‘regsvr32 vbscript.dll’.

After running the command, the installer worked perfectly fine, and I got to try out Safari!

I’m going to be conducting a webcast on Windows Error Reporting (WER). Windows Error Reporting is one of those best kept secrets at Microsoft. If you have ever experienced an application crash or hang in Windows, the mechanism to collect and report that data and send it back to Microsoft is WER.

Windows Error Reporting is built into Windows XP and Windows Server 2003. It does not require any special application programming for ISVs to enable its use. Best of all, it is free.

Microsoft has built an entire support infrastructure that it uses to collect application failure information. As an ISV, you can leverage the same infrastructure for your applications to improve customer satisfaction and reduce support costs.

I understand that many computer users find it a trouble to manually type error messages and paste it in forums to get help. For short error message, It’s not too bad. But there are some really long error messages with random error code numbers, location, file names UGH! I’d go mad if I had to type the error messages below.

Why don’t Windows error messages has a button for you to copy all the error messages? Why can’t I simply use my mouse to highlight the error messages in command prompt? Actually there are ways to let you copy the text in windows error message and also in command prompt.

Actually there is! You can easily copy Windows error messages by using the copy shortcut key CTRL+C. Don’t believe? Go to Start > Run, simply type anything at the run box and hit enter. You’ll get an error message that says “Windows cannot find ‘xxxxxxxx’. Make sure you typed the name correctly, and then try again. To search for a file, click the Start button, and then click Search.” Now press CTRL+C simultaneously. Then open up a notepad or any text editor and hit CTRL+V. You should see this being pasted at your text editor.

—————————
xxxxxxx
—————————
Windows cannot find ‘xxxxxxx’. Make sure you typed the name correctly, and then try again. To search for a file, click the Start button, and then click Search.
—————————
OK
—————————

Unfortunately this method doesn’t copy ALL error messages. Only windows error messages.

As for how to copy and paste in command prompt or DOS window, there are 2 ways to do it.
1. Right click at anywhere at the command prompt, and select Mark.

You can now use your mouse left click to mark the area that you want to copy. Once you have selected the text you want to copy, then use the right mouse button or the Enter key to copy the selected text to the clipboard. To paste, right click and select Paste.

2. Right click at command prompt titlebar and select Properties.

At options tab, check or enable QuickEdit Mode.

Click OK. You can now easily mark the text that you want in command prompt and then to copy the text, right click your mouse OR hit the enter key. To paste, right click your mouse.

Now you know how to copy error messages from windows and command prompt. Please make sure you include the exact error messages that you get from your computer in forum when posting a problem. It enables us to understand better what is the problem with your computer.

Welcome to WordPress. This is your first post. Edit or delete it, then start blogging!