Monday, September 29, 2008

CString and Path functions in shlwapi.dll

The "Path" functions in shlwapi.dll are examples of obscure APIs that are incredibly useful. There are dozens of useful functions in there, including PathAppend, PathFileExists, PathFindExtension, and PathFindFileName.

The only problem is that these functions don't play nicely with CString without going through the contortions of GetBuffer/ReleaseBuffer.

Turns out that Visual Studio 2005 and 2008 both include the atlpath.h header file, which includes wrappers for all of the Path functions to make them easy to use with CString. This makes those functions much easier (and much safer) to use.

Sunday, September 28, 2008

Visual Studio 2008 C/C++ applications under Win9x

On of the disadvantages of Visual Studio 2008 is that it does not create applications that support Windows 95/98/98SE/ME nor Windows NT. Although Windows XP has been shipping for seven years, there are still people out there who have never seen any reason to upgrade and are still running the old operating systems. (As of August 2008, shows that the combined market share of the Windows 9x variants is less than 0.9%.)

Windows 95 support was dropped in Visual Studio 2005, but working around the problem was easy.

Visual Studio 2008 is a thornier problem. VS2008 dropped support for all variants of Win9x and the C run-time depends on several functions that require Windows 2000 or later. Fortunately, a third party company has created a product named Legacy Extender that provides a drop-in solution. The caveat is that it only works with the statically linked C runtime libraries, not with the DLLs.

For a modest $29.95/developer, including unlimited upgrades, Legacy Extender is a great solution to a difficult problem.

Saturday, September 13, 2008

Screenshots for technical support

The bane of every support technician's extistence is trying to interpret what a customer is saying. I'm launching a new site named that allows users to send technical support people a screenshot without requiring any expertise.

Check it out.

Monday, September 8, 2008

Remote Debugging Managed Code

Last year I blogged about how to get Remote Debugging working. That article was for Visual Studio 2005, but it works fine with some minor modifications for directory and filenames for Visual Studio 2008.

Now I've had to take the next step, which is remote debugging managed code instead of native code. Turns out that debugging managed code is even more complicated than native code.

One of the key problems I originally had was that I was never able to get authenticated debugging working because one computer was on a workgroup and one was on a domain. After reading several articles, I was able to solve the problem by creating an account on the remote computer that had the same username and password as the account of the development computer. If your development system isn't on a domain, make sure that the remote account is created on the local computer and not the domain. You may need to use the "NET USER" command from the command line to create such an account.

If you are running Windows Firewall, the remote debug module msvcmon.exe will automatically unblock the right ports for you. At least that was easy.

The next trick is to convince .Net to run your application from a network drive. This technique is described in the .Net Security Blog.

By the way, the Remote Debugger Configuration Wizard was useless for me.

Tuesday, September 2, 2008

Testing Google APIs

I blogged a little while ago about the problems with Google documentation. I've now completed my code that uses these APIs and I'm writing stress tests for the system. Except there's one problem: The server can generate all sorts of errors that aren't under your control, and there's no way to test these error conditions.

These errors are different than communication errors. It's easy to simulate a "link down" problem or similar TCP/IP failure. The problem is that the Google Data API servers can fail in strange and bizarre ways.

One example is the simple "Server Busy" command. The documentation says to "wait and retry." Unfortunately, there's no way to force this scenario, so there's no way to test this error.

Another example is error 403 "Operation could not be completed". What do you do with that? Even worse, if you are performing batch operations, you could have partial failure. Again, there's no way to test this scenario.

Please vote for my bug report asking Google to fix this problem: