HttpClient请求抛出IOException


70

下面的代码将引发带有消息的IOException:“指定的注册表项不存在。”

HttpClient client = new HttpClient();

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

client.GetAsync(uri);

这只是在Main中的控制台应用程序中。似乎该错误由mscorlib.dll!Microsoft.Win32.RegistryKey.Win32Error(int errorCode,字符串str)引发。我不知道为什么会引发此错误或如何开始调试它。

编辑堆栈跟踪:

在Microsoft.Win32.RegistryKey.Win32Error(Int32 errorCode,String str)

它只有1条线,没有内部异常等。

调用堆栈为:

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]  

1
什么是整个堆栈跟踪?
阿兰2012年

1
什么是HResult对IOException异常?看起来您的进程无法访问注册表中的IE代理信息。
user7116 2012年

HResult为2,不太清楚是什么意思!
JFoulkes,2012年

看起来好像打开了HKCU,但是没有访问权限。出于好奇,您是否在代理设置中设置了PAC文件或其他内容?如果您取消选中“自动检测代理设置”,这是否消失了?
user7116 2012年

我个人还没有设置类似的东西。不知道我公司网络设置中是否有任何设置...。在Internet选项中,LAN设置被设置为自动检测,如果取消选中自动检测,仍然会出现异常。
JFoulkes,2012年

Answers:


85

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

一切归结为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)
    {
    }
}

如您所见,它会检查知识库文章中提到的特定注册表项。另外,您还应该注意,该异常是在内部捕获的,但是您看到了它,因为您已在Visual Studio的调试选项中启用了“ First Chance Exceptions”。

如果您不想看到此异常,则应使用value添加指定的注册表项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

4
发现我的Windows 7 64位框中的更新已应用为KB2729449。其他系统的相关KB可以在此处找到technet.microsoft.com/en-us/security/bulletin/ms12-074 将LegacyWPADSupport添加到已运行的注册表中。
拉西

谢谢您很好地解决了这个问题:)
gideon

在我的机器,它正在寻找下HKLM \ SOFTWARE \微软\ .NETFramework钥匙,我跑64位赢得7
rstackhouse

@rstackhouse:对。我已经修改了答案。仅当您在64位操作系统上运行32位进程时,Wow6432Node才有意义。
索伦Kuklau

28

我同意Ligaz的回答,并且我已经记录了一个与此错误有关的Connect问题:https ://connect.microsoft.com/VisualStudio/feedback/details/773666/webrequest-create-eats-an-ioexception-on-the-首次通话#详细信息

将以下内容保存到.reg文件中,并将其导入注册表中,以防止出现此错误:

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

1
感谢您将此登录到Connect。
皮埃尔·阿诺

请注意,访问提及的连接URL需要一个Microsoft帐户。感谢您告知此公开阅读的网站。
斯特凡纳·古里科

10

无论出于何种原因,您的HttpClient代码都在注册表中寻找代理设置,因此无法打开密钥。浏览该代码可发现它尝试打开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"

这三个原因之一可能是您的过程无法访问的密钥,为什么我不确定。一种可能的解决方法是禁用“自动检测代理设置”。

否则,您将需要确切地知道它正在加载什么密钥,我们将分两个步骤进行操作。

  1. 启用S​​ystem.Net日志记录
  2. 下载并运行Procmon,对应用程序的注册表访问进行过滤,如下所示:
  1. 一旦打开,请禁用捕获(如果已启用)(放大镜应该有红色的X穿过)。在此处输入图片说明
  2. 开始过滤您的进程名称。在此处输入图片说明
  3. 取消选择除注册表项之外的所有选项

在此处输入图片说明

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

一旦确定了有问题的密钥,就可以弄清楚为什么您的应用程序无权访问它。也许,如果您的应用程序名称带有任何指示,则您的服务所运行的用户帐户将无法访问注册表项。


未找到HKLM \ SOFTWARE \ Microsoft \ .NETFramework \ LegacyWPADSupport的结果。那是proc mon日志中的最后一个条目
JFoulkes

该密钥不在我的注册表中,因此不是权限问题。
JFoulkes

1
通过该名称添加密钥有帮助吗?
user7116

它摆脱了IOException。现在,我收到一个SocketException消息:“试图以一种其访问权限10.34.5.92:80禁止的方式访问套接字”
JFoulkes,2012年

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.