WMI - Win32_OperatingSystem のシングルトン インスタンスに直接アクセスする
-
09-06-2019 - |
質問
に直接アクセスできなくて困っています Win32_オペレーティングシステム WMI 経由で公開される管理クラス。
これはシングルトン クラスであり、「Win32_OperatingSystem=@」がシングルトンのインスタンスを取得するための正しいパス構文であると確信しています。
InvokeMethod を呼び出すと、ClassPath プロパティ (コメント行) へのアクセスと同様に、質問の下部にリストされている例外が生成されます。
私の何が間違っているのでしょうか?
[ManagementObjectSearcher/ObjectQuery を使用して Win32_OperatingSystem のコレクション (1 つだけが含まれる) を返せることはわかっていますが、それがシングルトンであることはわかっているので、直接アクセスしたいと考えています。
ManagementScope cimv2 = InitScope(string.Format(@"\\{0}\root\cimv2", this.Name));
ManagementObject os = new ManagementObject(
cimv2,
new ManagementPath("Win32_OperatingSystem=@"),
new ObjectGetOptions());
//ManagementPath p = os.ClassPath;
os.InvokeMethod("Reboot", null);
System.Management.ManagementExceptionがキャッチされましたメッセージ= "無効なオブジェクトパス" source = "System.Management" stacktrace:System.management.managementexception.throwwithextendedinfo(managementStatus errorcode)at System.Management.ManagementObject.Initialize(boolean getObject)at System.management.management.baseobject.get_wbemobject()at System.management.management.object.get_classpath() .getMethodParameters(String MethodName、ManagementBaseObject&InParameters、IWBemClassObjectFreeThreaded&InParameterSclass、IWBemClassObjectFreeTheded&Outparametersersersers)
ご返信ありがとうございます。
ニック - どうすればいいのか分かりません :)
ウロス - シングルトンクラスだと思い込んでいました。 これ MSDN ページ。また、WBEMTest ユーティリティでクラスを開くと、 これ.
インスタンス ダイアログには次の内容が表示されます。「オブジェクトは 1 個」と「最大数は 1 個」バッチ:これらのフィールドとリストの「Win32_OperatingSystem=@」に 1"
ManagementScope は動作していることが確認されているので、何が起こっているのかわかりません。私は WMI の初心者ですが、これは最も単純な使用例の 1 つのように思えます。
解決
うわー、世界は変わりつつあります。申し訳ありませんが、Vista を使用していることに気づきませんでした。ご覧のように ここ, 、Windows XP では状況が異なりました。では、[インスタンス] ボタンをクリックすると何が起こるでしょうか?
他のヒント
Win32_OperatingSystem はシングルトン クラスではありません。修飾子を確認すると、シングルトン修飾子が定義されていないことがわかります。そのため、ManagementObjectSearcher.Get() または ManagementClass.GetInstances() しか存在しない場合でも、それを使用する必要があります。クラスの 1 つのインスタンス。Win32_OperatingSystem キー プロパティは Name なので、次を使用してインスタンスを直接取得するオプションがあります。
ManagementObject OS = new ManagementObject(@"Win32_OperatingSystem.Name='OSname'")
しかし、私の経験では、OSName は常に次のようなものです。
「Microsoft Windows XP Professional|C:\WINDOWS|\Device\Harddisk0\Partition1」
したがって、ManagementObjectSearcher を使用するのがおそらく最も簡単な解決策です。
このシンプルなアプリを試してみましたが、うまくいきました
using System;
using System.Management;
namespace WmiPlay
{
class Program
{
static void Main(string[] args)
{
try
{
ManagementScope cimv2 = new ManagementScope(@"\\.\root\cimv2");
ManagementObject os = new ManagementObject(cimv2, new ManagementPath("Win32_OperatingSystem=@"), new ObjectGetOptions());
Console.Out.WriteLine(os);
}
catch (Exception ex)
{
Console.Error.WriteLine(ex);
}
}
}
}
これがうまくいくかどうか見てみましょう?通常、Vista x64 で管理者として実行している Visual Studio で実行しました。
答えを 100% 確信しているわけではありませんが、リフレクターを使用して ManagementObjectSearcher が何をするのかを調べてみたことはありますか?それはあなたが何を間違っているかについてのヒントを与えるかもしれません。
おそらく、Primary = true のインスタンスを取得するクエリを構築するでしょう。しばらく Win32_OperatingSystem を使用していませんでしたが、複数のインスタンスを取得したことを覚えているようです。現在起動されているインスタンスの Primary は true でした。
ダンカンは次のように書いています。
インスタンス ダイアログには次の内容が表示されます。「オブジェクトは 1 個」と「最大数は 1 個」バッチ:これらのフィールドに「1」を追加し、「Win32_OperatingSystem=@」をリストします。
確かにうまくいくようです。次のように、別のシングルトン クラスを使用してコードをテストできます。
「Win32_WmiSetting=@」
それでも例外が発生するかどうかを確認してください。