Things to keep in mind regarding Registry while migrating a 32 bit application from Vista x64 to Windows 7 x64
If you are migrating a 32 bit application from Vista x64 to Windows 7 x64 and your application relies on some information in registry. There are few things you should consider as following.
In Windows 7, registry is virtualized. As a result, wow64 applications don’t have to explicitly provide registry path with Wow6432Node node. For example if you have to probe 32 bit .Net SDK’s location, you don’t have to use path like path \SOFTWARE\Wow6432Node\Microsoft\.NETFramework from your 32 bit app. Using just \SOFTWARE\Microsoft\.NETFramework should direct your application to an entry under Wow6432Node.
For example, If you are using RegistryKey class in a 32 bit managed application running on 64 bit Win7 and something like
RegistryKey key = Registry.LocalMachine.OpenSubKey(@"\SOFTWARE\Wow6432Node\Microsoft\.NETFramework”;
You will be routed to \SOFTWARE\Wow6432Node\Wow6432Node \Microsoft\.NETFramework and get null key returned.
Let me show you an example.
Although, On Windows 7, it is not needed to check platform before reading and writing in registry but to make things clear, I am going to use a method called CheckArchitecture() , Depending upon the processor and AddressWidth property returned by System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE") and WMI, I am figuring if the process is pure x86, x64 or WOW64 (32 bit process on 64 bit operating system.
//Logic to check architecture and verified it using three flags (X86,X64 and SysWOW64). I called this Method CheckArchitecture()
public static string CheckArchitecture()// Return one of these values (X64, X86, SysWOW64, Unidentified)
{
PropertyData PropData = null;
string archi = null;
string AddressWidth = null;
// Check Process architecture (x86 or AMD64)
string ProcessArchi = System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE");
// Check process architecture
ManagementObjectSearcher MObjCollection = new ManagementObjectSearcher("select * from Win32_Processor");
foreach (ManagementObject MObj in MObjCollection.Get())
{
// AddressWidth = 64 means x64 OS, 32 means x86 OS
PropData = MObj.Properties["AddressWidth"];
if (PropData.Name != null && PropData.Value != null) // Check to avoid null reference.
{
//Console.WriteLine(PropData.Name.ToString() + " = " + PropData.Value.ToString());
AddressWidth = PropData.Value.ToString();
}
}
// Check combination of ProcessArchi and AddressWidth
if (ProcessArchi == "AMD64" && AddressWidth == "64")
{
archi = "X64";
}
else if (ProcessArchi == "x86" && AddressWidth == "64")
{
archi = "SysWOW64";
}
else if (ProcessArchi == "x86" && AddressWidth == "32")
{
archi = "X86";
}
else
{
archi = "Unidentified";
}
return archi;
}
In this sample code I am calling my CheckArchitecture() method above.
RegistryKey key; // I am not opening registry right now.
// This should print Architecture value
Console.WriteLine("Architecture = " + CheckArchitecture());
string platform = CheckArchitecture();
// Called the method to check architecture.
string dbPath = string.Empty;
try
{
if (platform.ToString() == "X86")
{
// NOTE : No Wow6432Node in Key path
key = Registry.LocalMachine.OpenSubKey(@"Software\Microsoft\.NETFramework", RegistryKeyPermissionCheck.ReadSubTree, System.Security.AccessControl.RegistryRights.ReadKey);
//Output : Screenshot 1 at bottom
}
else if (platform.ToString() == "X64")
{
key = Registry.LocalMachine.OpenSubKey(@"Software\Microsoft\.NETFramework", RegistryKeyPermissionCheck.ReadSubTree, System.Security.AccessControl.RegistryRights.ReadKey);
//Output : Screenshot 2 at bottom
}
else if (platform.ToString() == "SysWOW64")
// Additional check. This is 32 bit process on 64 bit OS and CPU.
{
// NOTE : No Wow6432Node in Key path
key = Registry.LocalMachine.OpenSubKey(@"Software\Microsoft\.NETFramework", RegistryKeyPermissionCheck.ReadSubTree, System.Security.AccessControl.RegistryRights.ReadKey);
//Output : Screenshot 3 at bottom
}
else
{
throw new Exception("Unknown OS version ..");
}
if (key == null)
{
throw (new Exception("InstallRoot not Found .."));
}
dbPath = key.GetValue("sdkInstallRootv2.0").ToString(); // Print SDK Path
Console.WriteLine(dbPath);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
This is the output I got.
SCREEN SHOT 1 : 32 bit Windows 7 & 32 Bit application.
SCREEN SHOT 2 : 64 bit Windows 7 & 64 Bit application.
SCREEN SHOT 3 : 64 bit Windows 7 & 32 Bit application.
Note : Although values for 32 bit and 64 applications are different. Application queries same registry key in all three cases (Software\Microsoft\.NETFramework). OS itself mapped the 32 bit and SysWOW64 request to SOFTWARE\Wow6432Node\Microsoft\.NETFramework.
Author : Runeet(MSFT), SQL Developer Engineer, Microsoft
Reviewed by : Snehadeep(MSFT), SQL Developer Engineer, Microsoft
Comments
- Anonymous
October 02, 2010
I tried your code in Win2008 server not working. 32bit Code compiled under VS2008, TargetCPU:x86.