2011-10-17 21 views
1

C#を使用してリモートマシンにWMI接続を確立するためのオンラインチュートリアルが複数見つかりました。これらのチュートリアルでは、次のようなプロセスを説明します不正な資格情報を入力するとWMI APIがハングアップする

ConnectionOptions cOpts = new ConnectionOptions(); 
ManagementObjectCollection moCollection; 
ManagementObjectSearcher moSearcher; 
ManagementScope mScope; 
ObjectQuery oQuery; 

mScope = new ManagementScope(String.Format("\\\\{0}\\{1}", host.hostname, "ROOT\\CIMV2"), cOpts); 
oQuery = new ObjectQuery("Select * from Win32_OperatingSystem"); 
moSearcher = new ManagementObjectSearcher(mScope, oQuery); 

moCollection = moSearcher.Get(); 

ハッピーパスケース - ローカルホストへの接続、または適切な資格情報を使用してリモートホストに接続する - 作業罰金。現在ログインしているアカウントに、接続しようとしているリモートホストにアクセスできない場合のサポートが必要なプロジェクトに取り組んでいます。つまり、このケースをキャッチして、悪意のある資格情報をユーザーに知らせ、資格情報を再度提供するように促す必要があります。

リモートマシンのコンテキストを持たないConnectionOptionsオブジェクトに資格情報を指定すると、moSearcher.Get()への呼び出しが(一見)無期限にハングアップします。同様に、ManagementScopeのConnect()関数の呼び出しも同じ方法で停止します。

C++で同等のWMIコマンドを実行するのに似たロジックが用意されていますが、不適切な資格情報が提供された場合にはすぐに返されると報告できます。適切な「アクセスが拒否されました」というメッセージが返されます。私がテスト目的で使用しているホストは、既存のC++ロジックをテストするときに使用したホストと同じものなので、私たちの環境でWMIが正しく構成されていないと考える理由はありません。

私はWMI接続に関するタイムアウトの問題をc#で検索しました。私はConnectionOptionsとmoSearcher.OptionsのTimeoutプロパティを調べました。また、ManagementObjectSearcherインスタンスに関連付けることができるEnumerationOptionsオブジェクトのReturnImmediatelyプロパティを見てきました。これらのオプションは、私にとって望ましい効果はありませんでした。

私は別のスレッドでこれらのWMIコマンドを実行し、妥当な時間内に返されなかった場合はスレッドを強制終了する監視コードでスレッドを囲むことができます。それは、C#WMIルーチンのすべての消費者にプッシュされるかなりの量の作業のように思えますが、もっと簡単な方法があると思っています。さらに、このように未処理のスレッドを強制終了すると、WMI接続が正しく消去されるかどうかはわかりません。

リモートホストにpingを実行しても、ホストが起動しているとわからないため、私の資格情報が適切かどうかは分かりません(また、c#WMI呼び出しがハングする場合もあります)。リモートホストに対して資格情報を検証する別の方法はありますか?

他の人がこの問題に遭遇したと思うので、わかりやすいフラグやAPIが存在する可能性が常にあります。どんな情報/支援も感謝します。この長い記事を読んでくれてありがとう。

答えて

0

私はすべてのあなたの特別な機能があるかわからないが、ここであなたはそれがスレッドにあなたのルーチンをラップし、それを実行するための5秒を与えることができるはずトラブルシューティングに役立つために少しのルーチンです:

void Fake() { 
    bool ok = false; 
    ConnectionOptions cOpts = new ConnectionOptions(); 
    ManagementObjectCollection moCollection; 
    ManagementObjectSearcher moSearcher; 
    ManagementScope mScope; 
    ObjectQuery oQuery; 
    if (cOpts != null) { 
    mScope = new ManagementScope(String.Format("\\\\{0}\\{1}", host.hostname, "ROOT\\CIMV2"), cOpts); 
    if (mScope != null) { 
     oQuery = new ObjectQuery("Select * from Win32_OperatingSystem"); 
     if (oQuery != null) { 
     moSearcher = new ManagementObjectSearcher(mScope, oQuery); 
     if (moSearcher != null) { 
      ManualResetEvent mre = new ManualResetEvent(false); 
      Thread thread1 = new Thread(() => { 
      moCollection = moSearcher.Get(); 
      mre.Set(); 
      }; 
      thread1.Start(); 
      ok = mre.WaitOne(5000); // wait 5 seconds 
     } else { 
      Console.WriteLine("ManagementObjectSearcher failed"); 
     } 
     } else { 
     Console.WriteLine("ObjectQuery failed"); 
     } 
    } else { 
     Console.WriteLine("ManagementScope failed"); 
    } 
    } else { 
    Console.WriteLine("ConnectionOptions failed"); 
    } 
} 

あなたに助けやアイディアを与えることを望む希望。

+0

お返事ありがとうございました。そのスレッドコードは別のオプションです。私が気分が良くなるのは、私のようにこれらのAPIを実行するときに、他の人が同じ問題を経験することを見つけることです。 – Dan

+0

また、開発者であることを通知するためのエラーチェックが、何か問題が起きていないことにも注意してください。あなたのコードが 'moCollection = moSearcher.Get()'行までのエラーチェックステップを通してコードを作成している場合は、 'Get()'関数を調べてオーバーロードやエラーコードがあるかどうかを調べることができますそれは提供します。希望があれば助かります。 – jp2code

+0

たとえば、このリンク>> http://msdn.microsoft.com/en-us/library/67a77ef1.aspx <<は、 "即時発呼者の完全な信頼です。このメンバーは、部分的に信頼できるコードでは使用できません。 '" – jp2code

0

タイムアウトを超えた場合に殺される可能性のある別のスレッドでWMI API呼び出しを囲むようにjpの提案を受けました。テスト時に、別のスレッドがSystem.UnauthorizedAccessException型の例外をスローしました。スレッドロジックを削除し、この例外タイプを処理するcatchステートメントを追加しました。もちろん、ManagementObjectSearcher.Get()の呼び出しの直後に例外がキャッチされます。

try 
{ 
    moCollection = moSearcher.Get(); 
} 

catch (System.UnauthorizedAccessException) 
{ 
    return Program.ERROR_FUNCTION_FAILED; 
} 

catch (System.Runtime.InteropServices.COMException) 
{ 
    MessageBox.Show("Error, caught COMException."); 
    return Program.ERROR_FUNCTION_FAILED; 
} 

(System.Runtime.InteropServices。

親スレッドの一部として実行されたときに、この例外がスローされない(または少なくともVS 2010 IDEを介してユーザーの関心を引くことはできません)理由がわかりません。 。いずれにしても、これはまさに私が探していたものであり、C++のWMI接続ルーチンの動作と一貫しています。

関連する問題