CのWindowsサービス#

まえがき


Windowsサービスは、システムをフロート状態に保つことからペアレンタルコントロールサービスまで、ほとんどすべてを管理します。 タスクマネージャには、Windowsに組み込まれた別のユーティリティは言うまでもなく、レビューと停止/開始のためのツールがあります。 しかし、そのようなツールをプログラムに統合する必要がある場合はどうでしょう。 これらすべての情報はどこで入手できますか? サービスを管理する方法は? C#でどのように処理したか、どのような困難に遭遇したかを説明します。



それがすべて始まった方法


私は初心者のC#アプリケーション開発者です。 より正確には、私は約1年前に初心者でした。 今、私は特別な欲求があれば、非常に複雑なものを開発できると思います。 まあ、それはポイントではありません。 一般に、サービスを管理するために最も必要な機能を正しく表示し、所有するユーティリティを作成する必要がありました。 Windowsマネージャーの既存の機能のようなもの。



すべてが描かれた方法


インターフェイスは富を脅かすものではなかったため、ツールバーとサービスが表示されるリストで停止することにしました。 後者としてDataGridViewが選択されました。これは、情報を円柱形で表示するためです。これは私にとって非常に便利であり、ユーザーにとっても便利です(ソートなど)。

ツールバーには、選択したサービスを制御する約6つのボタンがありました。

インターフェイスを描く段階で問題はなく、わずか数時間で正常に完了しました。



すべてが開発された方法


まず、2つのメカニズムが必要でした。1つ目は、このマシンに登録されているすべてのサービスとそれらに関する情報を見つけることであり、2つ目は、これらすべてをDataGridViewに正しく駆動します。 2番目の問題が発生していないはずです。 しかし、最初のものは苦しめなければなりませんでした(そして判明したように、それは開発の中で最も難しい部分でした)。 彼についての詳細...



計画どおり、システムで各サービスに関する次の情報を見つける必要がありました。名前ではなく、システムではなくユーザー。 サービスの説明。 彼女の状態; 起動タイプ; ファイルへのパスと、そのファイルの代わりに起動されたファイル。 名前に問題はありませんでした-ServiceControllerクラスのDisplayNameは非常に正しく表示していました。 ステータスもそれほど難しくありません-同じクラスのStatusプロパティが大いに役立ちました。 しかし、誰がサービスを開始したのか、どのタイプのサービスを開始したのか、画像はどこにあるのかを知るには、すでにレジストリに登らなければなりませんでした。 また、原則として、非常に複雑なものはありませんが、以前の属性よりも長く座っていなければなりませんでした。



物事が複雑になった方法


結局のところ、つまずきのブロックは、ユーザーが理解できるサービスの説明でした。 それを取得する方法を探し始めたので、ServiceControllerもレジストリも通常の説明を提供できないことに気付きました。 多くの場合、レジストリのDescription行には、dllライブラリへのリンクと、このライブラリ内でサービスの説明が含まれている行番号が含まれています。 そして、C#はまだdllから情報を動的に取得する方法を知らないので、リストを更新するたびにレジストリを調べ、そこでリンクと行番号を取得し、ライブラリに移動してロードし、行を探し、説明をコピーしてライブラリをダウンロードします 予想どおり、これはパフォーマンスにひどい影響を及ぼしました。 このような控えめなプログラムの最初の起動には5秒かかります(ただし、その後の更新は非常に迅速に行われます)。



それがすべて終わった方法


他のすべて(コントロール、DataGridでの情報出力、リストの更新後にフォーカスを戻し、所定の場所に並べ替えるという形でのユーザーの利便性など)は非常に簡単でした。 試行錯誤(およびネットワークでの無数のざわめき)により、これはすべて達成されました。 その結果、ユーティリティは非常に便利であることが判明し、タスクマネージャの標準サービスの代わりにテストとして使用することに同意する人さえいました。

これが動作中のプログラムの画面です 画像



コードは(主要部分も含めて)非常に膨大です。説明情報の検索に関する部分は次のとおりです。



val = targetKey.GetValue( "説明");

if(val == null)

行[1] = ""; //説明なし

他に

{

文字列s =(文字列)val;

Match m = Regex.Match(s、@ "^ [@](?(。*))、\ S *-(?(\ D *))");

if(m.Success)//文字列がリソース参照であるかどうかを確認

{

string w1 = m.Groups ["path"]。値; // dllへのパス

//パス内のシステム変数%SystemRoot%を置き換えます(存在する場合)

string w2 = Regex.Replace(w1、@ "%SystemRoot%|%windir%"、SystemRootPath、RegexOptions.IgnoreCase);

//パス内のシステム変数%ProgramFiles%を置き換えます(存在する場合)

string DllPath = Regex.Replace(w2、@ "%ProgramFiles%"、ProgramFilesPath、RegexOptions.IgnoreCase);

int ID = Convert.ToInt32(m.Groups ["id"]。Value); //リソースID

//必要なdllをロードします

IntPtr hndl = DllInterop.LoadLibrary(DllPath);

//説明を取得します

行[1] = DllInterop.LoadStringDll(hndl、ID);

// dllをアンロードします

DllInterop.FreeLibrary(hndl);

}

他に

行[1] = s;



PS(ほぼ確実に)「熱心な」開発者とプログラマーは自分自身に新しいものを見つけることはないと思いますが、C#でWindowsサービスを使用したことがない人は有益だと思います。 コードの一部またはプログラム自体が必要な場合は、ご連絡ください。大変助かります。



All Articles