I use this code to get the installed .NET Version on a remote machine. With Windows 7 it works perfect but with Windows 10 the following exception throws
System.Security.SecurityException: Requested registry access is not allowed.
The user with i connect, is in the Administrators Group
The Service "RemoteRegistry" is set to Startup type "Manual"
Code example
using (RegistryKey remoteHklm = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, hostName))
{
using (RegistryKey serviceKey = remoteHklm.OpenSubKey(#"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full", true))
{
if (serviceKey != null)
{
version = serviceKey.GetValue("Version").ToString();
}
else
{
version = "error on get version from registry";
}
}
}
You have with Windows 10 no write Access to this registry key. Change the second OpenSubKey parameter to false, you can check in Registry Editor the permission of the key.
using (RegistryKey serviceKey = remoteHklm.OpenSubKey(#"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full", false))
Related
I want to get underlying machine OS info along with its other details in C# .NET Code.
When ran the below code on Windows 10 Pro machine, it returns the wrong value as "Windows 10 Enterprise".
Registry.GetValue(#"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion", "ProductName", "").ToString();
Is there any other key to be queried on Registry? Else it has manually interpreted through its minor & major version details?
It requires explicitly to be queried on a 32-bit or 64-bit registry depending upon your system.
This solution does not use any hacks to get the OS Edition. It gives exact same value which you can see in the registry when you navigate to the path.
Eg. In my case it returns, "Windows 10 Pro"
RegistryKey localKey = null;
if (Environment.Is64BitOperatingSystem) {
localKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine,
RegistryView.Registry64);
} else {
localKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine,
RegistryView.Registry32);
}
var productName = localKey.OpenSubKey(# "SOFTWARE\Microsoft\Windows
NT\CurrentVersion").GetValue("ProductName").ToString();
Console.WriteLine("ProductName : " + productName);
I'm finishing a application in C# which contains a SQL Server database.
How can I check if the user has SQL Server 2012 Express Local DB installed?
Is it possible to check via registry both on x86, x64?
Basically the idea is if the user does not have SQL Server installed, the application advise to install it.
As the installer I'm working for setup does not have dependencies for SQL Server 2012 Express Local DB.
Thanks.
You'll have to loop through the Uninstall GUIDs and find one that starts with keyword "Microsoft SQL Server 2012". You can find it by going to Control Panel > Programs and Features > and look at the "Display Name" column.
//HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall{guidVariable}\DisplayName
.. should match the "Microsoft SQL Server 2012*" wild card.
I don't have the exact code, but this should get you started. Just loop through all children of the "Uninstall" key, and then find the "DisplayName" key by getting the value. The "GUID" variable below should be your iterator, since you do not know that value. I'm sure you can get a list of all of the GUID values that are sub keys of "Uninstall" key.
string UninstallRegKeyPath = #"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
Guid UninstallGuid = new Guid(GUID);
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(UninstallRegKeyPath, true))
{
if (key == null)
{
return;
}
try
{
string guidText = UninstallGuid.ToString("B");
RegistryKey child = key.OpenSubKey(guidText);
if (child != null)
{
string displayName = child.GetValue("DisplayName").ToString();
if (displayName.Contains("Microsoft SQL Server 2012"))
{
// implement logic when MSSQL 2012 is found
}
child.Close();
}
}
}
Just be cautious. There are both 32 bit installations and 64 bit installations. Wow6432Node contains the 32 bit programs I believe, so everything installed in C:\Program Files (x86)\ by default (but may be anywhere). And there is the other location, which I'll let you find, for all of the 64 bit programs, which are installed in C:\Program Files\ by default (and again may be installed anywhere).
EDIT:
Try this. You may also want to replace "LocalMachine" with "CurrentUser" since many installers let you configure them for your user, or all users.
using (RegistryKey root = Registry.LocalMachine.OpenSubKey(#"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"))
{
string searchKey = #"Microsoft SQL Server 2012";
string subKeyName = "DisplayName";
foreach (string keyname in root.GetSubKeyNames())
{
//Console.WriteLine(keyname);
using (RegistryKey key = root.OpenSubKey(keyname))
{
try // in case "DisplayName doesn't exist
{
string displayName = key.GetValue(subKeyName).ToString();
if (displayName.StartsWith(searchKey))
Console.WriteLine("GUID: " + keyname + Environment.NewLine + displayName + Environment.NewLine);
}
catch
{
}
}
}
}
Console.ReadLine();
I'm getting reported errors from users who are receiving the error "System.Security.SecurityException, Requested registry access is not allowed." when trying to read the registry. I can't think why someone would not have permission to read the registry and I'm unable to reproduce the problem on my Windows 7 PC. Affected users are running .NET 4.0
Here's the C# code I'm using:
var baseReg = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32);
var key = baseReg.OpenSubKey(RegKey, RegistryKeyPermissionCheck.ReadSubTree);
if (key != null)
{
var value = key.GetValue("DisableAutoUpdate", 0);
if (value != null)
{
updatesDisabled = Convert.ToBoolean(value);
}
}
EDIT:
I've checked permissions on the registry key concerned for the affected user and standard Users have read permission for that key.
EDIT 2 and SOLUTION:
According to the affected user, installing .NET 4.5.2 resolves the problem! I'm not sure why.
Thanks to #nozzleman's answer below this is fixed by forcing it to open the key as read-only. However it's odd that .NET 4.0 as 4.5.2 appear to behave differently.
There is an overload of the OpenSubKey(..)-Method that allows to add a third parameter. You could try passing RegistryRights.ReadKey with that one and see if that solves the issue.
baseReg.OpenSubKey(
RegKey,
RegistryKeyPermissionCheck.ReadSubTree
RegistryRights.ReadKey);
Alternatively, try the other overload accepting 2 parameters like so
baseReg.OpenSubKey(RegKey, false);
This leads to opening the subkey readonly, and you dont neet to read the whole sub tree in the given szenario..
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 want to change Enable32BitAppOnWin64 property using C#. I know that the way of interacting with IIS 6 and IIS 7 are different. but I need the solution for both versions.
There are a few differences in programmatically managing IIS 6 and IIS 7.
IIS 6 is programmatically managed using the DirectoryEntry class and the metabase database API.
IIS 7 is managed using the Microsoft.Web.Administration assembly
and the ServerManager class.
Furthermore IIS 6 is not able to run both 64 bit and 32 bit worker processes
at the same time (see this MSDN BLOG).
So setting Enable32BitAppOnWin64 to true for IIS 6 means that all worker
processes (all application pools) are running as 32 bit processes.
IIS 7 is capable of running 64 bit and 32 bit worker processes at the same time.
This means that you set Enable32BitAppOnWin64 for a specific application pool
and not for all application pools.
You also have to detect the version of IIS in order to use the correct API.
This can be done by reading the following DWORD values from the registry
(for more information see Learn IIS):
HKLM\Software\Microsoft\InetStp\MajorVersion and
HKLM\Software\Microsoft\InetStp\MinorVersion
So, here is some code to set Enable32BitAppOnWin64 for IIS 6 and IIS 7
(please note that you have to reference the Microsoft.Web.Administration
and System.DirectoryServices assemblies in your Visual Studio project):
private static Version GetIISVerion()
{
using (RegistryKey inetStpKey =
Registry.LocalMachine.OpenSubKey(#"Software\Microsoft\InetStp"))
{
int majorVersion = (int)inetStpKey.GetValue("MajorVersion");
int minorVersion = (int)inetStpKey.GetValue("MinorVersion");
return new Version(majorVersion, minorVersion);
}
}
private static void Enable32BitAppOnWin64IIS7(string appPoolName)
{
Console.Out.WriteLine("Setting Enable32BitAppOnWin64 for {0} (IIS7)", appPoolName);
using (ServerManager serverMgr = new ServerManager())
{
ApplicationPool appPool = serverMgr.ApplicationPools[appPoolName];
if (appPool == null)
{
throw new ApplicationException(String.Format("The pool {0} does not exist", appPoolName));
}
appPool.Enable32BitAppOnWin64 = true;
serverMgr.CommitChanges();
}
}
private static void Enable32BitAppOnWin64IIS6(string serverName)
{
Console.Out.WriteLine("Setting Enable32BitAppOnWin64 for IIS6");
using (DirectoryEntry appPools =
new DirectoryEntry(String.Format("IIS://{0}/W3SVC/AppPools", serverName)))
{
appPools.Properties["Enable32BitAppOnWin64"].Value = true;
appPools.CommitChanges();
}
}
public static void Enable32BitAppOnWin64(string serverName, string appPoolName)
{
Version v = GetIISVerion(); // Get installed version of IIS
Console.Out.WriteLine("IIS-Version: {0}", v);
if (v.Major == 6) // Handle IIS 6
{
Enable32BitAppOnWin64IIS6(serverName);
return;
}
if (v.Major == 7) // Handle IIS 7
{
Enable32BitAppOnWin64IIS7(appPoolName);
return;
}
throw new ApplicationException(String.Format("Unknown IIS version: {0}", v.ToString()));
}
static void Main(string[] args)
{
Enable32BitAppOnWin64(Environment.MachineName, "DefaultAppPool");
}
I should also mention that there is a possibility to use the metabase API
for IIS 7, too. On Windows Server 2008 operating systems you can
install a role service called "IIS 6 Management Compatibility". This
role service enables you to use the "old" IIS 6 API to manage IIS 7.
If "IIS 6 Management Compatibility" is an option for you change the
function Enable32BitAppOnWin64IIS7 as follows:
private static void Enable32BitAppOnWin64IIS7(string serverName, string appPoolName)
{
Console.Out.WriteLine("Setting Enable32BitAppOnWin64 for {0} (IIS7)", appPoolName);
using (DirectoryEntry appPools =
new DirectoryEntry(String.Format("IIS://{0}/W3SVC/AppPools/{1}", serverName, appPoolName)))
{
appPools.Properties["Enable32BitAppOnWin64"].Value = true;
appPools.CommitChanges();
}
}
Of course, then you do not have to reference the Microsoft.Web.Administration assembly.
Rather than trying to reproduce someone elses answers, heres a link to a previous asker and the answers they received. I hope they are helpful.
IIS Application Pool: change settings programmatic