Подтвердить что ты не робот

Запрос HttpClient вызывает IOException

Следующий код генерирует сообщение 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 строка и нет внутреннего exexception и т.д.

Стек вызова:

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]  
4b9b3361

Ответ 1

Похоже, что это вызвано недавним обновлением безопасности для .NET Framework: MS12-074: Уязвимости в .NET Framework могут позволить удаленное выполнение кода: 13 ноября 2012 г. (KB 2745030)

Все это сводится к следующему коду в разрешении веб-прокси:

[RegistryPermission(SecurityAction.Assert, [email protected]"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. Также вы должны заметить, что исключение попадает внутри, но вы видите его, потому что вы включили First Chance Exceptions в параметрах отладки Visual Studio.

Если вы не хотите видеть это исключение, вы должны добавить указанный раздел реестра со значением 0:

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

и для 32-битных процессов на 64-битных машинах:

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

Ответ 2

Я согласен с ответом Ligaz, и я зарегистрировал проблему Connect об этой ошибке: https://connect.microsoft.com/VisualStudio/feedback/details/773666/webrequest-create-eats-an-ioexception-on-the-first-call#details

Сохраните следующее в файле .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

Ответ 3

По какой-либо причине ваш код HttpClient ищет параметры прокси-сервера в реестре и не может открыть ключ. Просмотр кода показывает, что он пытается открыть HKCU, а затем перейти к одному из следующих ключей в следующем порядке:

  • "HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Connections"
  • "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Connections"
  • "HKLM\\SOFTWARE\\Policies\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"

Один из этих трех потенциально является ключом, к которому у вашего процесса нет доступа, почему я не уверен. Одним из возможных исправлений является автоматическое определение параметров прокси-сервера.

В противном случае вам нужно выяснить, какой именно ключ он загружается, и мы сделаем это с двумя шагами.

  • После открытия отключите захват, если он включен (увеличительное стекло должно иметь красный X через него). enter image description here
  • Начните фильтрацию имени вашего процесса. enter image description here
  • Отменить выбор всех параметров, кроме записей реестра

enter image description here

  1. Включить захват (щелкните увеличительное стекло)
  2. Запустите приложение
  3. Найдите оскорбительную запись в журнале, дважды щелкните, чтобы увидеть, какой ключ был открыт.

Как только вы определяете оскорбительный ключ, вы можете понять, почему ваше приложение не имеет к нему доступа. Возможно, если имя вашего приложения является каким-либо признаком, учетная запись пользователя, на которую работает ваша служба, не имеет доступа к разделу реестра.