2013-10-24 38 views
0

我已經創建了一個安裝Windows服務的安裝程序。我在VS 2010中使用了Visual Studio默認安裝程序。BeforeInstall安裝程序方法之前鉤 - Windows Installer

服務將訪問並寫入安裝文件夾中存在的數據庫文件(SQLite)。

在卸載過程中,當服務停止或正在運行時,服務正在卸載而沒有任何錯誤。

但是,如果安裝程序從版本1遷移到2,並且以前版本的服務正在運行,則顯示「文件正在被某個應用程序訪問,再次嘗試」錯誤,因爲之前的安裝服務正在訪問DB文件。

所以我需要在安裝新版本之前停止以前的版本服務。 我有一個用於管理安裝和卸載的自定義操作腳本。 在BeforeInstall方法我寫了代碼來停止服務使用ServiceController。這可以停止服務。

ServiceController service = new ServiceController(「SERVICE_NAME」);

如果(!(service.Status.Equals(ServiceControllerStatus.Stopped)))

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

    } 

但是,即使之前BeforeInstall方法安裝程序複製新版本的文件替換我的以前版本的文件。

我總是有相同的安裝文件夾。 因此,如果我編寫代碼來停止BeforeInstall自定義操作中的服務,它仍然會拋出錯誤,因爲前一版本服務正在訪問的數據庫文件被嘗試刪除新版本。所以我得到「文件正在被訪問一些應用程序,再試一次「。

所以我甚至在安裝程序將文件複製到安裝文件夾之前需要一些鉤子。這樣,我可以在安裝程序嘗試更新Db文件之前停止該服務。

任何想法,將不勝感激。

回答

2

Windows Installer沒有「安裝前」的概念。這是一個Visual Studio安裝和部署項目抽象。此項目類型未能公開許多底層Windows Installer功能,這就是微軟在VS2012中將其取消的原因。

另一個未公開的概念是ServiceInstall和ServiceControl表。這就是爲什麼你被迫編寫自定義操作的原因。自定義操作以這種方式託管(超出您的控制範圍),以便在出現問題時用CLR版本紋理MSIEXEC進程並拋出模式1001例外(即使在無提示安裝期間)。

但有一個解決方案。切換到更好的工具,例如免費和開源的Windows安裝程序XML(WiX)和工業級Windows安裝程序XML(IsWiX)。使用這些工具,您可以創建一個Windows服務,爲其創建安裝程序並在10分鐘內測試VM上的安裝/卸載。觀看我的沉默演示:

Building and Deploying a Windows Service using IsWiX