You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中访问字典值触发KeyNotFoundException的问题求助

解决注册表键读取的KeyNotFoundException问题

问题重现

编写C#代码遍历注册表路径数组,将对应项的Start值存入Dictionary<string, uint>,但使用错误的键格式访问时抛出KeyNotFoundException:

原注册表遍历代码

string[] keys = {
    @"SYSTEM\CurrentControlSet\Services\XblGameSave",
    @"SYSTEM\CurrentControlSet\Services\XboxNetApiSvc",
    @"SYSTEM\CurrentControlSet\Services\XboxGipSvc",
    @"SYSTEM\CurrentControlSet\Services\XblAuthManager",
    @"SYSTEM\CurrentControlSet\Services\wisvc",
    @"SYSTEM\CurrentControlSet\Services\Spooler",
    @"SYSTEM\CurrentControlSet\Services\PrintNotify",
    @"SYSTEM\CurrentControlSet\Services\MapsBroker",
    @"SYSTEM\CurrentControlSeSet\Services\bthserv", // 路径拼写错误
    @"SYSTEM\CurrentControlSet\Services\DiagTrack",
    @"SYSTEM\CurrentControlSet\Services\dmwappushservice",
    @"SYSTEM\CurrentControlSet\Services\diagsvc",
    @"SYSTEM\CurrentControlSet\Services\diagnosticshub.standardcollector.service",
    @"SYSTEM\CurrentControlSet\Services\WdiServiceHost",
    @"SYSTEM\CurrentControlSet\Services\WdiSystemHost",
    @"SYSTEM\CurrentControlSet\Services\AJRouter",
    @"SYSTEM\CurrentControlSet\Services\ALG",
    @"SYSTEM\CurrentControlSet\Services\CertPropSvc",
    @"SYSTEM\CurrentControlSet\Services\Fax",
    @"SYSTEM\CurrentControlSet\Services\CscService",
    @"SYSTEM\CurrentControlSet\Services\RetailDemo",
    @"SYSTEM\CurrentControlSet\Services\seclogon",
    @"SYSTEM\CurrentControlSet\Services\SCardSvr",
    @"SYSTEM\CurrentControlSet\Services\ScDeviceEnum",
    @"SYSTEM\CurrentControlSet\Services\SCPolicySvc",
    @"SYSTEM\CurrentControlSet\Services\SysMain",
    @"SYSTEM\CurrentControlSet\Services\WerSvc",
    @"SYSTEM\CurrentControlSet\Services\DoSvc",
    @"SYSTEM\CurrentControlSet\Services\lfsvc",
    @"SYSTEM\CurrentControlSet\Services\SEMgrSvc",
    @"SYSTEM\CurrentControlSet\Services\PhoneSvc",
    @"SYSTEM\CurrentControlSet\Services\RemoteRegistry",
    @"SYSTEM\CurrentControlSet\Services\WdiServiceHost", // 重复键
    @"SYSTEM\CurrentControlSet\Services\WdiSystemHost", // 重复键
    @"SYSTEM\CurrentControlSet\Services\feafes",
    @"SYSTEM\CurrentControlSet\Services\ALG", // 重复键
    @"SYSTEM\CurrentControlSet\Services\CertPropSvc", // 重复键
    @"SYSTEM\CurrentControlSet\Services\Fax", // 重复键
    @"SYSTEM\CurrentControlSet\Services\CscService", // 重复键
    @"SYSTEM\CurrentControlSet\Services\WalletService",
    @"SYSTEM\CurrentControlSet\Services\WSearch",
    @"SYSTEM\CurrentControlSet\Services\W32Time",
    @"SYSTEM\CurrentControlSet\Services\tzautoupdate",
    @"SYSTEM\CurrentControlSet\Services\CDPSvc",
    @"SYSTEM\CurrentControlSet\Services\DusmSvc",
    @"SYSTEM\CurrentControlSet\Services\fhsvc",
    @"SYSTEM\CurrentControlSet\Services\PcaSvc",
};

Dictionary<string, uint> dict = new Dictionary<string, uint>();

foreach (string key in keys)
{
    RegistryKey rkey = Registry.LocalMachine.OpenSubKey(key, true);

    try
    {                    
        dict.Add(key, Convert.ToUInt32(rkey.GetValue("Start", RegistryValueKind.DWord)));
    }
    catch (Exception)
    {
        // 空catch块,隐藏错误
    }
    finally
    {
        rkey?.Dispose();
    }
}

错误的访问代码

uint value = dict["@\"SYSTEM\\\\CurrentControlSet\\\\Services\\\\XblGameSave\""];

错误原因

  1. 键格式不匹配:访问字典时使用了带额外引号和冗余转义的字符串,而字典中的键是原始的@"SYSTEM\CurrentControlSet\Services\XblGameSave"(实际存储值为SYSTEM\CurrentControlSet\Services\XblGameSave),两者完全不同,导致找不到对应键。
  2. 原代码的潜在问题:
    • 注册表路径拼写错误:CurrentControlSeSet应为CurrentControlSet,导致该路径无法打开,不会被加入字典。
    • 重复键:数组中存在多个重复路径,dict.Add会抛出异常但被空catch块吞噬,导致这些键无法存入字典。
    • GetValue参数错误:第二个参数应为默认值,而非RegistryValueKind.DWord,会引发类型转换错误。
    • 空catch块:隐藏所有异常,无法定位哪些键读取失败。

解决步骤

1. 修正键的访问方式

直接使用与数组中完全一致的字符串访问字典,无需额外转义或引号:

// 正确的访问方式(与数组中字符串一致)
uint value = dict[@"SYSTEM\CurrentControlSet\Services\XblGameSave"];
// 或者不用@符号,手动转义反斜杠
uint value = dict["SYSTEM\\CurrentControlSet\\Services\\XblGameSave"];

2. 修复原代码的潜在问题

以下是修正后的完整代码:

using Microsoft.Win32;
using System;
using System.Collections.Generic;

string[] keys = {
    @"SYSTEM\CurrentControlSet\Services\XblGameSave",
    @"SYSTEM\CurrentControlSet\Services\XboxNetApiSvc",
    @"SYSTEM\CurrentControlSet\Services\XboxGipSvc",
    @"SYSTEM\CurrentControlSet\Services\XblAuthManager",
    @"SYSTEM\CurrentControlSet\Services\wisvc",
    @"SYSTEM\CurrentControlSet\Services\Spooler",
    @"SYSTEM\CurrentControlSet\Services\PrintNotify",
    @"SYSTEM\CurrentControlSet\Services\MapsBroker",
    @"SYSTEM\CurrentControlSet\Services\bthserv", // 修正拼写错误
    @"SYSTEM\CurrentControlSet\Services\DiagTrack",
    @"SYSTEM\CurrentControlSet\Services\dmwappushservice",
    @"SYSTEM\CurrentControlSet\Services\diagsvc",
    @"SYSTEM\CurrentControlSet\Services\diagnosticshub.standardcollector.service",
    @"SYSTEM\CurrentControlSet\Services\WdiServiceHost",
    @"SYSTEM\CurrentControlSet\Services\WdiSystemHost",
    @"SYSTEM\CurrentControlSet\Services\AJRouter",
    @"SYSTEM\CurrentControlSet\Services\ALG",
    @"SYSTEM\CurrentControlSet\Services\CertPropSvc",
    @"SYSTEM\CurrentControlSet\Services\Fax",
    @"SYSTEM\CurrentControlSet\Services\CscService",
    @"SYSTEM\CurrentControlSet\Services\RetailDemo",
    @"SYSTEM\CurrentControlSet\Services\seclogon",
    @"SYSTEM\CurrentControlSet\Services\SCardSvr",
    @"SYSTEM\CurrentControlSet\Services\ScDeviceEnum",
    @"SYSTEM\CurrentControlSet\Services\SCPolicySvc",
    @"SYSTEM\CurrentControlSet\Services\SysMain",
    @"SYSTEM\CurrentControlSet\Services\WerSvc",
    @"SYSTEM\CurrentControlSet\Services\DoSvc",
    @"SYSTEM\CurrentControlSet\Services\lfsvc",
    @"SYSTEM\CurrentControlSet\Services\SEMgrSvc",
    @"SYSTEM\CurrentControlSet\Services\PhoneSvc",
    @"SYSTEM\CurrentControlSet\Services\RemoteRegistry",
    @"SYSTEM\CurrentControlSet\Services\feafes",
    @"SYSTEM\CurrentControlSet\Services\WalletService",
    @"SYSTEM\CurrentControlSet\Services\WSearch",
    @"SYSTEM\CurrentControlSet\Services\W32Time",
    @"SYSTEM\CurrentControlSet\Services\tzautoupdate",
    @"SYSTEM\CurrentControlSet\Services\CDPSvc",
    @"SYSTEM\CurrentControlSet\Services\DusmSvc",
    @"SYSTEM\CurrentControlSet\Services\fhsvc",
    @"SYSTEM\CurrentControlSet\Services\PcaSvc",
};

Dictionary<string, uint> dict = new Dictionary<string, uint>();

foreach (string key in keys)
{
    // 跳过已存在的键,避免重复添加异常
    if (dict.ContainsKey(key))
        continue;

    // 使用using自动释放RegistryKey资源,无需手动Dispose
    using RegistryKey rkey = Registry.LocalMachine.OpenSubKey(key);
    if (rkey == null)
    {
        Console.WriteLine($"无法打开注册表项: {key}");
        continue;
    }

    try
    {
        object startValue = rkey.GetValue("Start");
        if (startValue == null)
        {
            Console.WriteLine($"注册表项 {key} 中不存在Start值");
            continue;
        }

        // 先判断值类型是否为DWord,再转换
        if (rkey.GetValueKind("Start") == RegistryValueKind.DWord)
        {
            dict.Add(key, Convert.ToUInt32(startValue));
        }
        else
        {
            Console.WriteLine($"注册表项 {key} 的Start值不是DWord类型");
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine($"读取注册表项 {key} 时出错: {ex.Message}");
    }
}

// 按数组顺序安全访问字典值
foreach (string key in keys)
{
    if (dict.TryGetValue(key, out uint value))
    {
        Console.WriteLine($"{key}: {value}");
    }
    else
    {
        Console.WriteLine($"{key}: 未找到值");
    }
}

关键修正点

  • 修正了注册表路径的拼写错误。
  • 添加重复键检查,避免Add方法抛出异常。
  • 使用using语句自动释放RegistryKey资源,简化代码。
  • 优化GetValue逻辑,先判断值是否存在及类型是否正确。
  • 替换空catch块为错误日志,便于排查问题。
  • 使用TryGetValue安全访问字典,避免抛出KeyNotFoundException。

额外说明

若需要严格保持数组的顺序访问,建议使用OrderedDictionary替代Dictionary——虽然.NET Core 3.0+及.NET 5+的Dictionary已保证插入顺序,但OrderedDictionary的顺序语义更明确。

内容的提问来源于stack exchange,提问作者KrakenZ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 07:20:35