Le code suivant lève une IOException avec le message: "La clé de Registre spécifiée n'existe pas."
HttpClient client = new HttpClient();
Uri uri = new Uri("http://www.google.com");
client.GetAsync(uri);
C'est juste dans une application console dans Main. Il semble que l'erreur soit générée par mscorlib.dll! Microsoft.Win32.RegistryKey.Win32Error (int errorCode, string str). Je n'ai aucune idée pourquoi cette erreur est levée ou comment commencer à la déboguer.
Modifier la trace de la pile:
à Microsoft.Win32.RegistryKey.Win32Error (Int32 errorCode, String str)
C'est juste une ligne et il n'y a pas d'exception intérieure, etc.
La pile d'appels est:
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]
Il semble que cela soit dû à une récente mise à jour de sécurité pour .NET Framework: MS12-074: Des vulnérabilités dans .NET Framework pourraient permettre l'exécution de code à distance: 13 novembre 2012 (KB 2745030)
Tout se résume au code suivant dans la résolution du proxy 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)
{
}
}
Comme vous pouvez le voir, il recherche une clé de registre spécifique mentionnée dans l'article de la base de connaissances. Vous devez également noter que l'exception est interceptée en interne, mais vous la voyez car vous avez activé les exceptions de première chance dans les options de débogage de Visual Studio.
Si vous ne souhaitez pas voir cette exception, vous devez ajouter la clé de registre spécifiée avec la valeur 0
:
Registry location: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework
DWORD (32-bit) Value name: LegacyWPADSupport
Value data: 0
et pour les processus 32 bits sur les machines 64 bits:
Registry location: HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework
DWORD (32-bit) Value name: LegacyWPADSupport
Value data: 0
Je suis d'accord avec la réponse de Ligaz et j'ai enregistré un problème de connexion à propos de ce bogue: https://connect.Microsoft.com/VisualStudio/feedback/details/773666/webrequest-create-eats-an-ioexception- au premier appel # détails
Enregistrez les éléments suivants dans un fichier .reg et importez-les dans le Registre pour éviter que cette erreur ne se produise:
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
Pour une raison quelconque, votre code HttpClient
recherche des paramètres de proxy dans le registre et ne peut pas ouvrir la clé. Un coup d'œil dans le code montre qu'il tente d'ouvrir HKCU, puis d'accéder à l'une des clés suivantes dans l'ordre:
"HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Connections"
"HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Connections"
"HKLM\\SOFTWARE\\Policies\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"
L'un de ces trois est potentiellement la clé à laquelle votre processus n'a pas accès, pourquoi je ne suis pas sûr. Une solution possible consiste à désactiver les paramètres de détection automatique du proxy.
Sinon, vous devrez déterminer exactement quelle clé il charge et nous le ferons en deux étapes.
- Une fois ouvert, désactivez la capture si elle est activée (la loupe doit être barrée d'un X rouge).
- Commencez à filtrer le nom de votre processus.
- Désélectionner toutes les options sauf les entrées de registre
- Activer la capture (cliquez sur la loupe)
- Exécutez votre application
- Trouvez l'entrée incriminée dans le journal, double-cliquez pour voir quelle clé elle ouvrait
Une fois que vous avez déterminé la clé incriminée, vous pouvez déterminer pourquoi votre application n'y a pas accès. Peut-être, si le nom de votre application est une indication, le compte d'utilisateur sous lequel votre service s'exécute n'a pas accès à la clé de Registre.