Question

Please correct me if I'm wrong on this, as I'm certain I read it somewhere: Registry virtualization is disabled for Windows Services. Also, virtualization is disabled for x64 binaries.

I have a windows service written in C# that needs to load a value from HKEY_LOCAL_MACHINE\SOFTWARE. When I compile the service as x86 and start it, it fails to read the value. When I compile the same code as x64 and start it, it reads the value just fine. I want my service to be able to run on x86 machines in addition to x64 machines, but it needs to also be able to read this value. How do I get my windows service to read the value non-virtualized?

Was it helpful?

Solution

Registry virtualization is disabled for Windows Services. Also, virtualization is disabled for x64 binaries.

Yes, you're right, it's disabled for 64 bit processes and for "processes that are not interactive, such as services".

Take a look to my previous post here on SO for some details about registry views. Please do not confuse views with virtualization. They're different. Views are needed to isolate 32-bit application from 64-bit applications.

In C# you can do the same simply asking the OS to open the 64 bit version of the registry:

RegistryKey baseKey = RegistryKey.OpenBaseKey(
    RegistryHive.LocalMachine, RegistryView.Registry64);
RegistryKey key = baseKey.OpenSubKey("Software", false);
object value = key.GetValue("");

If your application/service will run in a 32-bit machine you'll always get the normal registry even if you ask for RegistryView.Registry64. When running in a 64-bit machine you'll always get the normal version of the registry (= 64-bit version).

Side question: why do you need to compile your application as X86 or X64? Can't simply keep AnyCPU?

Virtualization has a different purpose and it's not intended to separate the registry from 32 bit applications but to increase compatibility with legacy applications, we all hope that a 64 bit native application will use the registry in the correct way. To access the non-virtualized version of the registry you have to open the registry key using REG_KEY_DONT_VIRTUALIZE flag. It's not possible to use this flag with Microsoft.Win32 classes so you have to DllImport them and P/Invoke.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top