70

次のコードは、「指定されたレジストリ キーが存在しません」というメッセージとともに IOException をスローします。

HttpClient client = new HttpClient();

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

client.GetAsync(uri);

これは、メインのコンソール アプリにあるだけです。mscorlib.dll!Microsoft.Win32.RegistryKey.Win32Error(int errorCode, string str) によってエラーがスローされているようです。このエラーがスローされる理由や、デバッグを開始する方法がわかりません。

スタック トレースを編集します。

Microsoft.Win32.RegistryKey.Win32Error (Int32 errorCode、文字列 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]  
4

3 に答える 3

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

ご覧のとおり、KB 記事に記載されている特定のレジストリ キーをチェックします。また、例外は内部でキャッチされることに注意してください。ただし、Visual Studio のデバッグ オプションで First Chance Exceptions を有効にしているため、例外が表示されます。

この例外を表示したくない場合は、指定したレジストリ キーに値を追加する必要があります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
于 2012-11-20T10:07:44.667 に答える
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
于 2012-12-06T14:24:55.617 に答える
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"

これら 3 つのうちの 1 つは、プロセスがアクセスできないキーである可能性があります。理由はわかりません。考えられる解決策の 1 つは、プロキシ設定を自動的に検出するを無効にすることです。

それ以外の場合は、読み込まれているキーを正確に把握する必要があり、2 つの手順でそれを行います。

  1. System.Net ログを有効にします。
  2. 次のように、Procmon をダウンロードして実行し、アプリケーションのレジストリ アクセスをフィルタリングします。
  1. 開いたら、有効になっている場合はキャプチャを無効にします (虫眼鏡に赤い X が表示されている必要があります)。ここに画像の説明を入力
  2. プロセス名でフィルタリングを開始します。ここに画像の説明を入力
  3. レジストリ エントリ以外のすべてのオプションの選択を解除します

ここに画像の説明を入力

  1. キャプチャを有効にする (虫眼鏡をクリック)
  2. アプリケーションを実行する
  3. ログで問題のあるエントリを見つけ、ダブルクリックして開いているキーを確認します

問題のあるキーを特定したら、アプリケーションがそのキーにアクセスできない理由を突き止めることができます。おそらく、アプリケーションの名前からわかるように、サービスを実行しているユーザー アカウントにはレジストリ キーへのアクセス権がありません。

于 2012-10-30T15:32:47.410 に答える