インストーラーが新しいファイルのコピーを開始する直前に、古いインストール ディレクトリ (存在する場合) を削除するインストーラーが必要です。このフォルダーには、プログラムの使用中に生成されたいくつかのファイルとサブフォルダーが含まれており、インストーラーには含まれていません。このため、これを行うカスタム アクションを作成しました。
それで、いくつかのコード。まず、カスタム アクション コード (特別なものはありません):
[CustomAction]
public static ActionResult RemoveOldDatabase(Session session)
{
bool removeDatabase = session.CustomActionData["RemoveDatabase"] == "true";
string installDir = session.CustomActionData["InstallDir"];
if (removeDatabase)
{
try
{
Directory.Delete(installDir, true);
}
catch (Exception ex)
{
session.Log(ex.StackTrace);
}
}
return ActionResult.Success;
}
そしてwixコード(カスタムアクション呼び出しを定義します):
<CustomAction Id="actionCheckServerName" BinaryKey="actionBinary" DllEntry="CheckServerName" Execute="immediate" Return="check" />
<CustomAction Id="actionInstall" BinaryKey="actionBinary" DllEntry="Install" Execute="deferred" HideTarget="no" Impersonate ="no" Return="check"/>
<CustomAction Id="actionUninstall" BinaryKey="actionBinary" DllEntry="Uninstall" Execute="deferred" HideTarget="no" Impersonate ="no" Return="check"/>
<CustomAction Id="actionRemoveOldDatabase" BinaryKey="actionBinary" DllEntry="RemoveOldDatabase" Execute="deferred" HideTarget="no" Impersonate ="no" Return="ignore"/>
<CustomAction Id="actionGetNetworkComputers" BinaryKey="actionBinary" DllEntry="GetNetworkComputers" Execute="immediate" Return="check"/>
<CustomAction Id="SetInstallParameters" Return="check" Property="actionInstall" Value="InstallDir=[INSTALLDIR];ServerName=[SERVER_LIST];InstallMode=[SETUP_MODE];Single=[single];RemoveDatabase=[REMOVE_DATABASE]" />
<CustomAction Id="SetUninstallParameters" Return="check" Property="actionUninstsall" Value="UnInstallDir=[INSTALLDIR];ServerName=[SERVER_LIST];UnInstallMode=[INSTALL_MODE]" />
<CustomAction Id="SetRemoveOldDatabaseParameters" Return="check" Property="actionRemoveOldDatabase" Value="InstallDir=[INSTALLDIR];RemoveDatabase=[REMOVE_DATABASE]" />
<InstallExecuteSequence>
<Custom Action='AlreadyUpdated' After='FindRelatedProducts'>SELFFOUND</Custom>
<Custom Action='NoDowngrade' After='FindRelatedProducts'>NEWERFOUND</Custom>
<Custom Action="SetRemoveOldDatabaseParameters" Before="ProcessComponents"/>
<Custom Action="actionRemoveOldDatabase" After="SetRemoveOldDatabaseParameters">NOT Installed AND NOT UPGRADINGPRODUCTCODE</Custom>
<Custom Action="SetInstallParameters" Before="actionInstall"/>
<Custom Action="SetUninstallParameters" Before="RemoveFiles">Installed AND NOT REINSTALL AND NOT UPGRADINGPRODUCTCODE</Custom>
<Custom Action="actionInstall" Before="InstallFinalize">NOT Installed AND NOT UPGRADINGPRODUCTCODE</Custom>
<Custom Action="actionUninstall" After="SetUninstallParameters">Installed AND NOT REINSTALL AND NOT UPGRADINGPRODUCTCODE</Custom>
</InstallExecuteSequence>
どうしたの?ご覧のとおり、actionRemoveOldDatabaseは、インストーラーが新しいファイルのコピーを開始する前にトリガーする必要があります (パラメーターは SetRemoveOldDatabaseParameters によって既に設定されています)。そのため、古いファイルのみを削除する必要がありますが、これは起こりません。この方法でアクションactionRemoveOldDatabaseを実行すると、インストーラーが新しいファイルをコピーした後、インストールディレクトリが削除されます。したがって、インストーラーによってコピーされた新しいファイルはすべて削除されます。
わからない どうして?古い既存のフォルダのみを削除する方法と、カスタム アクションがコピーされたすべてのファイルを削除するのはなぜですか?
[編集] 私はすでにその理由を知っているようです. この場合、Install Dir は使用中であり (おそらく Windows インストーラーによってロックされます)、インストールの終了後に解放されます。カスタム アクションは、フォルダが解放されるまで待機してから削除します。残念ながら、手遅れです - フォルダーには既に新しいファイルが含まれています。
回避策を知っていますか?