I have a requirement to read registry values in HKEY_CLASSES_ROOT and HKEY_LOCAL_MACHINE. But when I am trying to get the subkey object with read access, I get this exception: "Requested registry access is not allowed". ( Note :: In my app i am not doing any write or modifications to registry.)
This error only occurs when I try running from client machine. In my machine, it works well. Since both the machines have administrative access, I think some other thing is causing the problem. I am able to read and edit registry values manually from the client machine.
I have edited manifest file and changed required permissions from asInvoker to requireAdministrator. But no luck. Any workarounds?
Here is my code sample.
public List<SysApps> GetAllApps()
{
List<SysApps> appList = new List<SysApps>();
// The area's we are scanning
appList.AddRange(this.LoadFiles(RegistryHive.CurrentUser, RegistryView.Registry32,
@"Software\Microsoft\Windows\CurrentVersion\Uninstall"));
appList.AddRange(this.LoadFiles(RegistryHive.LocalMachine, RegistryView.Registry32,
@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"));
appList.AddRange(this.LoadFiles(RegistryHive.LocalMachine, RegistryView.Registry64,
@"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"));
return appList.OrderBy(r => r.DisplayName).ToList();
}
private List<SysApps> LoadFiles(RegistryHive reghive, RegistryView regview, string regkeypath)
{
ist<SysApps> appList = new List<SysApps>();
using (RegistryKey regedit = RegistryKey.OpenBaseKey(reghive, regview))
using (RegistryKey regkey = regedit.OpenSubKey(regkeypath, RegistryKeyPermissionCheck.ReadSubTree))
{
if (regkey == null) goto last;
foreach (string subkey in regkey.GetSubKeyNames())
{
if (subkey == null) continue;
using (RegistryKey key = regkey.OpenSubKey(subkey))
{
if (key == null) continue;
SysApps sysapp = new SysApps();
sysapp._displayName = key.GetValue("DisplayName") == null ? string.Empty : (string)key.GetValue("DisplayName");
sysapp._publisher = key.GetValue("Publisher") == null ? string.Empty : (string)key.GetValue("Publisher");
sysapp._installDate = key.GetValue("InstallDate") == null ? string.Empty : (string)key.GetValue("InstallDate");
var decValue = key.GetValue("EstimatedSize") == null ? "0" : key.GetValue("EstimatedSize");
sysapp._estimatedSize = decValue.ToString() == "0" ? string.Empty : AppCommon.GetSize(decValue.ToString());
sysapp._displayIcon = key.GetValue("DisplayIcon") == null ? string.Empty : (string)key.GetValue("DisplayIcon");
if (string.IsNullOrEmpty(sysapp._displayIcon) && !string.IsNullOrEmpty(sysapp._displayName))
sysapp._displayIcon = this.GetIconForRoot(sysapp._displayName);
if (!string.IsNullOrEmpty(sysapp._displayIcon))
sysapp._displayIcon = sysapp._displayIcon.Replace("\"", string.Empty).Trim();
sysapp._displayVersion = key.GetValue("DisplayVersion") == null ? string.Empty : (string)key.GetValue("DisplayVersion");
sysapp._uninstallString = key.GetValue("UninstallString") == null ? string.Empty : (string)key.GetValue("UninstallString");
sysapp._modifyPath = key.GetValue("ModifyPath") == null ? string.Empty : (string)key.GetValue("ModifyPath");
// Validate
var rType = (string)key.GetValue("ReleaseType");
var sComponent = key.GetValue("SystemComponent");
var pName = (string)key.GetValue("ParentDisplayName");
if (!string.IsNullOrEmpty(sysapp._displayName) && string.IsNullOrEmpty(rType) && string.IsNullOrEmpty(pName) && (sComponent == null))
{
AppCommon.FileSize += Int32.Parse(decValue.ToString());
appList.Add(sysapp);
}
key.Flush();
key.Close();
}
}
regkey.Flush();
regkey.Close();
}
last:
return appList;
}
private string GetIconForRoot(string productName)
{
string result = string.Empty;
string installerKey = @"Installer\Products";
bool isFound = false;
using (RegistryKey regedit = RegistryKey.OpenBaseKey(RegistryHive.ClassesRoot, RegistryView.Registry32))
using (RegistryKey regkey = regedit.OpenSubKey(installerKey, RegistryKeyPermissionCheck.ReadSubTree))
{
if (regkey == null) goto last;
foreach (string subkey in regkey.GetSubKeyNames())
{
if (subkey == null) continue;
using (RegistryKey key = regkey.OpenSubKey(subkey))
{
if (key.GetValue("ProductName") != null)
if (productName == key.GetValue("ProductName").ToString())
if (key.GetValue("ProductIcon") != null)
{
isFound = true;
result = key.GetValue("ProductIcon").ToString();
}
key.Flush();
key.Close();
if (isFound) break;
}
}
egkey.Flush();
regkey.Close();
}
last:
return result;
}
Finally I found the answer. I did following changes to my code.
public async Task<List<Apps>> GetAllApps()
{
List<Apps> _installedApps = new List<Apps>();
_installedApps.AddRange(await this.LoadFiles(Registry.CurrentUser,
@"Software\Microsoft\Windows\CurrentVersion\Uninstall"));
_installedApps.AddRange(await this.LoadFiles(Registry.LocalMachine,
@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"));
_installedApps.AddRange(await this.LoadFiles(Registry.LocalMachine,
@"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"));
return _installedApps.OrderBy(x => x.DisplayName).ToList();
}
private async Task<List<Apps>> LoadFiles(RegistryKey rkey, string regkeypath)
{
List<Apps> appList = new List<Apps>();
RegistryKey regkey =
rkey.OpenSubKey(regkeypath,
RegistryKeyPermissionCheck.ReadSubTree,
RegistryRights.ReadKey);
if (regkey == null) goto last;
foreach (string subkey in regkey.GetSubKeyNames())
{
if (subkey == null) continue;
using (RegistryKey key = regkey.OpenSubKey(subkey))
{
if (key == null) continue;
// Validating
var rType = (string)key.GetValue("ReleaseType");
var sComponent = key.GetValue("SystemComponent");
var pName = (string)key.GetValue("ParentDisplayName");
var dName = (string)key.GetValue("DisplayName");
if (!string.IsNullOrEmpty(dName) && string.IsNullOrEmpty(rType) && string.IsNullOrEmpty(pName) && (sComponent == null))
appList.Add(await ReadKeyValues(key));
key.Flush();
key.Close();
}
}
regkey.Flush();
regkey.Close();
last:
return appList;
}
private Task<string> GetIconForRoot(string productName)
{
string result = string.Empty;
string installerKey = @"Installer\Products";
bool isFound = false;
RegistryKey regkey = Registry.ClassesRoot.OpenSubKey(installerKey,
RegistryKeyPermissionCheck.ReadSubTree,
RegistryRights.ReadKey);
if (regkey == null) goto last;
foreach (string subkey in regkey.GetSubKeyNames())
{
if (subkey == null) continue;
using (RegistryKey key = regkey.OpenSubKey(subkey))
{
if (key.GetValue("ProductName") != null)
if (productName == key.GetValue("ProductName").ToString())
if (key.GetValue("ProductIcon") != null)
{
isFound = true;
result = key.GetValue("ProductIcon").ToString();
}
key.Flush();
key.Close();
if (isFound) break;
}
}
regkey.Flush();
regkey.Close();
last:
return Task.FromResult(result);
}
private async Task<Apps> ReadKeyValues(RegistryKey key)
{
Apps installedApp = new Apps();
installedApp._displayName = key.GetValue("DisplayName") == null ? string.Empty : (string)key.GetValue("DisplayName");
installedApp._publisher = key.GetValue("Publisher") == null ? string.Empty : (string)key.GetValue("Publisher");
installedApp._installDate = key.GetValue("InstallDate") == null ? string.Empty : (string)key.GetValue("InstallDate");
var decValue = key.GetValue("EstimatedSize") == null ? "0" : key.GetValue("EstimatedSize");
installedApp._estimatedSize = decValue.ToString() == "0" ? string.Empty : Common.GetSize(decValue.ToString());
installedApp._systemIcon = key.GetValue("DisplayIcon") == null ? string.Empty : (string)key.GetValue("DisplayIcon");
if (string.IsNullOrEmpty(installedApp._systemIcon) && !string.IsNullOrEmpty(installedApp._displayName))
installedApp._systemIcon = await this.GetIconForRoot(installedApp._displayName);
if (!string.IsNullOrEmpty(installedApp._systemIcon))
installedApp._systemIcon = installedApp._systemIcon.Replace("\"", string.Empty).Trim();
installedApp._displayVersion = key.GetValue("DisplayVersion") == null ? string.Empty : (string)key.GetValue("DisplayVersion");
installedApp._uninstallString = key.GetValue("UninstallString") == null ? string.Empty : (string)key.GetValue("UninstallString");
installedApp._modifyPath = key.GetValue("ModifyPath") == null ? string.Empty : (string)key.GetValue("ModifyPath");
Common.FileSize += Int32.Parse(decValue.ToString());
return installedApp;
}
Then I added the app.manifest
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel
level="asInvoker"
uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
</application>
</compatibility>
</assembly>