ABSTRACT
This article shows a problem that exists when trying to obtain the path of Environment.SpecialFolder.CommonDocuments from a x86 process on systems running Windows x64 after the Common Documents folder has been moved from the default location. The article explains how to reproduce the problem and shows some working code to work around this bug. Additionally this article explains the background behind this problem and some implementation details of x86 emulation on Windows x64 systems.
Background
The 64-bit (x64) versions of Windows supports 32-bit (x86) processes through an emulation concept called 'Windows on Windows 64' (WOW64). Part of the magic are the File System Redirector and the Registry Redirector. The File System Redirector comes into play, when you try to access certain folders- e.g. %windir%\system32 - from an x86 process. It will map the request transparently to %windir%\SysWOW64. Registry Redirector does exactthe same for certain nodes in the registry. For example, HKEY_LOCAL_MACHINE\Software is redirected to HKEY_LOCAL_MACHINE\Software\Wow6432Node.
Additionally, Windows allows users to move those special folders. For example, a user may decide to move his Public Documents folder to a network share, from which backups are created by the local administrator.
Here are the steps you need to take to move the Public Documents folder:
Or use this alternative way for (moving the Public folders on Windows 7)
- Deactivate User Account Control (UAC) in the control panel
- Reboot Windows
- Navigate to %SYSTEMDRIVE%\Users\Public
- Right click on 'Public Documents' (or whatever is the localized name of that folder)
- Select 'Properties'
- switch to the 'Location' tab
- input the new path and apply settings, confirm all questions asked
Note: This is only possibly after deactivating UAC and restarting Windows, so Windows tries to protect you to some extend.
The Problem
When a user moves his special folders, all seems well (all IS well) – when viewed from the x64 world. When you look at the folder in Windows Explorer you see the real name (e.g. D:\Real Common Documents) replaced by the localized name ("Public Documents" or "Öffentliche Dokumente" on German versions of Windows).
But once you try to access that same information from any program that was compiled as x86 and runs on the WOW64 emulation, you'll get very different results indeed.
For demonstration purposes, I moved the Public Documents folder on my Windows 7 x64 computer from its usual place ( C:\Users\Public\Documents ) to D:\ Real Common Documents.
To illustrate I pulled together a very short program in C# and compiled it with .NET 4.0.
namespace GetSpecialFolders
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(Environment.GetFolderPath(Environment.SpecialFolder.CommonDocuments));
}
}
}
Then I fired up a command line and ran the following commands:
(Outputs are bold, actual commands are preceded by '>' )
>csc /platform:x86 Program.cs > dev.null
>Program.exe
C:\Users\Public\Documents
>csc /platform:x64 Program.cs > dev.null
>Program.exe
D:\Real Common Documents
(You can also have a look at the screen shot of this experiment)
As you can see the returned values differ between x64 and x86 versions.
Explaining the Behaviour
First and Foremost: This behaviour is (somwewhat) by design. The path to the Public Documents folder is stored in the registry and it is done so twice.
registry path for x64: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\Common Documents
registry path for x86: HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\Common Documents
So from my point of view it looks like moving the folder will update the x64 part, but not the x86 part of the registry.
The following folders are also stored in the 32 bit part of the registry – and are thus likely affected by the same bug:
- Common Administrative Tools
- Common AppData
- Common Desktop
- Common Documents
- Common Programs
- Common Start Menu
- Common Startup
- Common Templates
- CommonMusic
- CommonPictures
- CommonVideo
Important notes:
As you see there are no user-specific folders in this list. Doing the same steps with My Documents folder and testing with a slightly modified version of the above application showed that My Documents is NOT affected by this bug – i.e. the same path is yielded in x86 and x64.
Windows does not allow you to move all of the above folders. At least not with a convenient user interface – you might be able to pull that off through the registry however.
How to solve this problem
The only work around I know of, is the application (and its derivates) I posted above – compiled with /platform:x64.
Calling the resulting executable and parsing its output solved the problem for me and will likely solve it for you.
I tried calling SHGetKnownFolderPath directly through P/Invoke while debugging my application, but that unsurprisingly did not help me.
Further Reading:
- the MSDN connect report I filed
- the StackOverflow question I wrote on my journey to enlightment
UPDATE 1:
Running the same test (see above) on Windows 8 x64 Consumer Preview returns an empty string for the x86 version.
So this matter seems to actually get worse with Windows 8!



