I am trying to create a key in the uninstall entry in the registry in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall but when I run the code it instead creates it in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Wow6432Node\Microsoft\Windows\CurrentVersion, I don't understand where it could be getting this path from.
Below is the code that I am using
private void addToRegistry(string installPath)
{
using (RegistryKey parent = Registry.LocalMachine.OpenSubKey(#"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", true))
{
if (parent == null)
{
MessageBox.Show("Failed to open registry key. Installation cannot continue", "Registry Error",
MessageBoxButton.OK, MessageBoxImage.Error);
}
try
{
RegistryKey key = null;
string appParent = "Boardies Email Server";
parent.CreateSubKey(appParent);
key = parent.OpenSubKey(appParent);
//key = parent.OpenSubKey(appParent, true) ??
// parent.CreateSubKey(appParent);
if (key == null)
{
MessageBox.Show("Failed to add registry entry. Error: nInstallation Aborted", "Registry Error",
MessageBoxButton.OK, MessageBoxImage.Error);
throw new Exception();
}
Assembly asm = GetType().Assembly;
Version version = asm.GetName().Version;
string exe = string.Format("{0}\\EmailServer.exe", installPath);
}
catch (Exception ex)
{
MessageBox.Show(string.Format("Failed to install, unable to insert into registry: {0}\n\nInstallation Aborted", ex.Message),
"Registry Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
Thanks for any help you can provide.
Probably, your application is 32 bits, in Windows x64 the Register is virtualized so 32 bits and 64 bits apps can coexist and use the same register keys; so your app sees that is writing in this path:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
But is really writing on this path:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Wow6432Node\Microsoft\Windows\CurrentVersion
So in theory if you require such key from another 32 bits app, there should not be problems as it will also see this path as.
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
It is a Registry Redirector.
Try using the RegistryView Enumeration for RegistryKey.OpenBaseKey Method, see the RegistryView.Registry64 enum member.
By the way, you can allow your program to run as a 64-bit process so there would be no redirection: Project => Properties => Build tab: change Platform target to AnyCPU.
That's because you have to change the value at the correct top level. You can identify the correct location with autoruns.exe. It will point you to the right location!
(see example below in which I disabled a file system check when Windows boots up)
This tool not only locates all startup registry keys, but all other services as well, including 3rd party installs!
Related
I am writing a 64-bit C# Windows forms application that will run under Windows PE 10 64-bit to pull the Display Name from Active Directory. I have to use 64-bit because the PCs I am running this on will only boot UEFI so I cannot boot into a 32-bit recovery environment. Every time my code reaches a certain spot, I receive the error message: Unknown Error [0x80005000]. If I compile this and run in 32-bit Windows PE 10, it runs fine, with no modification to the code other than compiling 32-bit.
I am using VS2019 and the code is using .NET v4.7.
Below is the code that I am using:
using (PrincipalContext ad = new PrincipalContext(ContextType.Domain,
"dotted.domain.com", "OU=Users,DC=dotted,DC=domain,dc=com",
ContextOptions.Negotiate, main.interactiveUser, main.interactivePwd))
{
try
{
//this is where it fails
using (UserPrincipal wantedUser = UserPrincipal.FindByIdentity(ad, combo1.Text))
{
if (wantedUser != null)
{
givenName = wantedUser.DisplayName;
}
else
{
MessageBox.Show("User name not found in AD. Please locate manually",
"Error finding name", MessageBoxButtons.OK, MessageBoxIcon.Error);
givenName = "DisplayNameNotFoundInAD";
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
break;
}
}
Here are the meanings of my variables:
dotted.domain.com = the name of my domain
main.interactiveUser = user name to log into the domain with from another form
main.interactivePwd = password for said user name
combo1.Text = text from combo box that has the user name I want to search for
wantedUser = user name of the person I want the display name for
givenName = display name for the user name I am searching for
I have tried it with and without the OU=Users with the same result. It also works fine if I am running in Windows normally. I found some other posts about possibly editing the registry with owner info, that made no difference.
Any ideas on why this is happening?
Had a similar issue accessing the registry in 64-bit WinPE in the past. From my understanding it is exactly what PrincipalContext does.
In my case, I had to uncheck
prefer 32-bit
on the build-tab in VS.
PS: Would have commented only, but currently I'm not on enough reputation
I have created an application(windows) compiled with .NET 4.6.1 and used the FolderBrowserDialog object. When a button is pressed I execute this code:
FolderBrowserDialog folderbrowserdialog = new FolderBrowserDialog();
folderbrowserdialog.Description = "Custom Description";
if (folderbrowserdialog.ShowDialog() == DialogResult.OK)
{
filePath = folderbrowserdialog.SelectedPath ;
}
what i get from the folderbrowserdialog(like foto)
however ,the folder browserdialog is not showing the networks shared folder(that the purpose of my app) otherewise just the pc folders.
but what i want to get it is the network shared folders which could i also access from windows 10 like foto here:
notes to be marked:
i could not use the open file dialog cause i need the folder location.
i desgined the Appto be opened just like admin by adding manisfest so the app is always starting like admin.
the app should be comptiable with windows 10,7
note i know that i could try setting this registry option (could be broken in Win10):
HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows/CurrentVersion/Policies/System
EnableLinkedConnections=1
but it does not make a sense to add this registry by every customer PC
so is there any tipps to show the network shared folders in FolderBrowserDialog ?
Finally after reading many topics i found that the only solution is to add a Registry key programmatically so here how to add specfic C# Registry Subkey with dword value:
i wrote a method wich could all use it
just to let you know after using it you have to restart the device after it ,it will work ;)
public void ConfigureWindowsRegistry()
{
RegistryKey localMachine = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry64); //here you specify where exactly you want your entry
var reg = localMachine.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", true);
if (reg == null)
{
reg = localMachine.CreateSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", true);
}
if (reg.GetValue("EnableLinkedConnections") == null)
{
reg.SetValue("EnableLinkedConnections", "1", RegistryValueKind.DWord);
MessageBox.Show(
"Your configuration is now created,you have to restart your device to let app work perfektly");
}
}
I had the same issue. The reason of the problem: I was using as an Administrator. The mapped drives are related to the user, so I tried to use as an normal user and I could see the mapped drives.
I want to modify a data in registry path SOFTWARE\Wow6432Node\Program\SubProgram using C# code in windows 7. I am able to read the value but I can't write into Registry.
Here is the code:
RegistryKey SUBKEY;
RegistryKey TAWKAY = RegistryKey.OpenRemoteBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, "");
string subkey = "SOFTWARE\\Wow6432Node\\Program\\SubProgram ";
if (TAWKAY.OpenSubKey(subkey) != null) // Get values from Registry
{
TAWKAY = RegistryKey.OpenRemoteBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, "");
SUBKEY = TAWKAY.OpenSubKey(subkey); // subkey opens
SUBKEY = TAWKAY.OpenSubKey(subkey,true); // subkey not open shows error Requested registry access is not allowed
SUBKEY.SetValue("Some name", "1234567890");
Console.WriteLine(SUBKEY.GetValue("Some name").ToString());
}
else
{
Console.WriteLine("Cannot open registry");
}
Console.Read();
If I set OpenSubKey(subkey, true), it shows an error message Requested registry access is not allowed
Is there any permission needed to write into registry?
Please help me to solve the issue
Wow6432Node is not a real path in the registry. It is an alias for 32 bit keys in 64 bit OS.
You must use RegistryView.Registry32 in order to specify you want to work with 32 bits.
RegistryKey reg32key = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32);
RegistryKey reg_32bit_AppKey = reg32key.OpenSubKey(#"SOFTWARE\Program\SubProgram");
if (reg_32bit_AppKey != null)
{
// Here you can work with "SOFTWARE\\Wow6432Node\\Program\\SubProgram "
}
Modifying/deleting/adding keys in HKLM requires administrator rights.
In that case you want to do that you will need to change your applications manifest requestedExecutionLevel value to requireAdministrator
It is better to use "Reg" command inorder to perform any operation on registry.
Even though if you want to access the registry of remote machine you don't nedd credentials of that machine, having the machine name is sufficient.
For more information about "REG" command refer to the following link
http://technet.microsoft.com/en-us/library/cc732643(v=ws.10).aspx
I am trying to read registry keys from folder "HKLM\SOFTWARE\Microsoft.NETFramework\v4.0.30319"
Folder contains two keys SKUs and AssemblyFoldersEx. First key is successfully readed, but second is failed (return null).
How to fix this?
C# code:
class Program
{
static void Main(string[] args)
{
Microsoft.Win32.RegistryKey rkey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(#"SOFTWARE\Microsoft\.NETFramework\v4.0.30319\SKUs", false); // success
Microsoft.Win32.RegistryKey rkey2 = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(#"SOFTWARE\Microsoft\.NETFramework\v4.0.30319\AssemblyFoldersEx", false); // failed (returns null)
}
}
Open your project in VS and go to Properties > Build then change Platform target to Any CPU then recompile. I suspect your Platform target is x86 and you are running on a 64 bit version of Windows.
Wow6432Node branch of the registry will get you every time :)
I'd like to know where the installation path for an application is. I know it usually is in ...\Program Files... but I guess some people install it in different locations. I do know the name of the application.
Thank you.
The ideal way to find a program's installation path (on Windows) is to read it from the registry. Most installers will create a registry key for that program that contains the installation path. Exactly where this key is and what it will be named varies depending on the program in question.
To find if the program has a key in the registry, open 'regedit' and use the Edit > Find option to try and locate a key with the program name. If such a key exists, you can read it using the RegistryKey class in the .NET Framework library.
If the program does not have a registry key then another option is just to ask the user to locate the .exe file with the OpenFileDialog, although this is obviously not ideal.
Many (most?) programs create an App Paths registry key. Have a look at
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths
If you know the application in question (as compared to any application) registry key is the probably the best option (if one exists).
The install might put in its own custom "install path key" somewhere (so do a find as Fara mentioned) or it might be in the uninstall section for installed programs, so you could check:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
But be aware that any new version of an install could change the key it writes out, both for a custom key or for the uninstall entry. So checking the registry should probably be only for a known install\version.
tep
Best way is to use Installer APIs to find the program location.
You can write a Managed wrapper over the APIs
Search for MsiGetProductInfo
Reference: http://msdn.microsoft.com/en-us/library/aa369558(VS.85).aspx
You can use MSI (I wrote a C# wrapper for it here https://github.com/alialavia/MSINet). Here is a simple example:
var location = "";
foreach (var p in InstalledProduct.Enumerate())
{
try
{
if (p.InstalledProductName.Contains("AppName"))
{
location = p.InstallLocation;
break;
}
}
catch { }
}
Take a look in the registry.
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\
or
HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\
Each of the above contain a list of sub-keys, one for each installed application (as it appears, for example, in the "Programs and Features" applet)
You can search for your application there, or if you know the product code, access it directly.
public string GetInstallPath(string applicationName)
{
var installPath = FindApplicationPath(#"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", applicationName);
if (installPath == null)
{
installPath = FindApplicationPath(#"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall", applicationName);
}
return installPath;
}
private string FindApplicationPath(string keyPath, string applicationName)
{
var hklm = Registry.LocalMachine;
var uninstall = hklm.OpenSubKey(keyPath);
foreach (var productSubKey in uninstall.GetSubKeyNames())
{
var product = uninstall.OpenSubKey(productSubKey);
var displayName = product.GetValue("DisplayName");
if (displayName != null && displayName.ToString() == applicationName)
{
return product.GetValue("InstallLocation").ToString();
}
}
return null;
}