Registry and Wow6432Node on C# - c#

I´m trying to access a path in the registry inside Wow6432Node, to write a value inside it, but it is not working. I tried with different codes, but it´s still not working. I am running it as "Any CPU" on a x64 bit Windows 10. I suspect it has something to do with the difference on the registry between x86 and x64. Am I wrong?
if (rv3.Checked == true)
{
string line2 = File.ReadLines(AppDomain.CurrentDomain.BaseDirectory + "simulators.txt").Skip(3).Take(1).First();
MessageBox.Show(line2);
if (System.IO.Directory.Exists(line2))
{
var baseReg = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
var Key = baseReg.OpenSubKey(#"SOFTWARE\Wow6432Node\Microsoft\Microsoft Games\flight simulator\10.0\");
if (Key != null)
{
RegistryKey key2 = baseReg.OpenSubKey(#"SOFTWARE\Wow6432Node\Microsoft\Microsoft Games\flight simulator\10.0\");
key2.SetValue("SetupPath", line2);
key2.Close();
}
}
}
Kind regards!

I ran into similar issues when working with the registry, and I suspect you're a victim of "virtualization".
On a machine with User Account Control (UAC) you aren't strictly denied permission to write to the registry, but the calls get virtualised. See if the values you are expected to see are turning up at HKEY_USERS\<User SID>_Classes\VirtualStore\Machine\Software\.
The solution is to add an application manifest file to the solution, and set requestedExecutionLevel level="requireAdministrator", which means whenever you run the application on a machine with UAC it will ask "Are you sure?". You also need to ensure the project properties specify the manifest to use.
I then ran into a second problem, which is that when you're debugging through Visual Studio, it will run with VS execution level, not those specified in the manifest (see here). The easiest solution is to set VS to run as Administrator in the shortcut properties.

Related

C# HKEY_LOCAL_MACHINE Registry edit working in VS (Debug) but not when published to .exe

I have a requirement for an application to "run on start-up" for all users. This has to be setup by the application it's self, not by a user adding a shortcut to start-up folder or something similar. I have managed to get this to work by adding the .exe path to the registry Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run. The following code successfully adds the path to the registry when in debug mode and visual studios is run as administrator.
using Microsoft.Win32;
var path = #"SOFTWARE\Microsoft\Windows\CurrentVersion\Run";
try
{
string baseDir = "EXAMPLE_DIR";
using (RegistryKey? key = Registry.LocalMachine.OpenSubKey(path, true))
{
if (key is not null)
{
string exePath = $#"{baseDir}\iOK2.exe";
key.SetValue("iOK2", exePath);
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
However the same code fails to add to the registry when it has been "Published" to an an executable (.exe) file.
The code doesn't produce any errors, it seemingly executes and exists successfully. I have tried running as admin, creating an app.manifest and requiring admin, ensured it's compiled to 64-bit and is accessing the correct registry
Any ideas on what is happening or something I'm missing? If this fails I could potentially call a PowerShell script to edit the registry, but would rather keep dependencies to a minimum if at all possible

access to the registry key is denied When i want update the value

i want edit Registry key called "usbstor" value and this my code in update method
try
{
string path = baseRegistryKey + "\\" + SubKey;
Registry.SetValue(path, KeyName, KeyValue, RegistryValueKind.DWord);
return true;
}
catch (Exception e)
{
// AAAAAAAAAAARGH, an error!
ShowErrorMessage(e, "Writing registry " + KeyName.ToUpper());
return false;
}
and path="HKEY_LOCAL_MACHINE\system\currentControlset\services\usbstor" keyname="start" When i run the code i'll get "Access to the registry key 'HKEY_LOCAL_MACHINE\system\currentControlset\services\usbstor' is denied"
what is probelm?
Executable
HKEY_LOCAL_MACHINE is always protected space in registry, so you need to either elavate privilliges to those of at least Power User or run your executable As Administrator (the one built from your solution, should be in ./bin folder) or disable UAC. Either way it will be troublesome inside Visual Studio as long as you don't have either way configured/set.
Note that if you try to use Run.. -> regedit you are also prompted by UAC, so that's not only restriction for your app but for access to registry per se.
Inside Visual Studio
Elevating Visual Studio before opening to Run as administrator is sufficent to edit registry from code.
Application manifest
For future usage you might want to create app.manifest and set your application to always require administrator privileges.
Right click on your project in Solution Explorer, then: Add -> New Item... -> Application Manifest File.
Inside your newly created application manifest, change the line:
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
to line
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
From now on it will always prompt UAC if not run as administrator.
If you run Visual Studio as not administrator, it will attempt to restart IDE as administrator, prompting to do so before proceeding.
An alternative solution is to change the permissions on the registry key. Open the key using Regedit, right click and select 'Permissions'. Either add the profile that your application runs under (ie a service account) or select an existing group (ie Users) and grant them full access. This way you're not having to grant elevated privileges which is always a security concern.

Monitor GAC changes in registry with WMI - RegistryKeyChangeEvent GACChangeNotification Not Found

I'm trying to monitor the registry for changes to the GAC using WMI. I have the following code:
WqlEventQuery query = new WqlEventQuery(#"SELECT * FROM RegistryKeyChangeEvent WHERE Hive = 'HKEY_LOCAL_MACHINE' AND KeyPath='SOFTWARE\\Microsoft\\Fusion\\GACChangeNotification\\Default'");
_regWatcher = new ManagementEventWatcher(query);
_regWatcher.EventArrived += new EventArrivedEventHandler(_regWatcher_EventArrived);
_regWatcher.Start();
But when it calls Start(), it causes a ManagementException with the message "Not Found". I copied the key path from the registry so I know it exists. I have never done this before, so maybe I'm misusing it. I want to receive notification when any value is changed in the Default key (specifically when a value is added). Why is it giving the "Not Found" exception and how do I correctly monitor this key for changes using WMI?
You are surely yet another victim of the registry redirector in the 64-bit version of Windows. Project + Properties, Build tab, change the Platform target setting from x86 to AnyCPU. On VS2012 and up, untick the "Prefer 32-bit" checkbox.
Your program will now as a 64-bit process and can properly see the registry key. Instead of the HKLM\Software\Wow6432Node subkey you tried to look at before.

File exists in Windows Explorer and notepad, but is not accessable in my program

Why does the following problem happen?
Scenario:
Make sure that IIS is installed
Execute "notepad
%WINDIR%\System32\inetsrv\config\applicationHost.config" using admin
account
Actual Result: the file is successfully opened in notepad
Execute the following code in admin account's context:
string filePath = #"%WINDIR%\System32\inetsrv\config\applicationHost.config";
Console.WriteLine(File.Exists(Environment.ExpandEnvironmentVariables(filePath)));
Actual Result: False
Expected Result: True
The problem is if you are running a 32-bit application on a 64-bit OS, the .Net framework automatically redirects the request from %WINDIR%\System32 to %WINDIR%\SysWOW64.
If you change your project to target 64-bit, this will solve your problem.
You can also resolve the problem by changing System32 to sysnative, but only if you leave the application as a 32-bit app:
string filePath = #"%WINDIR%\sysnative\inetsrv\config\applicationHost.config";
This might be due to file system redirection. AFAIK t happens either for 32/64 bit mismatch or in case of low-privilege (UAC) processes.
I know of now way of disabling that behavior using managed APIs. You need to use http://msdn.microsoft.com/en-us/library/windows/desktop/aa365743(v=vs.85).aspx and/or be a high privilege process.
If you change your project to target 64-bit, this is likely to solve your problem.
I can't reproduce your result. When I run this from an administrator command line prompt, I get exists = True.
string s = #"%WINDIR%/System32\inetsrv\config\applicationHost.config";
bool exists = File.Exists(Environment.ExpandEnvironmentVariables(s));
Console.WriteLine("exists = {0}", exists);
I'm running Windows Server 2008, 64-bit. .NET 4.0.

How to get list of all startup processes from Registry using C# on Windows 7 64 bit?

Hi guys I have a strange issue.
I am trying to get list of all startup programs from Registry - LocalMachine,CurrentUser, subkeys Run, RunOnce, RunOnceEx. And after that I can get list of links in Startup folder
For Win64 I found that startup programs are in this key
LocalMachine/Software/Wow6432Node/Microsoft/Windows/CurrentVersion/Run
The problem is in this code, running it I get List of apps which are in different Subkey LocalMachine\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Run instead of the described bellow LocalMachine\Software\Microsoft\Windows\CurrentVersion\Run
Is that normal?
Microsoft.Win32.RegistryKey key;
key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Run", false);
foreach (string appName in key.GetValueNames())
{
try
{
MessageBox.Show(appName);
}
catch (Exception ex)
{
}
}
I tryed using this WMI solution but it didnt get all startup apps. That's why i decided to get them manually from the Registry.
Is this script correct and why it doesn't do what it is supposed to do?
Is there any other way to get all startup apps and processes?
Thanks
On a 64-bits windows OS, there are 2 distinct HKLM\Software hives. One for 64-bits apps (which is HKLM\Software) and one for 32-bits apps (which is HKLM\Software\Wow6432Node when viewed from a 64-bits apps. It is viewed as HKLM\Software for a 32-bits apps).
If you compile your .Net application as MSIL or x64, you could access the 32-bit software hive by adding Wow6432node to the registry path.
Otherwise, you could also compile as x86 and run in 32-bits.
Hope this help

Categories

Resources