之前转了一篇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自带的程序)来实现还原数据库的备份。不同的的是现在放在了安装程序做。读者完全可以尝试在一个命令行下先做。看看数据库是否已经被成功安装。