Friday, December 29, 2006

STLport on Visual Studio 2005

As part of my effort to port to VS2005, I updated to the latest version of STLport, 5.1.0. I've now reconsidered this and have switched to the STL built into VS2005. Here's why.

Years ago, when I initially switched from MFC collection classes to STL, I ran into one big problem - STL didn't have any debugging code to check iterators or array bounds. This caused random mysterious failures in the field in my first product that used STL when I didn't understand that certain operations invalidated iterators. I spent months working the problems out of that product. As part of that effort, I switched to STLport, which was much more robust than the STL implementation in Visual C++ 6.0 and STLport had debugging code in it to trap invalidated iterators, invalid array bounds, and other such programming errors.

The version of STL that ships with VS2005 benefits from Microsoft's security push and has had code added to check for problems like invalid array bounds. The VS2005 STL also has extensive debugging code that goes away in the release build. So my original need for STLport has ended. Even so, since my code was already thoroughly tested with STLport, I thought it best not to switch.

Today I was enduring my normal frustrations trying to debug an STLport set, which is effectively impossible to view in the debugger. I had the same problem with STL collection classes in VC6. Then I discovered that the VS2005 debugger actually understands the version of STL that ships with VS2005 and will automatically display the elements in collection classes such as set and vector. This is a huge timesaver and was enough justification for me to drop STLport.

Update 12/18/2007: A set of debugger visualizers has been published for STLport. Go to this link.

Sunday, December 24, 2006

ReadyBoost Problems

I've had to disable ReadyBoost on my system. I've been using the Apacer HT202 Handy Steno 1GB drive, which at a 200x transfer rate is supposed to be one of the best drives on the market for ReadyBoost. I've run this configuration for two weeks now and have consistently run into the same problem. After using the system for several hours with dozens of windows open, the thumb drive hangs. It's not clear whether the drive itself hangs or whether it's a driver issue, but Vista is not able to recover. Explorer hangs, the DOS prompt hangs - anything that tries to access the drive locks up and can't be killed in Task Manager.

A hardware reset brings the system back to normal, except now the RAID array is unhappy because it's been interrupted and it takes two hours to validate the mirror, during which time the system is unusable. (Intel ICH8R chipset on a P5b Deluxe WiFi motherboard.)

Hopefully a solution will present itself after Vista is released to consumers.

Saturday, December 23, 2006

The Windows SDK

If you want to use many of the new features in Windows Vista, you'll need to load the latest Platform SDK. Except it's no longer called the Platform SDK, it's now called the Windows SDK. You can find it at:

http://www.microsoft.com/downloads/details.aspx?familyid=7614FE22-8A64-4DFB-AA0C-DB53035F40A0&displaylang=en

This link points to the final release. Make sure you don't download one of the Release Candidates instead.

Using the latest SDK is a bit of a challenge. It's an all-or-nothing proposition because of new security tags that have been added. Once you've installed the SDK (1.2GB!!) you'll need to update Visual Studio 2005 to make it work. Go to Tools / Options / Projects and Solutions / VC++ directories and add the following:
  • Add C:\Program Files\Microsoft SDKs\Windows\v6.0\bin to the list of directories for Executable files. The new entry should be above ALL of the VCInstallDir entries.
  • Add C:\Program Files\Microsoft SDKs\Windows\v6.0\include to the list of directories for Include files. The new entry should be above $(VCInstallDir)PlatformSDK\include.
  • Add C:\Program Files\Microsoft SDKs\Windows\v6.0\lib to the list of directories for Library files. The new entry should be above $(VCInstallDir)PlatformSDK\lib.

I also use STLport and the Boost library. I put the STLport and Boost directories at the top of the list. I then had to add #undef __in_range before including any STL files in order to make STLport build with the new SDK.

Finally, if you run into an error such as this one:

C:\Program Files\Microsoft SDKs\Windows\v6.0\Include\unknwn.idl(108) : error MIDL2025 : syntax error : expecting ] or , near "annotation"

This error is caused by using the Visual Studio 2005 MIDL compiler instead of the Windows SDK midl compiler. The Windows SDK midl compiler is thirteen months newer. The fix is to add the SDK bin directory to the list of directories as described above. Thanks to Mike Wasson for describing this fix in this article.

(Revised 12/27/2006)

Friday, December 22, 2006

Visual Studio Debugger Hangs

Ever since I first tried to run our software under Visual Studio 2003, I've had trouble with the debugger and the debuggee freezing solid. This problem cropped up again today in Visual Studio 2005. I knew the problem was something to do with the symbol server, but that was all I knew. Fortunately, the developer of VirtualDub has pinpointed the causes. You can find his discussion at:

http://www.virtualdub.org/blog/pivot/entry.php?id=118

The easiest solution to the second problem in the article is to "seed the cache." Visual Studio shows in its status bar (at the bottom) which DLL is being processed. In your application startup code you need to call LoadLibrary for each DLL that causes a hang, as shown in that status bar. This will force Visual Studio to download the symbols over the Internet while the process is in a "safe" state.

In my case, on a Windows Vista RTM system, I placed the following code in InitInstance() before any network calls were made:

LoadLibrary("SENSAPI.DLL");
LoadLibrary("SCHANNEL.DLL");
LoadLibrary("CREDSSP.DLL");
LoadLibrary("RASAPI32.DLL");


Note that these aren't all of the DLLs, just the DLLs at the top of the dependency hierarchy. The dependent DLLs will be loaded automatically. It's not a bad idea to just leave this code in your debug build because the problem will recur as soon as any of those DLLs are updated in a service pack. Make sure you add the related "FreeLibrary" calls if you do this.

Thursday, December 21, 2006

Parallel Builds - Success!

I've given up on the parallel build facility in VCBUILD (the /M option, such as /M2). It is almost useless for our build scenario. Instead I've switched to GNU make from the "cygwin" project. GNU make supports the -j command line parameter to enable parallel builds. GNU make also allows me to specify dependencies at whatever granularity level I need. Currently I specify dependencies on a per-project basis (one project = one .vcproj file), but I could just as easily go one level deeper and have multiple dependencies for each project, such as Debug/Release/Demo.

My makefile looks something like this (simplified for demonstration purposes):

all: sdk gui server

sdk:
vcbuild c:/proj/sdk/sdk.vcproj

gui: core
vcbuild c:/proj/gui/gui.vcproj

server: core
vcbuild c:/proj/svr/svr.vcproj

core:
vcbuild c:/proj/core/core.vcproj


This makefile is launched by a batch file that sets two very important environment variables:

set SolutionPath=c:\proj\proj.sln
set VCBUILD_DEFAULT_OPTIONS=/M1

By setting the "SolutionPath" environment variable to the solution file, we give VCBUILD the ability to set the $(SolutionDir) variable in the build scripts, which is typically required to build successfully.

When you point VCBUILD at a vcproj file, it automatically builds all configurations in that file. This way the makefile doesn't need to have knowledge of all the possible configurations. One feature you give up by specifying the vcproj file is that VCBUILD won't automatically add dependent libraries to the link line. For Visual Studio, this isn't a loss because the feature is largely broken anyway.

Using GNU make gives me the control that I need to keep my dual core processor busy. I'm finally happy :-)

Monday, December 18, 2006

Parallel Builds

One of the features in Visual Studio 2005 that I was most looking forward to was the ability to do parallel builds such that both cores in the Dual Core processor are used. So far this has been a complete bust.

Problem #1: Visual Studio wants to build based on Configurations instead of Projects. This means that you can't build a Release version of a project at the same time you build a Debug version.
Problem #2: Visual Studio will only build one Configuration at a time. This means that you can't create a build of one product while another product is in progress.
Problem #3: The meaning of Problem #1 and Problem #2 is that Visual Studio is optimized to build solutions that are based on many projects. This is typical for a C# application, but somewhat atypical for a C++ application. Our build hierarchy is wide and shallow, which means that Visual Studio's parallel build mechanism is almost useless.

I also tried to create a fake configuration that included all projects. This solution didn't work either because many library dependencies are generated based on the configuration, and this information is lost with an all-at-once Configuration.

Sunday, December 17, 2006

VS2005 SP1 Released

Service Pack 1 for Visual Studio 2005 was released on December 14. I thought this would cure my VS2005 Vista-related issues, but now Microsoft is saying that there is going to be a service pack for the service pack that will address Vista compatibility. This update will be called the "Visual Studio 2005 SP1 Update for Windows Vista" and isn't expected to be available until February or March.

Here are links for SP1 for VS2005:

Wednesday, December 13, 2006

Certified for Windows Vista

I'm reworking our software to pass the "Certified for Windows Vista" Test Cases. You can get this lengthy document from:

http://download.microsoft.com/download/8/e/4/8e4c929d-679a-4238-8c21-2dcc8ed1f35c/Windows%20Vista%20Software%20Logo%20Spec%201.1.doc

Even if you don't go for the logo, it's worth reading this document. There are a lot of changes in Vista that affect client application development and you're in for many technical support headaches if you don't plan for them.

One of the logo requirements is to use an MSI-based installer. This was a big change for us. We've historically used a minimalist custom installer because our entire application was a single statically linked executable that was 500KB. I searched everywhere for an MSI-based install generator that didn't add 1.5MB of overhead. We couldn't use the VS2005-based installer because we needed a wrapper that could handle dependency installation (such as installing the MSI installer) because we still support Windows 98.

We decided to use Advanced Installer from Caphyon. It does everything we need, is reasonably priced, and has decent technical support. Yesterday Caphyon released version 4.6 which adds several features for Vista logo requirements. I've now been using Advanced Installer for six months and I've been very happy with the choice.

Tuesday, December 12, 2006

Alt-Tab on Vista

Call me a gadfly, but does anyone else find the Alt-Tab functionality in Vista to be almost useless? Almost all of my windows are text, which means that they all look very much alike when they are shrunk down. In addition, the selection rectangle as you cycle through the windows is just a faint outline with the same interior color as everything else, so it's very difficult to see the current selection. Since I routinely keep 20+ windows open, changing between windows has become very painful.

I was delighted to find that you can tell Vista to revert to the Windows XP style window cycling:
http://www.mattbrindley.com/developing/windows/windows-vista-win-tab-alt-tab/

The short summary is to create a DWORD called "AltTabSettings" in \HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer and set it to 1.

This feature doesn't appear to be documented by Microsoft.

Monday, December 11, 2006

Code Signing with SIGNTOOL

Part of our automated build system is to digitally sign our applications with our company's Verisign code signing certificate. Predictably, the signcode command failed under Vista.

First, a little history. Originally we signed our application like this:

signcode /spc C:mycredencials.spc /v a:myprivatekey.pvk /t http://timestamp.verisign.com/scripts/timstamp.dll c:\Project1.exe

The problem is that it required us to enter a password in a dialog box every time this command was run. Since we built several applications at a time, our "automated" build process required a lot of manual intervention.

The solution to that problem was to embed the key in the registry using PVKIMPRT. This was always painful because PVKIMPRT had some issues on Windows XP, so you had to use Windows 2000 or Windows 98 to import and export the certificate into a usable format. [Update 7/25/2008 - The problem was originally caused because the key was generated on Windows 2000. This is no longer true, so you can now safely use PVKIMPRT on Windows XP.]

The command line for signcode that directly accessed the certificate store was:

signcode -cn "Cool Corp" -n "My Application" -i http://www.example.com/MyApp.html -t http://timestamp.verisign.com/scripts/timstamp.dll c:\Project1.exe

This worked well on Windows XP, but failed on Vista with the error "failed to build the certificate chain." [Update 7/25/2008 - This problem was probably caused because the intermediate key was not installed. See my later post.]

Recent discussions about codesigning seem to advocate using signtool instead of signcode, although there's no discussion about the difference. I found that signtool has one big advantage over signcode: it can read PFX files, which is what Internet Explorer exports (Control Panel / Internet Options / Content / Certificates / Export). However, if you export your certificate to a PFX file in Windows Vista, you are required to provide a password, which didn't play well with one of our automated build tools.

The first solution was to use Windows XP to create the PFX file instead of Vista. WinXP will allow you to export your certificate and private key to a PFX file without a password. However, I found a better solution with a little research.

Signtool can automatically select a code signing certificate from the registry with the /a option. That's very handy. Eventually I ended up with this command in the Post Build Event:

$(SolutionDir)Tools\SignTool sign /a /d "My Application" /du "http://www.example.com/MyApp.html" /t http://timestamp.verisign.com/scripts/timstamp.dll $(TargetPath)

Saturday, December 9, 2006

Developing on Vista (or not)

I've run into an unexpected problem. Visual Studio 2005 is only supported on Windows Vista with VS2005 Service Pack 1. This shouldn't be a problem, except that SP1 is still in Beta and isn't released yet. This means that there is no production development environment that's certified to run on Vista right now.

I installed SP1 beta with some difficulty. The installer would get 90% of the way finished, then back out all changes with no error. After two hours I found a note that said you had to use "Run as Administrator" when running the installing the service pack. An error message would have been nice.

The good news is VS2005 runs well on the new hardware (Core 2 Duo E6600 with 2GB RAM.) There are still some rough spots performance-wise, but they are annoyances as opposed to productivity killers.

Friday, December 8, 2006

Visual Studio on Vista

Now that Windows Vista is RTM, I have bought a Core 2 Duo system, installed Vista, and am converting my development environment over to Vista. The performance of my Windows XP box has significantly degraded over the past year despite aggressive efforts at removing unnecessary processes. With SuperFetch and ReadyBoost, I'm hoping to see a dramatic improvement in Vista.

Up until now all of our C++ development has been in Visual C++ 6.0 (VC6) because we needed compatibility with Windows 95. Visual Studio 97 (which includes VC6) installed fine on Vista, but Service Pack 6 did not. Turns out that VC6 has reached "end of life" and it won't be supported on Vista. OTOH, VB6 *is* officially supported on Vista, but since no one has figured out how to install SP6 on the RTM, it remains to be seen how this can be made to work.

Since VC6 is now ten years old, I've decided to convert our applications to Visual Studio 2005. I do this with some reluctance because VS2005 had been an absolute pig on a P4 2.4 GHz with 1GB of RAM. Also, our applications use some VC6 features that will need to be reworked for VS2005, such as try { } catch (...) {}. This catch block on VC6 would catch access violations, but this functionality was deemed to be non-standard and was removed. It's now necessary to put in explicit Win32 structured exception handling support.

The good news is that last year I proactively fixed some of the most egregious problems, such as the scope of variables in for loops.