Visual Studioセットアッププロジェクトでの、カスタム動作の使い方です。
カスタム動作を使うとVisualStudioで作ったインストーラだけでは難しい操作が行えるみたいです。
カスタム動作の発生するイベントには、インストール時、確定時、ロールバック時、アンインストール時に指定した動作を行えることができます。
カスタム動作自体も、すでにビルドされたDLLやEXE以外にもInstallerクラスを使う方法があります。
今回の自分がしたい要件は下記の通りです。
・ソフト配布用アーカイブを解凍した一時フォルダをインストール確定後に削除。
・ソフトのデータ用ファイルを任意の場所にコピー。
上記をInstallerクラスを使った方法でやってみました。
まず、配置プロジェクトと同じソリューションにクラスライブラリプロジェクトを作成します。
そのクラスライブラリにクラスを追加するため、新しい項目から「インストーラ クラス」を選択します。
(別にインストーラクラスじゃなくてもInstallerを継承したクラスを作り、属性RunInstallerをtrueにすればいいだけみたいです。)
このクラスに中に親クラスのInstall , Commit , Rollback , Uninstallメソッドをオーバライドして、各イベント時の処理を書きます。
下記が一時フォルダ削除とデータ用ファイルコピーの処理を確定時に実行するよう記述したソースです。
(プロジェクト名は InstallClass とします。)
/// <summary> /// Installerから呼び出されるクラス。インストール、アンインストール時のカスタム動作を記述する /// </summary> [RunInstaller(true)] public partial class InstallClass : Installer { public InstallClass() { InitializeComponent(); } /// <summary> /// インストール確定時の処理をオーバーライド。 /// アーカイブ一時解凍フォルダ削除。 /// データファイルを既定のフォルダにコピー。 /// </summary> /// <param name="savedState"></param> public override void Commit(System.Collections.IDictionary savedState) { base.Commit(savedState); try { //一時フォルダ取得(システムの一時ディレクトリ) string tmpDir = Path.GetTempPath(); tmpDir += "\\解凍したフォルダ名"; if (Directory.Exists(tmpDir)) { //インストール時に使用した一時データ削除 Directory.Delete(tmpDir, true); } //データファイルをC:\aaa\bbbフォルダにコピー string AppDataFld = Environment.GetEnvironmentVariable("SystemDrive"); AppDataFld += "\\aaa\\bbb\\"; //C:\aaa\bbbが存在しないときのみDBファイルコピー if (!Directory.Exists(AppDataFld)) { Directory.CreateDirectory(@AppDataFld); //インストーラからインストールフォルダのパスを取得する string instDir = this.Context.Parameters["dir"]; File.Copy(instDir + "データファイル名", AppDataFld + "データファイル名"); } } catch { //エラー時は何もしない } } }
あとは配置プロジェクト側の設定となります。
配置プロジェクトのファイルシステム→アプリケーションフォルダにて、InstallClassプロジェクト(Installerクラスのあるプロジェクト)をプライマリ出力します。
配置プロジェクトを右クリック→カスタム動作で、確定を右クリック→カスタム動作の追加を選択し、上記で指定したアプリケーションフォルダのInstallClassのプライマリ出力を選択します。
InstallClassにインストール先のアプリケーションフォルダを教えるために、カスタム動作→InstallClassのプライマリ出力の下記プロパティに値をしています。また、InstallerClassのプロパティもTrueにしないといけません。(Exe等をカスタム動作にするときはInstallerClassのプロパティをFalseにします)
CustomActionDataプロパティ:/dir="[TARGETDIR]\" InstallerClassプロパティ:True
ここで指定した値をInstallClassで取得するときは下記のようにおこなえます。
this.Context.Parameters["dir"];
これで試してみたのですが、「InstallStateが見つかりません」というエラーが発生しました。
いろいろ探した結果こちらに解決策が書かれてました。
どうやらインストール確定時だけ動かしたいときでも、配置プロジェクトのカスタム動作の「インストール」にもInstallクラスのプライマリ出力を加えないといけないようです。
ただ、いろいろ試してみたところ、アンインストールしたときに*.InstallStateファイルが残るときがあるみたいです。
詳しく調べてみる必要がありそうです。
参考(カスタム動作以外にも、VisualStudioセットアッププロジェクトの使い方のリンクも入れてます)
VSセットアッププロジェクトのプロパティ
.NET Visual Studio Installerを使ったインストーラの作成 VSでのインストーラ作成がわかりやすく解説されてます。
カスタム動作エディタの使い方
チュートリアル : カスタム動作を使用した、インストール時のアセンブリのプリコンパイル MS公式のチュートリアルです