之前轉了一篇c#程序數據庫安裝的文章,原作者用的是vb來寫的安裝程序。我想更多人應該青睞於使用c#,畢竟也是c#的程序打包,作者對c#一定比VB熟悉。之前的vb代碼本人安裝數據庫程序沒用成功,估計原因是sql語句執行的問題。尤其是數據庫本分的邏輯名要寫對。本人用C#代碼改寫後,修正了數據庫安裝部分的代碼,並添加了配置文件寫入功能。
現貼出自己的代碼。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration.Install;
using System.IO;
using System.Xml;
using System.Text;
namespace installDBbyCs
{
[RunInstaller(true)]
public partial class InstallerDB : Installer
{
public InstallerDB()
{
InitializeComponent();
}
public override void Install(System.Collections.IDictionary stateSaver)
{
base.Install(stateSaver);
//設置配置文件
SetConfing();
try
{
//恢復數據庫
ReStoreDb();
}
catch(Exception ex)
{
this.Uninstall(stateSaver);
throw ex;
}
}
/// <summary>
/// 設置配置文件
/// </summary>
private void SetConfing()
{
FileInfo file = new FileInfo(this.Context.Parameters["targetdir"] + "DbConfig.xml");
XmlDocument doc = new XmlDocument();
doc.Load(file.FullName);
foreach (XmlNode node in doc.SelectSingleNode("DbConfig").ChildNodes)
{
if (node.Name == "name") node.InnerText = this.Context.Parameters["user"];
if (node.Name == "DataBase") node.InnerText = this.Context.Parameters["dbname"];
if (node.Name == "placeId") node.InnerText = this.Context.Parameters["placeId"];
if (node.Name == "password") node.InnerText = this.Context.Parameters["pwd"];
}
doc.Save(file.FullName);
// doc.Save(this.Context.Parameters["targetdir"] + "DbConfig.xml");
}
private void DeleteFile(string FileFulName)
{
FileInfo file = new FileInfo(FileFulName);
if (file.Exists)
{
file.Delete();
}
}
public override void Uninstall(System.Collections.IDictionary savedState)
{
base.Uninstall(savedState);
this.DeleteFile(this.Context.Parameters["targetdir"] + "DB.dat");
}
/// <summary>
/// 還原數據庫
/// </summary>
public void ReStoreDb()
{
string dbName = this.Context.Parameters["dbname"];
string bakFile = this.Context.Parameters["targetdir"] + "DB.dat";
string toFile = this.Context.Parameters["targetdir"];
CreatSql(dbName,bakFile);
setupDB();
}
/// <summary>
/// 創建還原的sql
/// </summary>
/// <param name="db"></param>
/// <param name="path"></param>
/// <returns></returns>
private void CreatSql(string db,string path)
{
string strToFileName = this.Context.Parameters["targetdir"];
//這個邏輯名根據備份的數據庫各異,可以通過SQL來獲取,這裏不給出具體SQL
string logicName = "TestSystem";
StringBuilder sql = new StringBuilder();
sql.AppendLine("GO");
sql.AppendLine("RESTORE DATABASE [" + db + "] FROM DISK = N'" + path + "' WITH FILE = 1, NOUNLOAD , STATS = 10, RECOVERY , MOVE N'" + logicName + "_Data' TO N'" + strToFileName + db + ".mdf', MOVE N'" + logicName + "_Log' TO N'" + strToFileName + db + "_log.ldf'");
System.IO.StreamWriter file = new System.IO.StreamWriter(String.Format("{0}Mydb2000tp.sql", this.Context.Parameters["targetdir"] ));
file.Write(sql.ToString());
file.Close();
}
/// <summary>
/// 用osql.exe運行sql腳本
/// </summary>
private void setupDB()
{
System.Diagnostics.Process sqlProcess = new System.Diagnostics.Process();
sqlProcess.StartInfo.FileName = "osql.exe";
sqlProcess.StartInfo.Arguments = String.Format(" -U {0} -P {1} -i /"{2}Mydb2000tp.sql/" -o /"{3}/"", this.Context.Parameters["user"], this.Context.Parameters["pwd"], this.Context.Parameters["targetdir"], this.Context.Parameters["targetdir"] + "Dbsetup.log");
sqlProcess.Start();
sqlProcess.WaitForExit();//等待執行
sqlProcess.Close();
//刪除腳本文件
DeleteFile(String.Format("{0}Mydb2000tp.sql", this.Context.Parameters["targetdir"]));
}
}
}
既然有人問,我就寫清楚一點。這裏做的數據庫安裝其實是把原本要手動的還原數據庫的備份用程序來實現。其實原本可以通過寫SQL的方式利用osql.exe(sqlserver自帶的程序)來實現還原數據庫的備份。不同的的是現在放在了安裝程序做。讀者完全可以嘗試在一個命令行下先做。看看數據庫是否已經被成功安裝。