一般應用程式的製作非常容易,基本上就是把您的應用程式拖入該安裝程式的過程。如果您的應用程式的運行需要資料庫的支援(如SQL Server),問題就變得比較複雜一點。
主要有如下幾個方面的問題:
(1) 如何在獲得安裝畫面的值,比如獲得使用者輸入的使用者名稱密碼。
(2) 如何設計一個程式來與資料庫伺服器進行互動,建立新的資料庫。
如何在獲得安裝程式中的值,可以參看如下連結,這裡我們不做太多的介紹。
<http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vsintro7/html/vxconATourOfVisualStudio.asp>
這個例子示範了如何在使用者介面自訂對話方塊要求使用者輸入資訊,然後在自訂動作中把獲得的值通過CustomActionData來傳遞給自訂動作中的主輸出,最後在主輸出相面裡面的程式裡面來建立一個資料庫。
通過對上面的例子的理解,基本上可以按照這個方式來建立一個資料庫,它通過ADO.net執行SQL語句來完成建立資料庫的。但是,如果有大量的資料表以及預存程序需要建立,通過這個的方式非常麻煩。可不可以通過直接在SQL Server中建立相應的資料庫產生指令檔來直接完成呢?
我們有3個解決方案:
(1) 通過調用osql來執行資料庫指令碼檔案
(2) 通過把相應的指令檔作為資源檔嵌入到項目中,然後通過ADO.net來執行
(3) 通過調用SQL Server的sp_attach_db的預存程序來直接附加資料庫。
2.1 通過調用osql來執行資料庫指令碼檔案
從上面的例子我們已經知道了如何傳遞值,那麼我們只要在專案檔中程式段中執行osql即可。
這裡有一個問題就是從什麼地方找到資料庫的指令檔。我們可以把指令檔放到檔案系統中,直接安裝到使用者機器上,並可以通過如下方法獲得到該檔案的位置。
Assembly asm=Assembly.GetExecutingAssembly();
String setuppath=asm.Location;
這樣我們就可以知道指令檔的位置了,下面的檔案就是如何啟動osql程式了。我們可以通過如下的程式碼片段來完成:
Process sqlprocess=new Process(); sqlprocess.StartInfo.FileName="osql.exe";
sqlprocess.StartInfo.Arguments=String.Format("-U {0} -P {1} -S {2} -i {3}",this.uid,this.pwd,this.serverip,this.spath); //uid 為使用者名稱,pwd為密碼,serverip為目標伺服器的ip,spath為資料庫指令碼所在的路徑
sqlprocess.StartInfo.WindowStyle=ProcessWindowStyle.Hidden;
sqlprocess.Start();
sqlprocess.WaitForExit(); //等待程式執行
sqlprocess.Close();
從上面可以知道,該方法必須要求安裝程式的客戶機以及安裝好了SQL Server才能使用(osql為安裝了SQL Server後提供的命令列下的程式).同時在實際的測試過程中,我們發現如果對於使用者在安裝程式是選擇帶有空格的路徑,如;C:\program files\yourappliaction\時,安裝失敗。這個是一個比較嚴重的問題。
2.2 通過把指令檔作為資源檔載入
從前面的討論中我們可以看到,直接使用ADO.net執行時比較麻煩,需要一句句執行,如果使用指令碼,資料庫中產生的指令碼中有”GO”命令,在ADO.net中執行時會出問題。因此,根據對資料庫安裝指令碼的分析,我們可以採用如下替代方案。
在資料庫的安裝過程中,無外乎如下幾個部分:
(1) 建立資料庫
(2) 建立表
(3) 建立試圖或者預存程序
並且這三個部分是有先後順序的,順序不能顛倒,但是每個過程中沒有循序關聯性。在測試過程中我們發現可以在一條語句中建立多個表或者多個預存程序。也就是說,我們可以把執行過程按照上面的順序執行就行了。並且我們把資料庫指令碼作為資源檔嵌入,只要調入執行就可以了,這樣就達到了簡化建立一條條命令的過程。
獲得資源檔代碼如下:
Assembly Asm=Assembly.GetExecutingAssembly();
StreamReader str;
str=new StreamReader(Asm.GetManifestResourceStream(Asm.GetName().Name+"."+filename))// filename為你需要摘入的資源檔。作為資源檔時,只要把檔案匯入到您的項目中,並且把產生操作改為內嵌資源即可。
這裡我們是直接獲得了該檔案的檔案流,因此直接把該流中的內容讀入即可。
我們可以通過如下操作完成:
(1) 建立一個資料庫的連結,建立資料庫. 比如: connectionstring=”server=127.0.0.1,uid=sa,pwd=pwd”;
(2) 重新建立一個資料庫連結,該連結指向建立的資料庫。connectionstring=”server=127.0.0.1,uid=sa,pwd=pwd,database=yourdatabase”;
(3) 在新的連結中執行建立資料表和資料存放區過程的代碼即可。
需要注意的是:不要在你的指令碼中有GO命名,其他命令都可以直接執行。
該方法的好處在於: 可以不要求安裝的目標機上有SQL Server,也不存在因為檔案路徑中有空格的問題而倒是安裝程式失敗。當然,如果您的資料庫為Oracle或者DB2等,您也可以採用類似的方法來實現。
2.3 通過sp_attach_db來建立資料庫
通過上面的討論我們已經很清楚如何安裝資料庫了。在安裝資料庫的過程中,我們除了可以通過資料庫指令碼來建立資料庫之外,我們也可以通過SQL Server的系統預存程序sp_attach_db來附加資料庫。
這裡我們解決兩個問題即可:
(1) 確定資料庫檔案(.mdf和.ldf)的位置。
(2) 執行預存程序。
對於問題1我們可以借鑒安裝資料的第一種方法,即把.mdf和.ldf通過檔案系統安裝到目標機上,然後通過
Assembly asm=Assembly.GetExecutingAssembly();
String setuppath=asm.Location;
獲得檔案的路徑。
最後通過調用sp_attach_db 加上相應的參數即可完成。
需要注意的是: 該方法也只能針對資料庫安裝在原生情況下進行安裝。
總結
本文通過介紹了三種不同的方法來在安裝程式是如何安裝資料庫,同時也分析了不同的方法的優劣之處,使用者可以根據自己的實際需要來選擇安裝方法。同時,通過該方法的提出,使用者也可以完成在安裝程式是對資料庫的配置工作。