Accessing Registry on windows 7 C# - c#

I am attempting to make an updater program, that when updates it writes a build number into the windows 7 registry which the main program reads when checking for updates. I've gone through the UAC virtualization kb at microsoft's page, and have found nothing. My app.manifest has
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
and yet, when i look in HKEY_Local_Machine\Software the build entry is not there, i dont even see it in HKEY_USERS\_Classes\VirtualStore\Machine\Software either.
the code i'm using to enter into registry is
Registry.LocalMachine.CreateSubKey("SOFTWARE\\build");
RegistryKey myKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\build", true);
myKey.SetValue("build", "3", RegistryValueKind.String);
any ideas/suggestions?

If your application is targetting x86 platforms, when running on an x64 system, it will use the corresponding registry node with the following names:
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\ or HKEY_CURRENT_USER\SOFTWARE\Wow6432Node.
So, if you set platform target to x86 for your build, on x86 systems it will go under HKEY_LOCAL_MACHINE\SOFTWARE whereas on x64 systems it will go under HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node which is a reserved node for applications running on WOW64(Windows 32-bit on Windows 64-bit) mode.
For more information see Registry Reflection

Related

Edited the registry with C# but cannot find the change with regedit

I changed my registry via C# with the following code:
RegistryKey regKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32);
RegistryKey openSubKey = regKey.OpenSubKey(#"SOFTWARE\ASA\Suite", true);
openSubKey?.SetValue("Password", encryptedString, RegistryValueKind.String);
openSubKey?.SetValue("UserName", UserNameTextBox.Text, RegistryValueKind.String);
openSubKey?.SetValue("DomainName", DomainNameTextBox.Text, RegistryValueKind.String);
openSubKey?.Close();
regKey.Close();
These entries did already exist and were only replaced. When I use the same kind of code to read the settings I get the correct settings back, BUT when I open the registry with regedit.exe and search for it manually I find only the old values. In the regedit.exe it is this path: Computer\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\ASA\Suite
I already looked into the path without WOW6432Node (and even in the HKCU) but there is no ASA entry at all.Has someone an idea what that could be? Why don't I see the changes I made? I am completly puzzled here...
EDIT: I changed my project from anyCPU to x86 and no change, but as soon as I changed it to x64 the keys read were the ones that regedit.exe shows. But I open the 32bit variant of the registry hive, and when I write something here the question persists... why can't I see the changes made? A x86 app under x64 Windows should automatically write to the WOW6432Node, shouldn't it?
EDIT2: I tested the x86 version on an x86 Windows. I change the registry and can read it, but with regedit I cannot see the changes... wtf is this?
EDIT3: I found the changed keys under HKCR\VirtualStore\MACHINE\SOFTWARE\ASA\Suite I don't know why yet, but I search for an answer and post it here.
May be somebody else is overwriting it ?
May be this can help?
http://www.advancedinstaller.com/user-guide/registry-wow6432-node.html
The Wow6432Node registry entry indicates that you are running a 64-bit Windows version.
The operating system uses this key to display a separate view of HKEY_LOCAL_MACHINE\SOFTWARE for 32-bit applications that run on 64-bit Windows versions. When a 32-bit application writes or reads a value under the HKEY_LOCAL_MACHINE\SOFTWARE\\ subkey, the application reads from the HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\\ subkey.
A registry reflector copies certain values between the 32-bit and 64-bit registry views (mainly for COM registration) and resolves any conflicts using a "last-writer-wins" approach.
Ok, I have the answer. I didn't wanted to use a manifest so I removed it and thus didn't got asked if the app had to be elevated. So, because a normal user (even if the logged in user had admin rights) can't write to the HKLM, it wrote a key to HKCU\VirtualStore... that way my app could also read the keys but in the regedit.exe it was not where it was expected.
To get around this I implemented a manifest and changed the line with the requestedExecutionLevel:
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
Now I don't even have to build an x64 and an x86 version but can use Any CPU instead and let my app do the work (i.e.: to look if to use the RegistryView.Registry32 or RegistryView.Registry64)

My registry key doesn't exist when query through my VB.NET application [duplicate]

Can anyone tell me why I can't access the registry key of "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData"?
if I query the GetSubKeysNames of "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer" it only returns one value being "Secure" ----> Where are all the other subkeys?
Thanks.
High odds that you are running your program on the 64-bit version of Windows and it is forced to run in 32-bit mode. The registry redirector will make you actually read the keys in HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node. And yes, that one also has a Microsoft\Windows\CurrentVersion\Installer key but it is pretty empty. Use Regedit.exe to compare.
The simplest fix is to remove the forcing. Project + Properties, Build tab, set the Target platform setting to AnyCPU. If you have VS2012 and up then untick the "Prefer 32-bit" option. Repeat for the Release configuration. If you must run in 32-bit mode then you can use the .NET 4+ RegistryKey.OpenBaseKey() method, passing RegistryView.Registry64.

UAC prompting on startup program with "asInvoker" on the "requestedExecutionLevel"

I am developing a very simple C# Windows Application (it only displays a message box saying "UACtest") that I want it to run at startup without prompting UAC.
For that I created a registry key for it under HKCU, and in the machine that I compiled it (Windows 8 64-bit using Visual Studio 2013) it runs at startup without promping UAC, as expected.
However, if I export the executable to a Windows 7 machine and do exactly the same thing, a UAC prompt is shown at startup.
Please note that the manifest of the executable has "asInvoker" on the "requestedExecutionLevel", the whole manifest is this:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<requestedExecutionLevel level="asInvoker" uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly
Also when I directly double click the executable, it never prompts UAC neither on Windows 7 32-bit or in the Windows 8 64-bit, the UAC prompting problem is only at startup.
I also tried to compile the executable on the Windows 7 32-bit machine (to maybe bypass some compatibility issues) and a strange thing happened, in that machine now UAC is not prompted at startup as expected, however, when I make the test on another machine (Windows 7 64-bit under Virtual Box) it prompted UAC at startup.
This has now really puzzled me, can someone please tell me a way to compile it so that it never prompts UAC at startup on all versions of Windows?
The project properties I used on Visual Studio 2013 are the default ones, except:
*Target framework: 2.0
*Platform target: x86
And the UAC settings on all machines where the default one: "Notify me only when applications try to make changes on my computer (default)"
Moving the executable has caused the destination system to mark the file as coming from a different system, and as a result the destination system will block execution at startup (in case the executable maliciously added itself to the startup).
Removing the block should fix the issue, it can however be avoided altogether if the executable is added to the system by an installer.
How to set up an installer is however a different question.
The problem was the Zone Identifier, which was set to 3, as for all files downloaded from internet.
If anyone else have this problem, just delete the Zone Identifier, for example with this tool:
http://jameskovacs.com/2005/04/11/zonestripper-updated/
And now the program should run at startup without prompting UAC.

Why I can't run the Snipping Tool from WPF?

I've created a WPF Window with a lot of buttons, each of them run a different program. To run MS Word, for instance, I used:
System.Diagnostics.Process.Start("C:\\Program Files (x86)\\Microsoft Office\\Office14\\WINWORD.EXE");
But when I try to run the Windows 7 Snipping Tool the same way it doesn't work. It was supposed to be like this:
System.Diagnostics.Process.Start("C:\\Windows\\System32\\SnippingTool.exe");
I'm sure the path is correct, but always appears a message saying the file wasn't found. I would like to know why is this happening.
Important: I use Windows 7 64 bits.
Use this:
// if the build platform of this app is x86 use C:\windows\sysnative
if(!Environment.Is64BitProcess)
System.Diagnostics.Process.Start("C:\\Windows\\sysnative\\SnippingTool.exe");
else
System.Diagnostics.Process.Start("C:\\Windows\\system32\\SnippingTool.exe");
The problem is in your build platform (x86) and the automatic redirection of the folder C:\Windows\System32\ on 64-bit OS'es.
Basically, for several reasons, in vista/windows 7 64-bit OS'es when a 32 bit application try to access to C:\Windows\System32\ it is automatically redirected to the folder called C:\Windows\SysWOW64\. Hence, you cannot start snippingtool.exe because it is not present in that folder.
The only way is to use C:\Windows\sysnative\ and bypass the redirection.
My psychic debugger tells me that you are running a 32-bit program on a 64-bit version of
Windows, so your call to %WINDIR% (C:\Windows) is actually being re-routed to C:\Windows\SysWOW64.
Use the environment variable instead of hard-coding paths to directories that may move around depending on the environment and/or Windows version..
You should use an environment variable instead. Likely you are running it on a 64 bit system and C:\Windows\System32\ is getting redirected.

TaskDialog in WPF

I am trying to use the TaskDialog but encountering some problems:
I am getting the following error:
Error 1 Could not find file
'Microsoft.Windows.Common-Controls,
Version=6.0.0.0, Culture=*,
PublicKeyToken=6595b64144ccf1df,
ProcessorArchitecture=X86,
Type=win32'. WpfApplicationUnleashed
I have changed my manifest file to as per this link
http://www.nbdtech.com/Blog/archive/2008/06/16/The-Application-Manifest-Needed-for-XP-and-Vista-Style-File.aspx
2) If I use this TaskDialog, I will see if the OS running is windows vista or higher and selectively use/ dont use TaskDIalog, however, is there any difference in TaskDIalog in Vista and Windows 7.I mean will have to filter windows vista and windows 7 also ?
Are you running your app under the debugger? If so, try running it without the debugger i.e. press Ctrl+F5, or run it from Explorer. If it works without the debugger, then the problem is because of the Visual Studio hosting process, which is a special process which the debugger uses to host your real application when debugging to speed various things up.
To work around this, create a second copy of your manifest file called YourApp.vshost.exe.manifest in your project, and set it 'Copy to Output' to 'Copy if newer'.

Categories

Resources