2

Windowsサービスのパスを取得したいのですが、

var managementObjectSearcher = new ManagementObjectSearcher("Select * from Win32_Service where serviceName = MyService");

このコードは、他のサービスのコンストラクターで書かれています。

システムが稼働しているときはすべて正常に動作しますが、システムを再起動すると、この呼び出しにStopWatchクラスが設定され、この呼び出しのためにサービスの開始に35〜45秒かかることが示されます。

システム再起動時のパフォーマンスを改善するための提案...

4

3 に答える 3

7

Windows32_Servicesクラスが存在しないため、どちらのWin32_ServiceWMIクラスを使用している場合でも、使用するプロパティ(この場合は)を返すだけでパフォーマンスを向上させることができるため、PathNameWQL文を次のように変更します。

SELECT PathName FROM Win32_Service Where Name='MyService'

アップデート

@Baconに対して行われた観察は非常に正しいです。取得するサービスの名前がわかっているので、次のようなWin32_Serviceのオブジェクトパスを作成できます。

Win32_Service.Name="ServiceName"

そして、ManagementObjectクラスを使用すると、最速の方法でインスタンスをサービスに取得できます。

于 2012-05-08T17:05:17.963 に答える
2

Nameのキープロパティであるによってサービスを取得しているのでWin32_Service class、インスタンスを検索するのではなく、直接取得してみてください。

string GetMyServicePath()
{
    string path = "Win32_Service.Name=\"MyService\"";

    using (ManagementObject service = new ManagementObject(path))
        return (string) service.GetPropertyValue("PathName");
}

これは、直接検索と検索を比較するために一緒に作成した簡単なベンチマークです。

private const int LoopIterations = 1000;

private const string ServiceClass = "Win32_Service";
private const string ServiceName = "MyService";
private const string ServiceProperty = "PathName";

private static readonly string ServicePath = string.Format("{0}.Name=\"{1}\"", ServiceClass, ServiceName);
private static readonly string ServiceQuery = string.Format(
    "SELECT {0} FROM {1} Where Name=\"{2}\"",
    ServiceProperty, ServiceClass, ServiceName
);
private static ManagementObjectSearcher ServiceSearcher = new ManagementObjectSearcher(ServiceQuery);

static void Main(string[] args)
{
    var watch = new Stopwatch();

    watch.Start();
    for (int i = 0; i < LoopIterations; i++)
    {
        var servicePath = GetServicePathByKey();
    }
    watch.Stop();
    Console.WriteLine(
        "{0:N0} iterations of GetServicePathByKey() took {1:N0} milliseconds",
        LoopIterations, watch.ElapsedMilliseconds
    );

    watch.Restart();
    for (int i = 0; i < LoopIterations; i++)
    {
        var servicePath = GetServicePathFromExistingSearcher();
    }
    watch.Stop();
    Console.WriteLine(
        "{0:N0} iterations of GetServicePathFromExistingSearcher() took {1:N0} milliseconds",
        LoopIterations, watch.ElapsedMilliseconds
    );

    watch.Restart();
    for (int i = 0; i < LoopIterations; i++)
    {
        var servicePath = GetServicePathFromNewSearcher();
    }
    watch.Stop();
    Console.WriteLine(
        "{0:N0} iterations of GetServicePathFromNewSearcher() took {1:N0} milliseconds",
        LoopIterations, watch.ElapsedMilliseconds
    );
}

static string GetServicePathByKey()
{
    using (var service = new ManagementObject(ServicePath))
        return (string) service.GetPropertyValue(ServiceProperty);
}

static string GetServicePathFromExistingSearcher()
{
    using (var results = ServiceSearcher.Get())
    using (var enumerator = results.GetEnumerator())
    {
        if (!enumerator.MoveNext())
            throw new Exception();

        return (string) enumerator.Current.GetPropertyValue(ServiceProperty);
    }
}

static string GetServicePathFromNewSearcher()
{
    using (var searcher = new ManagementObjectSearcher(ServiceQuery))
    using (var results = searcher.Get())
    using (var enumerator = results.GetEnumerator())
    {
        if (!enumerator.MoveNext())
            throw new Exception();

        return (string) enumerator.Current.GetPropertyValue(ServiceProperty);
    }
}

サーチャーの結果を直接列挙するのは、私が作成できる速度とほぼ同じで、ブロックを使用するよりもわずかに速く、を使用する場合のforeach2倍の速度LINQです。ServiceName定数を設定した64ビットWindows7Professionalシステムでは、Power次の結果が得られました。

1,000 iterations of GetServicePathByKey() took 8,263 milliseconds
1,000 iterations of GetServicePathFromExistingSearcher() took 64,265 milliseconds
1,000 iterations of GetServicePathFromNewSearcher() took 64,875 milliseconds
于 2012-05-08T19:18:32.607 に答える
2

気になるのがWMIの「待機時間」である場合、サービスのパスを取得するためにWMIを使用する必要はありません。実行可能ファイル名。QueryServiceConfigをP/呼び出しすることもできます。

http://www.pinvoke.net/default.aspx/advapi32/queryserviceconfig.html

于 2012-05-08T20:02:29.403 に答える