Search code examples
c#windowsregistry

“Requested registry access is not allowed” in HKEY_CLASSES_ROOT


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;
}

Solution

  • 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>