views:

2373

answers:

4

To pop up the UAC dialog in Vista when writing to the HKLM registry hive, we opt to not use the Win32 Registry API, as when Vista permissions are lacking, we'd need to relaunch our entire application with administrator rights. Instead, we do this trick:

ShellExecute(hWnd, "runas" /* display UAC prompt on Vista */, windir + "\\Reg", "add HKLM\\Software\\Company\\KeyName /v valueName /t REG_MULTI_TZ /d ValueData", NULL, SW_HIDE);

This solution works fine, besides that our application is a 32-bit one, and it runs the REG.EXE command as it would be a 32-bit app using the WOW compatibility layer! :( If REG.EXE is ran from the command line, it's properly ran in 64-bit mode. This matters, because if it's ran as a 32-bit app, the registry keys will end up in the wrong place due to registry reflection.

So is there any way to launch a 64-bit app programmatically from a 32-bit app and not have it run using the WOW64 subsystem like its parent 32-bit process (i.e. a "*" suffix in the Task Manager)?

A: 

Have you considered creating a small "helper" application to make the registry update for you? If you compile it to 64bit and include a manifest that indicates it requires administrator rights, then it'll cover both bases for you.

There are API's to detect the "bitness" of the OS you're running on so you could, conceivably, compile both RegistryUpdate32.exe and RegistryUpdate64.exe and call the relevant one.

Rob
+5  A: 

Whether a 32-bit or 64-bit native (unmanaged) program is run depends solely on the executable. There are two copies of reg.exe, in C:\Windows\System32 (64-bit) and C:\Windows\SysWOW64 (32-bit). Because you don't specify a path, you're getting whatever appears first in the PATH environment variable, which is the 32-bit version for a 32-bit process.

You should really factor this function out into a separate program or COM object, and mark the program with a manifest, or launch the COM object using the COM elevation moniker.

Mike Dimmick
Don't forget that due to file system redirection (or whatever MS calls it), a 32-bit process that tries to open/exec "c:\Windows\System32\foo.exe" will have that file open/exec silently redirected to "C:\windows\SysWow64\foo.exe" unless specific measures are taken to disable the redirection.
Michael Burr
Yep Mike, that's what I noticed after I marked that as an "answer". That is -- I actually *had* written the full "System32" path in my test, so it should have picked the 64-bit version anyway, but didn't. I assumed it was for the reason you point out. :)
Jonas
+1  A: 

try this (from a 32bit process):

> %WINDIR%\sysnative\reg.exe query ...

(found that here).

akira
If this works, that sounds like a nice trick to have in one's bag.
Jason R. Coombs
A: 

The trick with "sysnative" noted above actually works.

Knaģis