0

Windows サービスをインストールするインストーラーを作成しました。VS 2010 で Visual Studio の既定のインストーラーを使用しました。

サービスは、インストール フォルダに存在するデータベース ファイル (SQLite) にアクセスして書き込みます。

サービスが停止中または実行中のアンインストール中に、サービスはエラーなしでアンインストールされます。

しかし、インストーラーがバージョン 1 から 2 に移行され、以前のバージョンのサービスが実行されている場合、以前のインストール サービスが DB ファイルにアクセスしていたため、「ファイルがアプリケーションによってアクセスされています。再試行してください」というエラーが表示されました。

そのため、新しいバージョンをインストールする前に、以前のバージョンのサービスを停止する必要があります。インストールとアンインストールを管理するためのカスタム アクション スクリプトがあります。メソッドではBeforeInstall、 を使用してサービスを停止するコードを記述しましたServiceController。これにより、サービスが停止する可能性があります。

ServiceController service = new ServiceController("SERVICE_NAME");

if (!(service.Status.Equals(ServiceControllerStatus.Stopped)))

    {
        service.Stop();
        service.WaitForStatus   (System.ServiceProcess.ServiceControllerStatus.Stopped);

    }

しかし、BeforeInstall方法の前であっても、インストーラーは新しいバージョンのファイルをコピーして、以前のバージョンのファイルを置き換えています。

私はいつも同じインストールフォルダを持っています。そのため、BeforeInstall カスタム アクションでサービスを停止するコードを記述しても、以前のバージョンのサービスによってアクセスされている DB ファイルが新しいバージョンによって削除されようとしたため、エラーがスローされます。アプリケーション。再試行してください。」

そのため、インストーラーがファイルをインストール フォルダーにコピーする前であっても、いくつかのフックが必要です。インストーラーが Db ファイルを更新しようとする前に、サービスを停止できるようにします。

任意のアイデアをいただければ幸いです。

4

1 に答える 1

2

Windows インストーラーには、「インストール前」という概念がありません。これは、Visual Studio のセットアップおよび展開プロジェクトの抽象化です。このプロジェクト タイプは、多くの基本的な Windows インストーラー機能を公開できませんでした。これが、Microsoft が VS2012 でそれを排除した理由です。

公開されていない別の概念は、ServiceInstall テーブルと ServiceControl テーブルです。これが、カスタム アクションの作成を余儀なくされている理由です。問題が発生した場合に、MSIEXEC プロセスに CLR バージョンをタトゥーし、(サイレント インストール中でも) モーダル 1001 例外をスローするような方法で (ユーザーの制御を超えて) ホストされるカスタム アクション。

しかし、解決策があります。無料でオープン ソースの Windows Installer XML (WiX) や Industrial Strength Windows Installer XML (IsWiX) などのより優れたツールに切り替えます。これらのツールを使用すると、Windows サービスを作成し、そのインストーラーを作成し、VM でのインストール/アンインストールを 10 分でテストできます。サイレント デモをご覧ください:

IsWiX を使用した Windows サービスの構築と展開

于 2013-10-24T11:36:39.320 に答える