HttpClient请求抛出IOException

下面的代码抛出一个IOException消息:“指定的registry项不存在”。

HttpClient client = new HttpClient(); Uri uri = new Uri("http://www.google.com"); client.GetAsync(uri); 

这只是在Main中的一个控制台应用程序。 它看起来像错误正在由mscorlib.dll!Microsoft.Win32.RegistryKey.Win32Error(int errorCode,stringstr)引发。 我不知道为什么这个错误被抛出或如何开始debugging。

编辑堆栈跟踪:

在Microsoft.Win32.RegistryKey.Win32Error(Int32 errorCode,String 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] 

看起来这是由.NET Framework的最新安全更新引起的: MS12-074:.NET Framework中的漏洞可能允许远程执行代码:2012年11月13日(KB 2745030)

这一切都归结为在Web代理parsing下面的代码:

 [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) { } } 

正如您所看到的那样,它会检查知识库文章中提到的特定registry项。 你也应该注意到这个exception是在内部捕获的,但是你可以看到它,因为你已经在Visual Studio的debugging选项中启用了First Chance Exceptions。

如果您不想看到此exception,则应添加值为0的指定registry项:

 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的答案,并且我已经logging了一个关于这个bug的Connect问题: https ://connect.microsoft.com/VisualStudio/feedback/details/773666/webrequest-create-eats-an-ioexception-on-the- 首次呼叫#细节

将以下内容保存到一个.reg文件并将其导入registry以防止出现此错误:

 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 

无论出于何种原因,您的HttpClient代码正在查找registry中的代理设置,并且无法打开密钥。 通过代码查看,显示它试图打开HKCU,然后按顺序转到下列其中一个键:

  1. "HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Connections"
  2. "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Connections"
  3. "HKLM\\SOFTWARE\\Policies\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"

其中之一可能是您的stream程无法访问的关键,为什么我不确定。 一个可能的解决办法是禁用自动检测代理设置。

否则,您需要弄清楚它正在加载的密钥,我们将通过两个步骤来完成。

  1. 启用S​​ystem.Net日志logging 。
  2. 下载并运行Procmon,过滤registry访问为您的应用程序,如下所示:
  1. 一旦打开,禁用捕捉如果启用(放大镜应该有一个红色的X通过它)。 在这里输入图像说明
  2. 开始筛选你的进程名称。 在这里输入图像说明
  3. 取消select除registry项以外的所有选项

在这里输入图像说明

  1. 启用捕捉(点击放大镜)
  2. 运行你的应用程序
  3. 在日志中find有问题的条目,双击以查看它打开的是哪个键

一旦确定了违规密钥,就可以确定应用程序无法访问的原因。 也许,如果您的应用程序的名称是任何迹象,您的服务的用户帐户运行在缺乏访问registry项。