Reputation: 323
I have a program coded in C# that opens a cmd console and adds/modifies a registry value.
After the console outputs that the task completed, I test with reg query
if the registry value really changed. There is no problem. I get value 0x1
as expected by me.
But when I query this registry from outside the current cmd window like another cmd executed by me as admin, the value is 0x0
on reg query
.
How is this possible?
Here is my C# code:
string command = @"/K reg add HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock /t REG_DWORD /f /v AllowDevelopmentWithoutDevLicense /d 1";
Process proc = Process.Start("cmd.exe", command);
Query from inside the executed cmd by the program:
reg query HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock
AllowDevelopmentWithoutDevLicense REG_DWORD 0x1
From outside:
reg query HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock
AllowDevelopmentWithoutDevLicense REG_DWORD 0x0
AllowAllTrustedApps REG_DWORD 0x0
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock\AllowDevelopmentWithoutDevLicense
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock\AllowDevelopmentWithoutDevLicense=1
Upvotes: 3
Views: 1129
Reputation: 49096
When a 32-bit application on a 64-bit Windows accesses the registry key
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock
it is redirected by Windows registry redirector to
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\AppModelUnlock
whereby a 64-bit application really accesses
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock
The difference between the two registry paths is Wow6432Node
visible by default only for 64-bit applications on Windows x64.
See the Microsoft developer article Registry Keys Affected by WOW64.
And for completeness see also:
There are 32-bit cmd.exe
and reg.exe
on 64-bit Windows in directory %SystemRoot%\SysWow64
being %SystemRoot%\System32
for 32-bit applications and 64-bit cmd.exe
and reg.exe
in %SystemRoot%\System32
.
Your C# application is most likely compiled as 32-bit application and therefore calls 32-bit cmd.exe
which calls 32-bit reg.exe
.
You could workaround this from within the 32-bit application by calling explicitly %SystemRoot%\Sysnative\cmd.exe
.
But be aware of the fact that %SystemRoot%\Sysnative
does not exist on 32-bit Windows and also does not exist for 64-bit applications on 64-bit Windows. (Sysnative
is a special alias, not a hard link, junction or a real folder.)
Therefore your 32-bit C# application needs first to check if %SystemRoot%\Sysnative\cmd.exe
exists and use this path to edit the 64-bit registry value using 64-bit cmd
and reg
. But on 32-bit Windows %SystemRoot%\System32.exe\cmd.exe
must be called by the 32-bit C# application. By the way: %SystemRoot%
references the value of environment variable SystemRoot.
See also the answers on:
NOTE 1:
Running cmd.exe
is not needed at all. It is possible to run directly on 32-bit Windows
%SystemRoot%\System32\reg.exe
or on 64-bit Windows
%SystemRoot%\Sysnative\reg.exe
from a 32-bit application.
NOTE 2:
And last but not least a C# application does not need to use reg.exe
at all as .NET Framework has built-in support for accessing Windows registry - the Registry.SetValue Method. Microsoft even added some examples in an example code block.
KEY_WOW64_64KEY can be used in a 32-bit application to explicitly access always the 64-bit registry key as explained on Microsoft documentation page Accessing an Alternate Registry View.
Upvotes: 3