The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

在 Setup 專案中開發自訂動作(Custom Actions)應注意的事

我在 Setup 專案的自訂動作(Custom Actions)裡經常會寫許多判斷,用以檢查安裝過程中一些必要的條件是否成立,例如資料庫是否可正常連線、適當的安裝參數是否有正常傳入、…等等。但是在檢查的過程中若發現條件不足時,正確的回應方式應該要使用 InstallException 類別丟出例外狀況,讓安裝程式進行復原(Rollback)動作,但是這個 InstallException 例外狀況的「發生點」也是挺重要的。

一開始我都是用 override 的方式撰寫自訂動作:

public override void Install(IDictionary stateSaver)
{
  if(...)
     throw new InstallException("安裝過程發生錯誤");

    base.Install(stateSaver);
}

不過當錯誤發生時,卻會出現以下第二張圖的錯誤訊息:

Error 1001. 安裝過程發生錯誤

Error 1001. 在安裝的復原階段發生例外狀況。將略過此例外狀況,而繼續復原。然而,復原完成之後,電腦可能將無法完全還原成原來的狀態。 –> savedState 字典沒有包含預期的值,而且可能已經損毀。 

如果是英文訊息的話,錯誤訊息如下:

Error 1001. An exception occurred during the Rollback phase of the installation. This exception will be ignored and the rollback will continue. However, the machine might not fully revert to its initial state after the rollback is complete. --> The savedState dictionary does not contain the expected values and might have been corrupted.

測試了一段時間後才發現,原來引發 InstallException 例外狀況時不能在 base.Install(stateSaver); 之前,否則當例外發生時就會出現這個奇怪的錯誤訊息。

到後來,我就全部改成用「事件」的方式撰寫自訂動作,當然,引發 InstallException 例外狀況時一樣要放在 AfterInstall 這個事件裡,範例程式如下:

public Installer1()
{
  //System.Diagnostics.Debugger.Launch();

  InitializeComponent();

  this.BeforeInstall += new InstallEventHandler(Installer1_BeforeInstall);
  this.AfterInstall += new InstallEventHandler(Installer1_AfterInstall);

  this.Committing += new InstallEventHandler(Installer1_Committing);
  this.Committed += new InstallEventHandler(Installer1_Committed);

  this.BeforeUninstall += new InstallEventHandler(Installer1_BeforeUninstall);
  this.AfterUninstall += new InstallEventHandler(Installer1_AfterUninstall);
}

相關連結