Die HttpClient-Anforderung löst eine IOException aus

70

Der folgende Code löst eine IOException mit der Meldung aus: "Der angegebene Registrierungsschlüssel existiert nicht."

HttpClient client = new HttpClient();

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

client.GetAsync(uri);

Dies ist nur in einer Konsolen-App in Main. Es sieht so aus, als würde der Fehler von mscorlib.dll! Microsoft.Win32.RegistryKey.Win32Error (int errorCode, string str) ausgelöst. Ich habe keine Ahnung, warum dieser Fehler ausgelöst wird oder wie ich mit dem Debuggen beginnen soll.

Stapelverfolgung bearbeiten:

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

Es ist nur eine Zeile und es gibt keine innere Ausnahme usw.

Der Aufrufstapel lautet:

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]  
JFoulkes
quelle
1
Was ist die gesamte Stapelverfolgung?
Arran
1
Was ist die HResultauf dieser IOException? Es sieht so aus, als ob Ihr Prozess keinen Zugriff auf die IE-Proxy-Informationen in der Registrierung hat.
user7116
HResult ist 2, nicht sicher, was das bedeutet!
JFoulkes
Sieht so aus, als würde es die HKCU öffnen, hat aber keinen Zugriff. Haben Sie aus Neugier eine PAC-Datei oder etwas in Ihren Proxy-Einstellungen festgelegt? Und verschwindet dies, wenn Sie "Autodetect Proxy Settings" deaktivieren.
user7116
Ich persönlich habe so etwas nicht eingerichtet. Ich bin mir nicht sicher, ob irgendetwas aus dem Netzwerk-Setup meines Unternehmens etwas einstellt. In den Internetoptionen werden die LAN-Einstellungen so eingestellt, dass sie automatisch erkannt werden, und ich erhalte immer noch die Ausnahme, wenn ich die automatische Erkennung deaktiviere.
JFoulkes

Antworten:

85

Dies scheint auf ein kürzlich durchgeführtes Sicherheitsupdate für .NET Framework zurückzuführen zu sein: MS12-074: Sicherheitslücken in .NET Framework können die Ausführung von Remotecode ermöglichen: 13. November 2012 (KB 2745030)

Alles läuft auf den folgenden Code in der Web-Proxy-Auflösung hinaus:

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

Wie Sie sehen, wird nach einem bestimmten Registrierungsschlüssel gesucht, der im KB-Artikel erwähnt wird. Sie sollten auch beachten, dass die Ausnahme intern abgefangen wird, aber Sie sehen sie, weil Sie First Chance Exceptions in den Debug-Optionen von Visual Studio aktiviert haben.

Wenn Sie diese Ausnahme nicht sehen möchten, sollten Sie den angegebenen Registrierungsschlüssel mit dem folgenden Wert hinzufügen 0:

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

und für 32-Bit-Prozesse auf 64-Bit-Computern:

Registry location: HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework
DWORD (32-bit) Value name: LegacyWPADSupport
Value data: 0
Ligaz
quelle
4
Das Update auf meiner Windows 7 64-Bit-Box wurde als KB2729449 angewendet. Relevante KB für andere Systeme finden Sie hier technet.microsoft.com/en-us/security/bulletin/ms12-074 Das Hinzufügen von LegacyWPADSupport zur Registrierung hat funktioniert.
Rassi
Vielen Dank, dass Sie dies so schön
aufgeschlüsselt haben
Auf meinem Computer wurde unter HKLM \ SOFTWARE \ Microsoft \ .NETFramework nach dem Schlüssel gesucht, und ich verwende 64-Bit-Win 7.
rstackhouse
@rstackhouse: richtig. Ich habe die Antwort geändert. Der Wow6432Node ist nur relevant, wenn Sie einen 32-Bit-Prozess auf Ihrem 64-Bit-Betriebssystem ausführen.
Sören Kuklau
28

Ich stimme der Antwort von Ligaz zu und habe ein Connect-Problem zu diesem Fehler angemeldet: https://connect.microsoft.com/VisualStudio/feedback/details/773666/webrequest-create-eats-an-ioexception-on-the- Details zum ersten Anruf #

Speichern Sie Folgendes in einer REG-Datei und importieren Sie es in die Registrierung, um zu verhindern, dass dieser Fehler ausgelöst wird:

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
Bill Menees
quelle
1
Vielen Dank, dass Sie sich bei Connect angemeldet haben.
Pierre Arnaud
Beachten Sie, dass für den Zugriff auf die erwähnte URL der Verbindung ein Microsoft-Konto erforderlich ist. Vielen Dank, dass Sie auf dieser öffentlich lesbaren Website informiert haben.
Stéphane Gourichon
10

Aus irgendeinem Grund HttpClientsucht Ihr Code nach Proxy-Einstellungen in der Registrierung und kann den Schlüssel nicht öffnen. Ein Blick durch den Code zeigt, dass versucht wird, HKCU zu öffnen und dann nacheinander zu einem der folgenden Schlüssel zu wechseln:

  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"

Einer dieser drei Schlüssel ist möglicherweise der Schlüssel, auf den Ihr Prozess keinen Zugriff hat, weshalb ich nicht sicher bin. Eine mögliche Lösung besteht darin, die Proxy-Einstellungen für die automatische Erkennung zu deaktivieren.

Andernfalls müssen Sie genau herausfinden, welcher Schlüssel geladen wird, und das tun wir in zwei Schritten.

  1. Aktivieren Sie die System.Net-Protokollierung .
  2. Laden Sie Procmon herunter und führen Sie es aus. Filtern Sie dabei nach dem Registrierungszugriff für Ihre Anwendung:
  1. Deaktivieren Sie nach dem Öffnen die Aufnahme, wenn diese aktiviert ist (die Lupe sollte ein rotes X aufweisen).Geben Sie hier die Bildbeschreibung ein
  2. Starten Sie die Filterung nach Ihrem Prozessnamen.Geben Sie hier die Bildbeschreibung ein
  3. Deaktivieren Sie alle Optionen außer Registrierungseinträgen

Geben Sie hier die Bildbeschreibung ein

  1. Aufnahme aktivieren (auf die Lupe klicken)
  2. Führen Sie Ihre Anwendung aus
  3. Suchen Sie den fehlerhaften Eintrag im Protokoll und doppelklicken Sie, um zu sehen, welcher Schlüssel geöffnet wurde

Sobald Sie den fehlerhaften Schlüssel ermittelt haben, können Sie herausfinden, warum Ihre Anwendung keinen Zugriff darauf hat. Wenn der Name Ihrer Anwendung ein Hinweis ist, hat das Benutzerkonto, unter dem Ihr Dienst ausgeführt wird, möglicherweise keinen Zugriff auf den Registrierungsschlüssel.

user7116
quelle
Das Ergebnis für HKLM \ SOFTWARE \ Microsoft \ .NETFramework \ LegacyWPADSupport ist NAME NOT FOUND. Das ist der letzte Eintrag in proc mon log
JFoulkes
Dieser Schlüssel befindet sich nicht in meiner Registrierung, daher handelt es sich nicht um ein Berechtigungsproblem.
JFoulkes
1
Hat das Hinzufügen eines Schlüssels mit diesem Namen geholfen?
user7116
Die IOException wurde beseitigt. Jetzt erhalte ich eine SocketException mit der Meldung "Es wurde versucht, auf einen Socket zuzugreifen, der durch seine Zugriffsberechtigungen 10.34.5.92:80 verboten ist"
JFoulkes