category_name=blog%2Fmicrosoft

Mac Market Share Increasing!

January 17, 2009 | Comments Off

I was at the local library today to do a couple hours programming in a quiet environment without the normal distractions of my home office. To my surprise when I looked around I saw a sea of Apple MacBook and MacBook Pro laptops. Sure, there were a few Toshiba or HP laptops too, but the majority of the machines in the room had shinning bright Apple logos on the screens.

My unscientific survey in the library today yielded the following numbers:

System Count
White MacBook 2
Unibody 13″ Macbook 1
15″ MacBook Pro 2
12″ PowerBook 1
Toshiba 1
HP 2
IBM 1

That breaks down to 60% Apple, 40% Microsoft.

Now that’s what I like to see! Maybe the recent discussion on the macsb about Mac market share isn’t so far fetched after all. Here are a few interesting links:

Who knows if this is all true or not. With the recent announcement that Steve Jobs will be taking a six month leave of absense from Apple due to health concerns the future for Apple is less clear than it once was. I’m sure Apple will do just fine over the next 12-18 months since there are a number of products already in development. The big concern has to be about the sort of innovations that Apple can concieve of and execute on after the current pipeline runs dry. Will there be other folks at Apple with the same vision and forsight as Steve Jobs? Probably, but it is far from certain.

Atleast for now it seems like the market share for Apple will continue to climb. Microsoft will have to hit a home run with the new Windows 7 operating system if they want to fend off the onslaught of Mac OS X. Being a long time developer on both platforms I can say that from my point of view having more users on the Mac makes me happy! I look forward to developing, releasing and selling more applications on the Mac platform.

You can’t keep a good class library down … MFC gets reprieve from death sentence!

July 15, 2008 | Comments Off

A few years ago I was working at a company where we built applications using Visual Studio 6 and MFC. The applications had been around for about 10-12 years, and were all showing their age. Customers were beginning to request updated user interface features like they were seeing in modern Microsoft products such as Office and Internet Explorer. Sadly, we could not deliver these user interface enhancements easily because MFC was not getting any attention from Microsoft.

In late 2002 Microsoft was pushing the .NET Framework, C# and WinForms as the heir apparent for Win32, C++ and MFC. Converting a decade of legacy C++ MFC code to .NET and WinForms just wasn’t an option. We all felt like Microsoft had just abandoned us for greener pastures.

Our solution at the time was to start a long difficult process of moving away from MFC toward a cross-platform class library built by Trolltech, called Qt. In many respects this turned out to be a good decision since it meant we could begin to seriously consider offering our applications on Windows, Linux and the Mac instead of just on Windows. Still, it felt like Microsoft had hung us out to dry.

The WinForms classes just were not rich enough to build complex desktop applications at the time. Many of the conveniences we had come to rely upon from the MFC class libraries were missing and it would have been up to us to roll our own alternatives had we gone down the WinForms route. I think Microsoft was too focused on building web applications to devote sufficient resources to WinForms.

Here we are six years later and Microsoft has announced that they are providing a MFC Feature Pack for Visual C++ 2008 that will add significantly to the capabilities of the MFC class libraries. I can hear MFC development teams all across the Internet celebrating this change in stance from Microsoft.

Here are a couple links to information from Microsoft on the topic:

Couple MFC with a good third-party widget library like the toolkit offered by CodeJock Software and you have everything necessary to build some awesome new desktop applications.

Long Live MFC!

Microsoft Professional Developers Conference 2008 – See you there?

July 3, 2008 | 1 Comment

logo-flat.png

The last time I attended the Microsoft Professional Developer Conference was back in 2001, shortly after the attacks of September 11th, 2001. Just over 6000 people made the trip to Los Angeles to learn about the latest technologies from Microsoft, as they were in the midst of rolling out the .NET Framework. They were pushing Hailstorm (I still have the free book they gave everyone with the Hailstorm API in it. I never did get a chance to use it though.). Everyone was excited about building new web services using .NET and C#.

A lot has changed since then. Vista and Windows Server 2008 are here, the .NET Framework has gone through three major revisions, Visual Studio has seen major improvements supporting team development, Intel has delivered multi-core processors and Microsoft still hasn’t delivered on the promise that was Hailstorm.

The preliminary agenda for PDC 2008 has some interesting sessions listed. Topics I am hoping to learn more about this year include:

  • Silverlight
  • Visual Studio 10
  • Windows 7
  • Multi-core Programming Techniques

Even though Bill Gates is now officially retired it looks like he is scheduled to speak at the conference as well. For a geeky college dropout with a whiny voice he does a great job delivering keynotes to developers. He doesn’t have the stage presence of a Steve Jobs, but he isn’t running Apple either. I look forward to hearing what his message for Microsoft developers is this year.

The dates for the conference are October 26 – 30, and the event is being held at the Los Angeles Convention Center once again. I hope to see you there.

How to enable MSI Logging

June 9, 2008 | Comments Off

If you are trying to debug an installer problem it is probably worth having MSI logging turned on. This will produce a file in your %TEMP% directory that contains a detailed trace of the activities that took place in MSIEXEC. This can be very helpful when an install or uninstall fails without any clear indication as to why it failed.

Log files are stored in the directory pointed to by the TEMP environment variable. The filename format is MSIxxxx.LOG, where xxxx is replaced with a random string. A new log file is created for each invocation of MSIEXEC.

To enable logging through group policy, do the following:

  • Start / Run… / gpedit.msc
  • Drill down into Local Computer Policy / Computer Configuration / Administrative Templates / Windows Components / Windows Installer / Logging
  • Enable logging with the setting “voicewarmup”. These are the command-line arguments that MSIEXEC will use.

These links contain more information on setting up logging:

GetQueuedCompletionStatus() – Devil in the Details!

May 22, 2008 | Comments Off

One of the projects I work on makes use of the Win32 asynchronous I/O model for managing network traffic between a Windows Service and a custom-built network device.

One of the key Win32 APIs we use is called GetQueuedCompletionStatus. This API provides access to an I/O completion port that is managed by a separate operating system thread.

When dealing with this API and Windows asynchronous I/O in general it helps to think about the model as being supported by a separate workpool thread. This API gives the caller a way to synchronize with the operations of that workpool thread (or threads).

The prototype for this API is as follows:

BOOL GetQueuedCompletionStatus(
	HANDLE CompletionPort,
	LPDWORD lpNumberofBytes,
	PULONG_PTR lpCompletionKey,
	LPOVERLAPED* lpOverlapped,
	DWORD dwMilliseconds);

At first glance the API may not seem too complex. There are 5 parameters and a boolean return type. Some of the parameters are easy to figure out just be looking at their names. Others are less clear. You could speculate that the returned boolean is an indicator of whether or not the operation was successful or not. It is easy to be lulled into a false sense of understanding by reading through the first few paragraphs of the MSDN documentation on this API.

It actually turns out that this API is very complex (perhaps too complex?), and careful study of the MSDN documentation is required if you wish to handle all of the possible conditions when this API returns. Pay careful attention to the section in the documentation that discusses Return Values and Remarks.

My favorite gem from the return values section (and the one I recently missed when using this API) is:

If a socket handle associated with a completion port is closed, GetQueuedCompletionStatus returns ERROR_SUCCESS, with *lpOverlaped non-NULL and lpNumberOfBytes equal to zero.

In other words, when the socket is closed (possibly because the peer closed it) you will get what appears to be a successful I/O completion. This does not represent what most would consider a successful return, and if you have not carefully checked the other parameters, your code may mis-interpret this condition.

Another area where you need to be careful when using Windows Asynchronous I/O is application shutdown. There may be a number of pending I/O operations that have been queued to the I/O completion port. It is your responsibility to finish processing all of these I/O operations (possibly by first closing the socket and then handling each failed I/O completion event) and release any resources that were allocated for the I/O operations. Failing to do this will likely result in a memory leak for the application.

The moral of the story is to always read the entire MSDN documentation page and make sure your code handles all of the possible combinations of return values!

WinQual Registration Head Aches

March 8, 2008 | 5 Comments

In order to digitally sign Windows drivers you need what Microsoft called an Authenticode Digital Certificate. The company I work is creating a number of drivers, so we had a need for an Authenticode Digital Certificate. The certificate would also be used to sign the Microsoft installer packages that we release to customers.

Being a cost conscious group we shopped around and identified two main sources for Authenticode digital certificates.

* VeriSign http://www.verisign.com
* Thawte http://www.thawte.com

Comparing the prices it seemed clear that the Thawte certificate was a better bet so that is what we purchased. Everything appeared to be fine until we tried to join the WinQual program. That is when I started asking myself the following question:

Question: When is an Authenticode Digital Certificate not an Authenticode Digital Certificate?

Answer: When you try and use it in the application process for joining the WinQual program.

In the last couple weeks I have been learning about the requirements to digitally sign Windows device drivers. My strategy has been to take the Toaster sample from Microsoft and try to duplicate all of the steps necessary to build a signed version of the driver. Naively, I figured it should be easy to replicate the steps taken by Microsoft to sign this sample program. Boy was I wrong!

It turns out that there is a utility called inf2cat or something like that. Microsoft recommends using it to create the category file containing hashes of the files you want digitally signed as part of your driver package. So, for me to replicate the Toaster sample signing process I need a copy of inf2cat. This tool is apparently only available to members of the WinQual program that Microsoft runs.

Okay, so I need to join WinQual. How hard could that be. I went to https://winqual.microsoft.com and learned that in order to joint he program you must submit a file to them that is digitally signed with your Authenticode certificate. So off I went to get an Authenticode certificate for my company. After a few google searches I came to the conclusion that VeriSign and Thawte are the two primary sources for these certificates, and Thawte is considerably cheaper. I purchased an Authenticode certificate from Thawte and a few days later the certificate was on my machine and it was time to make the membership request on the WinQual site.

I followed all of the instructions to digitally sign the required file using my new Authenticode certificate. Everything seemed to go smoothly until I tried to upload the signed file to Microsoft. Their web site kept saying that the file was not signed correctly. I went back to the main WinQual web page to try and find an answer to this problem. There was nothing there to help me solve this mystery so I went to the only other resource I could think of. That is the DDK mailing list archives at OSR. These folks have been doing Windows driver work for ages and if anyone knew what was wrong, I was sure the answers would be on their mailing list.

It only took one keyword search of the archives to learn what the problem was. It seems that not all Authenticode digital certificates are created equal, and Microsoft has a predilection to those minted by VeriSign. My new Thawte digital certificate would be just fine for signing my drivers, but it would not be at all useful in joining the WinQual program. It was beginning to look like I needed to buy another Authenticode certificate from VeriSign in order to join the WinQual program.

After carefully re-reading the WinQual page describing the ways to join the program I learned that you could also sign your membership request using something called a Corporate Identifier. It was a cheaper, less capable digital certificate that could be used to sign the file and join the program. This certificate could be purchased from VeriSign for $99.

I waited another couple days and the new Corporate Identifier finally appeared in my inbox. I followed the instructions to sign the file, upload it, and this time I met with success in joining the WinQual program.

So, instead of saving money by using the Thawte certificate I ended up spending roughly the same amount of money that it would have cost to just purchase the Authenticode certificate from VeriSign. The difference was that because the WinQual site was not clear on the specific requirements for using a VeriSign certificate I ended up wasting at least 2 or 3 days trying to join the WinQual program.

In the end it was clear that I should have purchased the “name brand” digital certificate from VeriSign.

HOWTO – Use Visual Studio 2005 for Qt Open Source Development

February 14, 2006 | Comments Off

THIS IS A WORK IN PROGRESS. EXPECT UPDATES AND DON’T BE SURPRISED BY INCOMPLETE INFORMATIONqtlogo_feature.png

Trolltech has released Qt 4 under a dual-license for all supported platforms. In earlier versions of Qt they only released the open source version for Mac and Linux, leaving Windows developers with no choice but to purchase a commercial license. That all changed with the release of Qt 4 when Trolltech started to provide an open source version for Windows development too! The only catch was that Trolltech only supports the MinGW GCC compiler for development using the open source version.

This article describes how to patch Qt 4 open source edition on Windows so you can develop using Visual Studio 2005. You can even develop using the free Express edition of Visual Studio 2005 so long as you also install the latest Platform SDK.

Please keep in mind that these patches and tips are not provided so you can get around the very generous Trolltech dual-license terms of use. If you are developing or intend to develop a commercial application using Qt 4 you must purchase a commercial license for Qt 4. Only use the information provided in this article if you wish to develop open source GPL software for the Windows platform and wish to use the Microsoft Visual C++ 2005 compiler instead of the MinGW GCC compiler.

Download Qt 4.1 Source Code, Patches, and Notes

  • Download the latest open source Windows version of Qt 4.1 from Trolltech at http://www.trolltech.com/download/qt/windows.html. Unzip the file to C:\. It will extract all of the files into a sub-directory called qt-win-opensource-src-4.1.0.
  • Download the latest patch file used to modify the open source version of Qt 4.1 to support Microsoft Visual Studio 2005 from Source Forge at http://sourceforge.net/projects/qtwin/. Unzip the file to C:\qt-win-opensource-src-4.1.0.
  • Download the build script, environment setup and notes from http://www.idevelopsoftware.com/downloads/qt/Qt41WinBuildScript.zip. Unzip the file to C:\qt-win-opensource-src-4.1.0.
  • If you don’t already have Visual Studio 2005 you can download the Express edition. You will also need to download the Platform SDK.

    http://msdn.microsoft.com/vstudio/express/visualC/default.aspx

    http://msdn.microsoft.com/vstudio/express/visualc/usingpsdk/default.aspx

Building Qt 4.1 using Visual C++ 2005

Open C:\qt-win-opensource-src-4.1.0 in Windows Explorer.
Double-click on the “Qt 4.1 Command Prompt” shortcut to open a Command Prompt window with the environment setup for Qt 4.1 development. IMPORTANT: You must already have Visual Studio 2005 installed. You may need to edit setenv.cmd if your copy of Visual Studio 2005 is not in the default location.

Run “installpatch41.bat”
This will patch the Qt 4.1 source code so it builds properly using the Visual C++ 2005 compiler.

Run “build.cmd”
This will build all of the Qt 4.1 libraries, utilities, and sample applications using the Visual C++ 2005 compiler.

To rebuild, if necessary, make sure to first clean up the previous build. Do this by running
nmake distclean

from the C:\qt-win-opensource-src-4.1.0 directory.

External Tools Configuration in Visual Studio 2005

Launch Visual Studio 2005 and select the “External Tools…” item from the Tools menu.
Use the “Add button to define each of the following external tools:

Title ……………….. QMake (Project File Generation Mode)
Command ……………… D:\qt-win-opensource-src-4.1.0\bin\qmake.exe
Arguments ……………. -project -spec win32-msvc2005
Initial directory …….. $(ProjectDir)
Use Output window …….. [X]
Treat output as Unicode .. [ ]
Prompt for arguments ….. [ ]
Close on exit ………… [X]

Title ……………….. QMake (Makefile Generation Mode)
Command ……………… D:\qt-win-opensource-src-4.1.0\bin\qmake.exe
Arguments ……………. -makefile -spec win32-msvc2005
Initial directory …….. $(ProjectDir)
Use Output window …….. [X]
Treat output as Unicode .. [ ]
Prompt for arguments ….. [ ]
Close on exit ………… [X]

Title ……………….. Qt Designer
Command ……………… D:\qt-win-opensource-src-4.1.0\bin\designer.exe
Arguments …………….
Initial directory …….. $(ProjectDir)
Use Output window …….. [ ]
Treat output as Unicode .. [ ]
Prompt for arguments ….. [ ]
Close on exit ………… [ ]

Title ……………….. Qt Assistant
Command ……………… D:\qt-win-opensource-src-4.1.0\bin\assistant.exe
Arguments …………….
Initial directory …….. $(ProjectDir)
Use Output window …….. [ ]
Treat output as Unicode .. [ ]
Prompt for arguments ….. [ ]
Close on exit ………… [ ]
Adding a Qt 4.1 Development Toolbar

Add a new toolbar for Qt 4.1 Development by selecting “Customize…” from the Tools menu. Once the “Customize” dialog appears select the “Toolbars” tab and press “New…” For the toolbar name enter “Qt 4.1 Development” and press “OK”.
Select the “Commands” tab on the “Customize” dialog. Select “Tools” from the “Categories:” list. Scroll down in the “Commands:” list until you see “External Command 7″. Drag commands 7, 8, 9, and 10 onto the new “Qt 4.1 Development” toolbar.
Creating a New Visual Studio 2005 Project

Open the “New Project” dialog by selecting File->New->Project… from the menu. Under “Project types” on the left side of the dialog expand “Visual C++” and then select “General.” The right side of the dialog will display a list of all the general project types. Select “Makefile Project” from the list of project types. Provide a name for the project and set the location on disk where you wish the project to be saved. Be sure not to check “Create directory for solution”, as this will create an extra level of directories that is just confusing. Click the “OK” button and you will be presented with the “Makefile Application Wizard.” Simply press the “Finish” button on the first page of the wizard.

Once the project has been created and opened, set the NMake Configuration Properties for the project as shown below. In the “Solution Explorer” right-click on the name of your project. Select “Properties…” from the context menu. On the property pages dialog select “Configuration Properties” and “NMake” on the left side tree control. On the right side, enter the following information, making sure to set the properties for both the debug and release configurations.

Release Configuration Settings

General
——-
Build Command Line …………………. nmake release-all
Rebuild All Commaond Line …………… nmake release-clean release-all
Clean Command Line …………………. nmake release-clean
Output ……………………………. foo.exe

IntelliSense
————
Common Language Runtime Support ……… No Common Language Runtime support
Preprocessor Definitions ……………. WIN32;NDEBUG;UNICODE;QT_LARGEFILE_SUPPORT;QT_DLL;
QT_GUI_LIB;QT_CORE_LIB;QT_THREAD_SUPPORT
Include Search Path ………………… “c:/qt-win-opensource-src-4.1.0/include/QtCore”;
“c:/qt-win-opensource-src-4.1.0/include/QtGui”;
“c:/qt-win-opensource-src-4.1.0/include”;
“c:/qt-win-opensource-src-4.1.0/include/ActiveQt”;
“c:/qt-win-opensource-src-4.1.0/mkspecs/win32-msvc2005″
Forced Includes …………………….
Assembly Search Path ………………..
Forced Using Assemblies ……………..
Debug Configuration Settings

General
——-
Build Command Line …………………. nmake debug-all
Rebuild All Commaond Line …………… nmake debug-clean debug-all
Clean Command Line …………………. nmake debug-clean
Output ……………………………. food.exe

IntelliSense
————
Common Language Runtime Support ……… No Common Language Runtime support
Preprocessor Definitions ……………. WIN32;_DEBUG;UNICODE;QT_LARGEFILE_SUPPORT;QT_DLL;
QT_GUI_LIB;QT_CORE_LIB;QT_THREAD_SUPPORT
Include Search Path ………………… “c:/qt-win-opensource-src-4.1.0/include/QtCore”;
“c:/qt-win-opensource-src-4.1.0/include/QtGui”;
“c:/qt-win-opensource-src-4.1.0/include”;
“c:/qt-win-opensource-src-4.1.0/include/ActiveQt”;
“c:/qt-win-opensource-src-4.1.0/mkspecs/win32-msvc2005″
Forced Includes …………………….
Assembly Search Path ………………..
Forced Using Assemblies ……………..
QMake Project Settings

Create a project file called “foo.pro” in the directory for your makefile project. Replace the name “foo.pro” with the name of your actual application. Place the file in the directory where your Visual Studio project was created. To start with, the contents might look something like this:

CONFIG += qt
TEMPLATE = app
SOURCES += foo.cpp
HEADERS += foo.h
FORMS += foo.ui
You should be off and running now. For more detailed information I would suggest reading the qmake reference manual. You might also want to take a look at the Qt 4.1 tutorials in Qt Assistant. Have fun!

Environment Variables Provided by Windows Operating System

July 23, 2004 | Comments Off

Microsoft assigns a type to each environment variable that is part of the environment block of a process. The possible types are System, User, Volatile and Process.

System
An environment variable that contains the same value for all processes running on the system, regardless of which user the process runs as. These are shared or global environment variables, and are defined in the system registry under the HKEY_LOCAL_MACHINE hive.
User
An environment variable that is specified for a particular user on the system. These are defined in the system registry as well, but are maintained under the HKEY_CURRENT_USER hive.
Volatile
An environment variable that is not persistent, and has a value that was assigned by the operating system based on some property of the system.
Process
An environment variable that is set only for a particular process. Often this would be set in the environment block by the parent process at the time the process is created. These are not persistent.

Additionally, the CMD.EXE command processor defines some dynamic environment variables that are assigned new values after each command is evaluated. These variables are volatile.

These tables were created by going through the on-line help for Windows 2000. I have listed all the volatile and dynamic environment variables I could find defined. There are probably more, and some of these may not be accurately documented.

Volatile Environment Variables
Name Description
ALLUSERSPROFILE Local – returns the location of the All Users Profile.
APPDATA Local – returns the location where applications store data by default.
COMPUTERNAME System – returns the name of the computer.
HOMESHARE System – returns the network path to the user’s shared home directory. This variable is set based on the value of the home directory. The user’s home directory is specified in Local Users and Groups.
LOGONSERVER Local – returns the name of the domain controller that validated the current logon session.
USERDOMAIN Local – returns the name of the domain that contains the user’s account.
USERNAME Local – returns the name of the user currently logged on.
USERPROFILE Local – returns the location of the profile for the current user.
NUMBER_OF_PROCESSORS Number of processors running on the machine.
PROCESSOR_ARCHITECTURE Processor type of the user’s workstation.
PROCESSOR_IDENTIFIER Processor ID of the user’s workstation.
PROCESSOR_LEVE Processor level of the user’s workstation.
PROCESSOR_REVISION Processor version of the user’s workstation.
OS Operating system on the user’s workstation.
COMSPEC Executable file for the command prompt (typically cmd.exe).
HOMEDRIVE Primary local drive (typically the C drive).
HOMEPATH Default directory for users (typically \users\default in Windows 2000).
PATH PATH environment variable.
PATHEXT Extensions for executable files (typically .com, .exe, .bat, or .cmd).
PROMPT Command prompt (typically $P$G).
SYSTEMDRIVE Local drive on which the system directory resides (typcially c:\).
SYSTEMROOT System directory (for example, c:\winnt). This is the same as WINDIR.
WINDIR System directory (for example, c:\winnt). This is the same as SYSTEMROOT.
TEMP Directory for storing temporary files (for example, c:\temp).
TMP Directory for storing temporary files (for example, c:\temp).
Dynamic Environment Variables
Name Description
CD Expands to the current directory.
DATE Expands to the same output as typing DATE.
TIME Expands to the same output as typing TIME.
RANDOM Generates a random integer in the range of 0 – 32767.
ERRORLEVEL Expands to the current ERRORLEVEL.
CMDEXTVERSION</td Expands to the current Command Processor Extensions version number.
CMDCMDLINE Expands to the original command line that invoked the Command Processor.

PATH Environment Variable Limitations in Windows

July 14, 2004 | Comments Off

Environment variables are managed using the System control panel applet in Windows. This user interface leaves much to be desired, but it works. Environment variables are separated into “System” and “User” categories. All users that may login on a machine share the System environment variables. Each user has her own set of User environment variables. User environment variables take precedence over System environment variables. How this precedence rule effects variable definitions is illustrated in the following example:

If the variable TEMP Generally speaking, if an environment variable appears in both categories then the value associated with the User environment variable will be used.

The PATH environment variable controls how the operating system searches for executable (EXE) and dynamic link library (DLL) files when asked to run an application. Some applications are installed for use by all users of the system and others are installed for exclusive use of a particular user.

Microsoft publishes some great human factors guidelines for building Windows applications. I sure wish they would follow some of these guidelines for the Control Panel applets that are provided with Windows. If these applets had to go through the logo certification process I’m sure they would fail!

Take for example the environment variable editing dialog box in the System applet.

EnvironmentVariables-thumb

This is a prefect example of what not to do when building a user interface. I hate editing environment variables using a one line edit box where you can’t even see the whole definition of the value. You can’t even resize the dialog box!

To make matters worse, there are limits imposed by the operating system that are not checked in the user interface. The PATH environment variable cannot exceed 1024 characters in length, but the user interface happily allows you to define a PATH that is way longer than this.

You can try this for yourself by defining a System PATH that is about 512 bytes in length and define a User PATH that is about 600 bytes long. Because the combine System+User PATH is longer than 1024 bytes the operating system decides to only use the System PATH, leaving out all your User PATH assignments.

A good user environment variable editor would check for this sort of thing. Since Microsoft doesn’t need to get their applications “logo certified” they can freely ignore the UI guidelines they publish. What a shame!

I looked into what it would take to create my own Control Panel Applet to replace this environment variable editor and it looks straight forward. Keep tuned, and maybe I’ll post an improved editor here.

As I dig further into this environment variable issue it seems like there is a lot of inconsistency between versions of Windows.

Microsoft has some information on the NT command prompt for Windows XP that says the maximum environment variable size is 8192 bytes and that the entire environment cannot exceed 65,536KB (though I think that is supposed to be bytes).

Early versions of MS-DOS had a 128 character limitation on the PATH variable. According to this article, that limitation was removed in MS-DOS 6.0. In KB169171 Microsoft talks about how 16-bit applications can still hang when the path exceeds 200 bytes.

The only place I could find that actually states that there is a 1KB limit on the combine length of the System+User path is here. In the WORKAROUND section of this article it states that the path should “total 1 KB or less of characters”. The article is for Windows NT Server 4.0 Terminal Server Edition, but my experiments on a Windows 2000 Professional system indicate that it is still the case. I haven’t tried Windows XP or Windows Server 2003 yet to determine if the problem exists in those variants of Windows.

www.idevelopsoftware.com is Digg proof thanks to caching by WP Super Cache