C# HttpClient请求引发IOException

C# HttpClient请求引发IOException,c#,.net,httpclient,ioexception,C#,.net,Httpclient,Ioexception,以下代码抛出IOException,并显示消息:“指定的注册表项不存在。” 这只是在一个主控制台应用程序。看起来错误是由mscorlib.dll引发的!Microsoft.Win32.RegistryKey.Win32错误(int errorCode,string str)。我不知道为什么会抛出这个错误,也不知道如何开始调试它 编辑堆栈跟踪: 位于Microsoft.Win32.RegistryKey.Win32错误(Int32错误代码,字符串str) 只有一行,没有内部异常等 调用堆栈是: m

以下代码抛出IOException,并显示消息:“指定的注册表项不存在。”

这只是在一个主控制台应用程序。看起来错误是由mscorlib.dll引发的!Microsoft.Win32.RegistryKey.Win32错误(int errorCode,string str)。我不知道为什么会抛出这个错误,也不知道如何开始调试它

编辑堆栈跟踪:

位于Microsoft.Win32.RegistryKey.Win32错误(Int32错误代码,字符串str)

只有一行,没有内部异常等

调用堆栈是:

mscorlib.dll!Microsoft.Win32.RegistryKey.Win32Error(int errorCode, string str) + 0x189 bytes    
mscorlib.dll!Microsoft.Win32.RegistryKey.GetValueKind(string name) + 0x7f bytes 
System.dll!System.Net.HybridWebProxyFinder.InitializeFallbackSettings() + 0x9e bytes    
[Native to Managed Transition]  
[Managed to Native Transition]  
System.dll!System.Net.AutoWebProxyScriptEngine.AutoWebProxyScriptEngine(System.Net.WebProxy proxy, bool useRegistry) + 0xd0 bytes   
System.dll!System.Net.WebProxy.UnsafeUpdateFromRegistry() + 0x2c bytes  
System.dll!System.Net.Configuration.DefaultProxySectionInternal.DefaultProxySectionInternal(System.Net.Configuration.DefaultProxySection section) + 0x1d8 bytes 
System.dll!System.Net.Configuration.DefaultProxySectionInternal.GetSection() + 0xec bytes   
System.dll!System.Net.WebRequest.InternalDefaultWebProxy.get() + 0xcc bytes 
System.dll!System.Net.HttpWebRequest.HttpWebRequest(System.Uri uri, System.Net.ServicePoint servicePoint) + 0xdf bytes  
System.dll!System.Net.HttpWebRequest.HttpWebRequest(System.Uri uri, bool returnResponseOnFailureStatusCode, string connectionGroupName, System.Action<System.IO.Stream> resendRequestContent) + 0x2b bytes  
System.Net.Http.dll!System.Net.Http.HttpClientHandler.CreateAndPrepareWebRequest(System.Net.Http.HttpRequestMessage request) + 0x59 bytes   
System.Net.Http.dll!System.Net.Http.HttpClientHandler.SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) + 0xf4 bytes  
System.Net.Http.dll!System.Net.Http.HttpMessageInvoker.SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) + 0x4f bytes 
System.Net.Http.dll!System.Net.Http.HttpClient.SendAsync(System.Net.Http.HttpRequestMessage request, System.Net.Http.HttpCompletionOption completionOption, System.Threading.CancellationToken cancellationToken) + 0x13e bytes 
System.Net.Http.dll!System.Net.Http.HttpClient.GetAsync(System.Uri requestUri, System.Net.Http.HttpCompletionOption completionOption) + 0xc bytes   

ConsoleServiceTest.exe!ConsoleServiceTest.Program.Main(string[] args) Line 20 + 0x17 bytes  C#
    [Native to Managed Transition]  
    [Managed to Native Transition]  
    Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() + 0x5a bytes  
    mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) + 0x285 bytes 
    mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) + 0x9 bytes   
    mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x57 bytes    
    mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x51 bytes   
    [Native to Managed Transition]  
mscorlib.dll!Microsoft.Win32.RegistryKey.Win32错误(int errorCode,string str)+0x189字节
mscorlib.dll!Microsoft.Win32.RegistryKey.GetValueKind(字符串名称)+0x7f字节
System.dll!System.Net.HybridWebProxyFinder.InitializeFallbackSettings()+0x9e字节
[本机到托管转换]
[管理到本机转换]
System.dll!System.Net.AutoWebProxyScriptEngine.AutoWebProxyScriptEngine(System.Net.WebProxy代理,bool useRegistry)+0xd0字节
System.dll!System.Net.WebProxy.UnsafeUpdateFromRegistry()+0x2c字节
System.dll!System.Net.Configuration.DefaultProxySectionInternal.DefaultProxySectionInternal(System.Net.Configuration.DefaultProxySection节)+0x1d8字节
System.dll!System.Net.Configuration.DefaultProxySectionInternal.GetSection()+0xec字节
System.dll!System.Net.WebRequest.InternalDefaultWebProxy.get()+0xcc字节
System.dll!System.Net.HttpWebRequest.HttpWebRequest(System.Uri Uri,System.Net.ServicePoint ServicePoint)+0xdf字节
System.dll!System.Net.HttpWebRequest.HttpWebRequest(System.Uri Uri,bool returnResponseOnFailureStatusCode,string connectionGroupName,System.Action resendRequestContent)+0x2b字节
System.Net.Http.dll!System.Net.Http.HttpClientHandler.CreateAndPrepareWebRequest(System.Net.Http.HttpRequestMessage请求)+0x59字节
System.Net.Http.dll!System.Net.Http.HttpClientHandler.SendAsync(System.Net.Http.HttpRequestMessage请求,System.Threading.CancellationToken CancellationToken)+0xf4字节
System.Net.Http.dll!System.Net.Http.HttpMessageInvoker.SendAsync(System.Net.Http.HttpRequestMessage请求,System.Threading.CancellationToken CancellationToken)+0x4f字节
System.Net.Http.dll!System.Net.Http.HttpClient.SendAsync(System.Net.Http.HttpRequestMessage请求,System.Net.Http.HttpCompletionOption completionOption,System.Threading.CancellationToken CancellationToken)+0x13e字节
System.Net.Http.dll!System.Net.Http.HttpClient.GetAsync(System.Uri requestUri,System.Net.Http.HttpCompletionOption completionOption)+0xc字节
ConsoleServiceTest.exe!ConsoleServiceTest.Program.Main(字符串[]args)行20+0x17字节C#
[本机到托管转换]
[管理到本机转换]
Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()+0x5a字节
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext ExecutionContext,System.Threading.ContextCallback回调,对象状态,bool preserveSyncCtx)+0x285字节
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext ExecutionContext,System.Threading.ContextCallback回调,对象状态,bool preserveSyncCtx)+0x9字节
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext ExecutionContext,System.Threading.ContextCallback回调,对象状态)+0x57字节
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart()+0x51字节
[本机到托管转换]

无论出于何种原因,您的
HttpClient
代码正在注册表中查找代理设置,无法打开该项。查看代码显示它试图打开HKCU,然后按顺序转到以下键之一:

  • “HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet设置\\连接”
  • “HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet设置\\连接”
  • “HKLM\\SOFTWARE\\Policys\\Microsoft\\Windows\\CurrentVersion\\Internet设置”
  • 这三者之一可能是您的流程无法访问的关键,为什么我不确定。一种可能的修复方法是禁用自动检测代理设置

    否则,您将需要准确地了解它正在加载的键,我们将通过两个步骤来完成

  • 下载并运行Procmon,对应用程序的注册表访问进行筛选,如下所示:
  • 打开后,如果启用,则禁用捕获(放大镜上应有一个红色的X)
  • 开始筛选进程名称
  • 取消选择除注册表项以外的所有选项
  • 启用捕获(单击放大镜)
  • 运行应用程序
  • 在日志中找到有问题的条目,双击查看它打开的键

  • 一旦确定了有问题的密钥,就可以找出应用程序无法访问该密钥的原因。如果您的应用程序名称有任何迹象表明,您的服务运行所使用的用户帐户可能无法访问注册表项。

    这似乎是由于.NET Framework最近的安全更新造成的:

    这一切归结为web代理解析中的以下代码:

    [RegistryPermission(SecurityAction.Assert, Read=@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework")]
    private static void InitializeFallbackSettings()
    {
        allowFallback = false;
        try
        {
            using (RegistryKey key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\.NETFramework"))
            {
                try
                {
                    if (key.GetValueKind("LegacyWPADSupport") == RegistryValueKind.DWord)
                    {
                        allowFallback = ((int) key.GetValue("LegacyWPADSupport")) == 1;
                    }
                }
                catch (UnauthorizedAccessException)
                {
                }
                catch (IOException)
                {
                }
            }
        }
        catch (SecurityException)
        {
        }
        catch (ObjectDisposedException)
        {
        }
    }
    
    正如您所见,它检查KB文章中提到的特定注册表项。您还应该注意,异常是在内部捕获的,但是您看到它是因为您在VisualStudio的调试选项中启用了第一次机会异常

    如果不希望看到此异常,则应添加值为
    0
    的指定注册表项:

    Registry location: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework  
    DWORD (32-bit) Value name: LegacyWPADSupport
    Value data: 0
    
    对于64位计算机上的32位进程:

    Registry location: HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework
    DWORD (32-bit) Value name: LegacyWPADSupport
    Value data: 0
    

    我同意Ligaz的回答,我已经记录了一个关于这个bug的连接问题:

    将以下内容保存到.reg文件中
    Registry location: HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework
    DWORD (32-bit) Value name: LegacyWPADSupport
    Value data: 0
    
    Windows Registry Editor Version 5.00
    
    ; The following value prevents an IOException from being thrown and caught
    ; by System.Net.HybridWebProxyFinder.InitializeFallbackSettings() (in System.dll)
    ; when WebRequest.Create is first called.  By default the "LegacyWPADSupport"
    ; value doesn't exist, and when InitializeFallbackSettings calls GetValueKind,
    ; an IOException is thrown.  This adds the value with its default of false to
    ; prevent the exception.
    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework]
    "LegacyWPADSupport"=dword:00000000
    
    [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework]
    "LegacyWPADSupport"=dword:00000000