5

クライアントのマシンで実行されている Windows サービスを作成しました。このサービスは、それ自体の新しいバージョンを時折ダウンロードし、自己更新を実行します。つまり、新しいサービスをインストールし、開始し、古いサービスを停止し、最終的に削除します。サービスは、それ自体を直接停止して他の処理を実行することはできないため、別の実行可能ファイルをスピンして、いくつかの作業を実行します。これを正しく行うのは難しく、新しいサービスが新しい .Net Framework を使用して構築されている場合 (最近の .Net 2.0 から .net 4.0 への切り替えなど) は特に問題になります。問題は、.Net 2.0 ライブラリが .Net 4.0 サービスで動作できないことです。

さて、1 つのアプローチは、古いバージョンのサービスに、新しいバージョンに付属するヘルパー プログラムをスピンさせることです。いくつかのものが通常同じままであっても、バージョンを混同しない方が安全だと思います-設計の複雑さを抑えるのに役立ちます.

現在、Windows サービスで動作する .Net バージョンに依存しない方法があるようsc.exeです: ツール: http://support.microsoft.com/kb/251192

私が求めていたのは本当に特効薬なのだろうか。さて、私はこの男をプログラムで呼び出してエラーをチェックするので、API を使用することもできます。理想的には、SC.exe とインターフェイスするネイティブ exe にコンパイルされる 1 つのネイティブ C++ プロジェクトが必要です。これは可能ですか?そうでない場合、別のコンピューターで sc.exe を見つけるにはどうすればよいですか? それらは 32 ビットまたは 64 ビットであり、Win XP SP2/3 以降の任意のバージョンの Windows を実行しています。

私の質問、独創的なアイデア、または私がここで提起した正確な質問に対する回答について質問がある場合はお知らせください.


編集: 2.0 コードを使用して 4.0 サービスをインストールしようとすると、次の場合と同じエラーが発生します。

> C:\Windows\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe MyService4.exe

Microsoft (R) .NET Framework インストール ユーティリティ バージョン 2.0.50727.4927 Copyright (c) Microsoft Corporation. 全著作権所有。

インストールの初期化中に例外が発生しました: System.BadImageFormatException: ファイルまたはアセンブリ 'file:///[path]\MyService4.exe' またはその依存関係の 1 つを読み込めませんでした。このアセンブリは、現在読み込まれているランタイムよりも新しいランタイムによってビルドされているため、読み込むことができません..

4

4 に答える 4

2

sc.exe は実際には常に同じパス %windir%\System32\sc.exe にあります (x64 は 64 ビット バイナリに System32 を使用します :-)。現在のセットアップがどのように見えるかはわかりませんが、MSI を持っている場合、または MSI に切り替えることができる場合は、カスタム インストール アクションを実行できます。これは、SCM API を使用するか、単に sc.exe を起動する構成ファイルを使用して、新しい .exe にすることができます。 stop、config、start を 2 ~ 3 回実行します。技術的には、MSI のカスタム インストール アクションとして .cmd を使用することもできますが、見た目が少し悪いかもしれません (cmd ウィンドウが表示されます)。

SCM API を使いたいと思っていて、C++ を知っているなら、それが間違いなく最良の方法です。また、インストール タスク用に別のバイナリを用意すると、.NET の組み込みインストール手順に縛られなくなります。C# と C++ から同じ NT API にアクセスできます。重要なのは、停止、開始、構成などの管理タスクを実行するバイナリが、サービス自体のバイナリとは異なる必要があるということです-それは.NETの問題です-まとめます。

主要な切り替えを行っているため、以前のインストールが MSI の下にない場合、新しい MSI はそれ自体ですべてを処理することができないため、.cmd ファイルを文字通りドロップして停止してクリーンアップすることをお勧めします。 sc.exeを使用して古いサービスを削除し、クリーンを開始してから、新しいインストールバイナリを開始します-それが何であれ。MSI はウィンドウ サービスを停止してアンインストールしますが、それは以前に MSI によってインストールされていた場合のみです。それはちょっと粘着性があります:-)

于 2010-08-17T08:17:26.630 に答える
1

これが何を意味するのかわかりません:

問題は、.Net2.0ライブラリが.Net4.0サービスで動作できないことです。

このServiceControllerクラスは、ネイティブサービスを含め、あらゆるサービスを制御できます。試したことはありませんが、このServiceInstallerクラスを使用してサービスを(アン)インストールすることもできると思います。

ニーズを満たしていない場合は、の代わりにネイティブAPIを直接ラップすることをお勧めServiceControllerします。MSDNドキュメントで開始できます。サービスコントロールマネージャーの機能が必要になります。このプログラムは、SCMAPIの単なるコマンドラインラッパーです。ServiceInstallersc.exesc.exe

于 2010-08-06T22:01:16.863 に答える
1

ネイティブ C++ アプリは、ここに記載されている関数を呼び出すことができます: http://msdn.microsoft.com/en-us/library/ms685942(v=VS.85).aspx (他の人が言及した SCM API)

あなたはの線に沿って何かをしたいと思うでしょう

OpenSCManager
OpenService (or CreateService)
ChangeServiceConfig
CloseServiceHandle
于 2010-08-18T13:41:15.257 に答える
1

更新パッケージの一部として、バージョン間で変わらない名前の実行可能ファイルが含まれています。たとえば、Setup.exe :-)

このツールは、更新ロジックによって新しいプロセスとして起動されると、すべてのセットアップを行います。CLR のバージョン管理の問題を回避するために、パッケージの残りの部分と同じバージョンのフレームワークを使用してコンパイルする必要があります。

既存のクラスで私が遭遇した最大の問題ServiceInstallerは、説明や障害/回復アクションなどの新しいサービス機能がサポートされていないことです。これを回避するために、CodeProject の Narendra (Neil) Baliga のコードをServiceInstallerEx微調整し、代わりにそのクラスを使用しました。彼のコードには、同じ Windows API を呼び出すために必要なp-invoke 定義SC.exeが含まれています。

多少の関連: 更新の要件が以前に使用したものと似ている場合は、サイド バイ サイド フォルダー (名前にバージョン/リリース番号が含まれる) にインストールし、最後の 2 つまたは 3 つを保持することをお勧めします。ロールバック。現在のバージョンのパスをセットアップ ツールに渡して、現在のプレイ状態を把握します。

于 2010-08-12T15:31:44.147 に答える