[RunInstaller(true)] public partial class JSWyglInstaller : Installer { public JSWyglInstaller() { InitializeComponent(); } #region 程序代码
/// <summary> /// 数据库的操作 /// </summary> #region 数据库的操作属性集合 private System.Data.SqlClient.SqlConnection sqlConn;
private System.Data.SqlClient.SqlCommand Command;
private System.Data.SqlClient.SqlTransaction Trans;
private string DBName;
private string ServerName;
private string AdminName;
private string AdminPwd; ///dbname=[DBNAME] /server=[DBSERVERNAME] /user=[USERNAME] /pwd=PASSWORD] /iis=[IISSERVER] /port=[PORT] /targetdir="[TARGETDIR]\" #endregion /// <summary> ///IIS的操作 /// </summary> #region IIS操作属性 private string iis;
private string port;
private string dir;
public static string VirDirSchemaName = "IIsWebVirtualDir";
private string _target;
private DirectoryEntry _iisServer;
private ManagementScope _scope;
private ConnectionOptions _connection;
#endregion
//连接数据库服务器到方法: #region ConnectDatabase 连接数据库
private bool ConnectDatabase() { if (Command.Connection.State != ConnectionState.Open) { try { Command.Connection.Open(); }
catch(Exception e) { MessageBox.Show("打开数据库失败:"+e.Message); return false; }
} return true; } /// <summary> /// 开启事物 /// </summary> private void BeginTrans() { if (Trans == null) Trans = sqlConn.BeginTransaction(); if(Command.Transaction==null) Command.Transaction = Trans; } /// <summary> /// 提交事物 /// </summary> private void CommitTrans() { if (Trans != null) Trans.Commit(); }
private void RollBack() { if (Trans != null) Trans.Rollback(); }
#endregion
//如果不能正确连接数据库服务器,请检查你的连接字符串,或者将连接字符串写入文件查看 //读取SQL文件的方法: #region GetSql 从文件中读取SQL,在读取包含SQL脚本的文件时需要用到,参考自MSDN
private string GetSql(string Name) {
try { //MessageBox.Show("GetSql"+Name); Assembly Asm = Assembly.GetExecutingAssembly();
Stream strm = Asm.GetManifestResourceStream(Asm.GetName().Name + "." Name);
StreamReader reader = new StreamReader(strm);
return reader.ReadToEnd(); } catch (Exception getException) { MessageBox.Show("读取文件错误:" + getException.Message); return string.Empty; //throw new ApplicationException("读取文件错误:"+getException.Message); } }
#endregion
//可以将此需要执行的SQL脚本放在此文本中 //执行SQL语句的方法:
#region ExecuteSql 执行SQL语句,参考自MSDN
private void ExecuteSql(string DataBaseName, string sqlstring) { //MessageBox.Show("ExecuteSql:DataBaseName"+DataBaseName +"-SqlString:"+sqlstring); Command = new System.Data.SqlClient.SqlCommand(sqlstring, sqlConn); if (ConnectDatabase()) { try { Command.Connection.ChangeDatabase(DataBaseName); Command.ExecuteNonQuery(); //MessageBox.Show("ChangeDataBaseSuccess");
} finally { Command.Connection.Close(); } } }
private void ExecuteSqlForTrans(string DataBaseName, string sqlstring) { //MessageBox.Show("ExecuteSql:DataBaseName"+DataBaseName +"-SqlString:"+sqlstring); if(Command==null) Command = new System.Data.SqlClient.SqlCommand(sqlstring, sqlConn); if (ConnectDatabase()) { try { BeginTrans(); Command.Connection.ChangeDatabase(DataBaseName); Command.ExecuteNonQuery(); //MessageBox.Show("ChangeDataBaseSuccess");
} catch(Exception ex) { if (Trans != null) Trans.Rollback(); Command.Connection.Close(); //throw new Exception("创建数据库 [" + DBName + "] 错误:" + ex.Message); MessageBox.Show("创建数据库 [" + DBName + "] 错误:" + ex.Message); } } }
#endregion
//创建数据库及数据库表: #region CreateDBAndTable 创建数据库及数据库表,参考自MSDN
protected bool CreateDBAndTable(string DBName) { bool Restult = false;
try { //MessageBox.Show("CreateDBAndTable"); if (string.IsNullOrEmpty(DBName)) return false; ExecuteSqlForTrans("master", "USE MASTER IF EXISTS (SELECT NAME FROM SYSDATABASES WHERE NAME='" + DBName + "') DROP DATABASE " + DBName); ExecuteSqlForTrans("master", "CREATE DATABASE " + DBName); ExecuteSqlForTrans(DBName, GetSql("DBSQL.txt")); CommitTrans(); Restult = true; }
catch (Exception ex) { MessageBox.Show("CreateDBAndTable"+ex.Message); //throw new Exception("创建数据库 [" + DBName + "] 错误:" + ex.Message); } finally { if(Command!=null) Command.Connection.Close(); }
return Restult;
}
#endregion
//从备份文件恢复数据库及数据库表 #region RestoreDB 从备份文件恢复数据库及数据库表
/// /// 从备份文件恢复数据库及数据库表 /// ///数据库名 ///配件中数据库脚本资源的名称 ///
protected bool RestoreDB(string DBName) { string dir = this.Context.Parameters["targetdir"];
//MessageBox.Show("DBDir:" + dir);
dir += @"DBInit\";
bool Restult = false;
string MSQL = "RESTORE DATABASE " + DBName +
" FROM DISK = N'" + dir + @"wygl.bak' " +
" WITH MOVE 'TXFee_Data' TO N'" + @"c:\" + DBName + ".mdf', " +
" MOVE 'TXFee_log' TO N'" + @"c:\" + DBName + ".ldf' ";
try {
ExecuteSql("master", "USE MASTER IF EXISTS (SELECT NAME FROM SYSDATABASES WHERE NAME='" + DBName + "') DROP DATABASE " + DBName); ExecuteSql("master", MSQL); //CommitTrans(); Restult = true;
} catch(Exception ex) { MessageBox.Show("创建数据库 [" + DBName + "] 错误:" + ex.Message); //throw new Exception("创建数据库 [" + DBName + "] 错误:" + ex.Message); } finally {
if (Command != null) Command.Connection.Close(); #region 作废 // 删除备份文件 //try //{
// File.Delete(dir + @"wygl.bak");
//} //catch //{
//} #endregion
} return Restult;
}
#endregion
//这里可以到注册表读取SQL Server的安装路径,把恢复后的数据库文件放到data目录地下。 //在本例中,只是实现了恢复,并未进行标准的操作。其中Test和Test_log时备份时数据库的文件信息。 //如果想要从备份文件中恢复,请把文件包含到项目里并且设置和DBSQL.txt一样,嵌入到程序里。最后执行删除。 //不过我想应该有办法不把文件先安装到目标机器上,而是有方法想读取DBSQL.txt文件一样,直接恢复数据库,不过确实没想到办法,失败! //网站安装好后,需要设置web.config文件,这里只涉及到连接字符串到设置,其他的可以同理修改。
#region WriteWebConfig 修改web.config的连接数据库的字符串
private bool WriteWebConfig() { System.IO.FileInfo FileInfo = new System.IO.FileInfo(this.Context.Parameters["targetdir"] + "/web.config");
if (!FileInfo.Exists) {
throw new InstallException("未找到Web.Config文件 :" + this.Context.Parameters["targetdir"] + "/web.config");
} System.Xml.XmlDocument xmlDocument = new System.Xml.XmlDocument();
xmlDocument.Load(FileInfo.FullName); bool FoundIt = false,FondReportServer=false;
foreach (System.Xml.XmlNode Node in xmlDocument["configuration"]["appSettings"]) { if (Node.Name == "add") { //根据安装设置连接字符串 //if (Node.Attributes.GetNamedItem("key").Value == "ConnectionString") //{
// Node.Attributes.GetNamedItem("value").Value = String.Format("Persist Security Info=False;Data Source={0};database={1};User ID={2};Password={3};Packet Size=4096;Pooling=true;Max Pool Size=100;Min Pool Size=1", ServerName, DBName, AdminName, AdminPwd); // FoundIt = true; //} //根据安装设置连接字符串 if (Node.Attributes.GetNamedItem("key").Value == "SqlConnectionString") {
Node.Attributes.GetNamedItem("value").Value = String.Format("Persist Security Info=False;Data Source={0};database={1};User ID={2};Password={3};Packet Size=4096;Pooling=true;Max Pool Size=100;Min Pool Size=1", ServerName, DBName, AdminName, AdminPwd); FoundIt = true; } if (Node.Attributes.GetNamedItem("key").Value == "SqlConnectionADO") {
Node.Attributes.GetNamedItem("value").Value = String.Format("Provider=SQLOLEDB.1;Password={3};Persist Security Info=False;User ID={2};Initial Catalog={1};Data Source={0}", ServerName, DBName, AdminName, AdminPwd); FoundIt = true; } //根据安装设置连接字符串 if (Node.Attributes.GetNamedItem("key").Value == @"auV8CdDyCk/67slOZw5fh1KU7XuAjzSUq7ZCaBKfXsgHpdZ7RgCJHL0TWqbjkpIG") { string str= String.Format("Persist Security Info=False;Data Source={0};database={1};User ID={2};Password={3};Packet Size=4096;Pooling=true;Max Pool Size=100;Min Pool Size=1", ServerName, DBName, AdminName, AdminPwd); Node.Attributes.GetNamedItem("value").Value = WYDAL.FangChan.StringUtils.CryptographyUtility(str);
FoundIt = true; } if (Node.Attributes.GetNamedItem("key").Value == "WebReportServer") { string [] dir=this.Context.Parameters["targetdir"].ToString().TrimEnd('\\').Split('\\'); //string dirRootString = this.Context.Parameters["targetdir"].ToString(); string dirRootName=string.Empty; if(dir!=null && dir.Length>0) { dirRootName=dir[dir.Length-1]; } //Node.Attributes.GetNamedItem("value").Value = String.Format("http://{0}/{1}/ReprotServer/YaWebReportService.asmx?WSDL",this.Context.Parameters["iis"] ,dirRootName ); Node.Attributes.GetNamedItem("value").Value = String.Format("http://{0}/WebReportServer/YaWebReportService.asmx?WSDL", this.Context.Parameters["iis"]); // MessageBox.Show(this.Context.Parameters["targetdir"]); FondReportServer = true; } } } if (!FoundIt ) { throw new InstallException("查找配置文件的数据库服务信息出错!"); }
if( !FondReportServer) { throw new InstallException("查找配置文件的报表服务器出错!"); } xmlDocument.Save(FileInfo.FullName);
return FoundIt;
} /// <summary> /// 从WEBCONFIG 中获取数据库连接字符串 /// </summary> /// <returns></returns> private string GetDBNameFromWebConfig() {
//MessageBox.Show("webconfig"); System.IO.FileInfo FileInfo = new System.IO.FileInfo(this.Context.Parameters["targetdir"] + "/web.config");
if (!FileInfo.Exists) { throw new InstallException("Missing config file :" + this.Context.Parameters["targetdir"] + "/web.config");
} System.Xml.XmlDocument xmlDocument = new System.Xml.XmlDocument();
xmlDocument.Load(FileInfo.FullName);
// bool FoundIt = false, FondReportServer = false;
foreach (System.Xml.XmlNode Node in xmlDocument["configuration"]["appSettings"]) { if (Node.Name == "add") { if (Node.Attributes.GetNamedItem("key").Value == "SqlConnectionString") {
string strNodeConnection= Node.Attributes.GetNamedItem("value").Value ;//= String.Format("Persist Security Info=False;Data Source={0};database={1};User ID={2};Password={3};Packet Size=4096;Pooling=true;Max Pool Size=100;Min Pool Size=1", ServerName, DBName, AdminName, AdminPwd); if (string.IsNullOrEmpty(strNodeConnection)) { int dataBaseIndex=strNodeConnection.IndexOf("database=")+10; int dataBaseEnd = strNodeConnection.Substring(dataBaseIndex, strNodeConnection.Length - dataBaseIndex - 1).IndexOf(";"); MessageBox.Show(strNodeConnection.Substring(dataBaseIndex, dataBaseEnd)); return strNodeConnection.Substring(dataBaseIndex,dataBaseEnd); } } } } return string.Empty;
}
#endregion
#region WriteRegistryKey 写注册表。安装部署中,直接有一个注册表编辑器,可以在那里面设置。
private void WriteRegistryKey() { // 写注册表
RegistryKey hklm = Registry.LocalMachine;
RegistryKey qzg = hklm.OpenSubKey("SOFTWARE", true);
RegistryKey F = qzg.CreateSubKey("QzgWygl");
//F.SetValue("FilePath", "kkkk"); old F.SetValue("FilePath", "QzgFxWygl");
}
#endregion
//操作IIS,建立网站等。可参考:
//用VS2005制作网页对IIS进行操作 #region Connect 连接IIS服务器 public bool Connect() { if (iis == null)
return false;
try
{
_iisServer = new DirectoryEntry("IIS://" + iis + "/W3SVC/1");
_target = iis;
_connection = new ConnectionOptions();
_scope = new ManagementScope(@"\\" + iis + @"\root\MicrosoftIISV2", _connection);
_scope.Connect();
}
catch
{
return false;
}
return IsConnected();
}
public bool IsConnected()
{
if (_target == null || _connection == null || _scope == null) return false;
return _scope.IsConnected;
}
#endregion
#region IsWebSiteExists 判断网站是否已经存在
public bool IsWebSiteExists(string serverID)
{
try
{
string siteName = "W3SVC/" + serverID;
ManagementObjectSearcher searcher = new ManagementObjectSearcher(_scope, new ObjectQuery("SELECT * FROM IIsWebServer"), null);
ManagementObjectCollection webSites = searcher.Get();
foreach (ManagementObject webSite in webSites)
{
if ((string)webSite.Properties["Name"].Value == siteName)
return true;
}
return false;
}
catch
{
return false;
}
}
#endregion
#region GetNextOpenID 获得一个新的ServerID
private int GetNextOpenID()
{
DirectoryEntry iisComputer = new DirectoryEntry("IIS://localhost/w3svc");
int nextID = 0;
foreach (DirectoryEntry iisWebServer in iisComputer.Children) {
string sname = iisWebServer.Name;
try
{
int name = int.Parse(sname);
if (name > nextID)
{
nextID = name;
}
}
catch
{
}
}
return ++nextID;
}
#endregion
#region CreateWebsite 添加网站
public string CreateWebSite(string serverID, string serverComment, string defaultVrootPath, string HostName, string IP, string Port)
{
try
{
ManagementObject oW3SVC = new ManagementObject(_scope, new ManagementPath(@"IIsWebService='W3SVC'"), null);
if (IsWebSiteExists(serverID))
{
return "Site Already Exists...";
}
ManagementBaseObject inputParameters = oW3SVC.GetMethodParameters("CreateNewSite");
ManagementBaseObject[] serverBinding = new ManagementBaseObject[1];
serverBinding[0] = CreateServerBinding(HostName, IP, Port);
inputParameters["ServerComment"] = serverComment;
inputParameters["ServerBindings"] = serverBinding;
inputParameters["PathOfRootVirtualDir"] = defaultVrootPath;
inputParameters["ServerId"] = serverID;
ManagementBaseObject outParameter = null;
outParameter = oW3SVC.InvokeMethod("CreateNewSite", inputParameters, null);
// 启动网站
string serverName = "W3SVC/" + serverID;
ManagementObject webSite = new ManagementObject(_scope, new ManagementPath(@"IIsWebServer='" + serverName + "'"), null);
webSite.InvokeMethod("Start", null);
return (string)outParameter.Properties["ReturnValue"].Value;
} catch (Exception ex) {
return ex.Message;
}
}
//创建网站管理服务 public ManagementObject CreateServerBinding(string HostName, string IP, string Port)
{
try
{
ManagementClass classBinding = new ManagementClass(_scope, new ManagementPath("ServerBinding"), null);
ManagementObject serverBinding = classBinding.CreateInstance();
serverBinding.Properties["Hostname"].Value = HostName;
serverBinding.Properties["IP"].Value = IP;
serverBinding.Properties["Port"].Value = Port;
serverBinding.Put();
return serverBinding;
}
catch
{
return null;
}
}
#endregion
//好了,准备工作已经做完,现在开始写最重要的Install方法了
//整个方法写完后如下:
#region Install 安装
///
/// 安装数据库
///
///
public override void Install(IDictionary stateSaver)
{ base.Install(stateSaver);
dir = this.Context.Parameters["targetdir"];
DBName = this.Context.Parameters["dbname"].ToString(); ServerName = this.Context.Parameters["server"].ToString();
AdminName = this.Context.Parameters["user"].ToString();
AdminPwd = this.Context.Parameters["pwd"].ToString();
iis = this.Context.Parameters["iis"].ToString();
port = this.Context.Parameters["port"].ToString(); //MessageBox.Show("Initial-"+DBName+"-"+ServerName+"-"+AdminName+"-"+AdminPwd+"-iis:"+iis+"-"+port+"-"+dir+"}");
//写入获取的安装程序中的变量,此段代码为调试用可以不添加 if(sqlConn==null) sqlConn = new SqlConnection(); this.sqlConn.ConnectionString = "Packet size=4096;User ID=" + AdminName + ";Data Source=" + ServerName + ";Password=" + AdminPwd + ";Persist Security Info=False;Integrated Security=false";
//本安装程序采用附加数据库的方式,所以去掉本段代码 // 执行SQL 安装数据库 可选择时恢复或者时直接创建 //if (!CreateDBAndTable(DBName)) //{ // MessageBox.Show("qzg-dbname"); // throw new ApplicationException("创建数据库时出现严重错误!");
//}
// 从备份数据库文件恢复数据库 if (!RestoreDB(DBName)) { MessageBox.Show("恢复数据库时出现严重错误,请与管理员联系!"); } //部署桌面快捷方式*******************#region//部署桌面快捷方式******************* string strDeskTop = System.Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory); StreamWriter sw2 = System.IO.File.CreateText(strDeskTop + "\\亿联物业管理系统.url"); stateSaver.Add("DeskQuick", strDeskTop + "\\亿联物业管理系统.url"); //保存桌面快诫方式文件绝对地址 string[] aryTh = dir.TrimEnd('\\').Split('\\'); string webdirs = aryTh[aryTh.Length-1];
string Urls = @"URL=http://"+iis+"/" + webdirs + @"/default.aspx"; sw2.WriteLine("[InternetShortcut]"); sw2.WriteLine(Urls); sw2.WriteLine("modified=228928983"); sw2.WriteLine("IconIndex=0"); sw2.WriteLine("IconFile=" + dir + "http://www.cnblogs.com/bingyun84/admin/file://wygl.ico/"); sw2.Flush(); sw2.Close(); //#endregio ////部署开始菜单 ***************#region 部署开始菜单 *************** string startMenue=Environment.GetFolderPath(Environment.SpecialFolder.StartMenu); if(File.Exists(startMenue+"\\亿联物业管理系统.url")) { if(MessageBox.Show("开始菜单已经存在,是否有覆盖它?","安装开始菜单",MessageBoxButtons.YesNo,MessageBoxIcon.Question, MessageBoxDefaultButton.Button1) == DialogResult.Yes) {
File.Copy(strDeskTop + "\\亿联物业管理系统.url", startMenue + "\\亿联物业管理系统.url", true); } else { throw new InstallException("开始菜单已经存在,安装取消"); } } else { File.Copy(strDeskTop + "\\亿联物业管理系统.url", startMenue + "\\亿联物业管理系统.url", false); } stateSaver.Add("StartMenueFile",startMenue+"\\亿联物业管理系统.url"); //保存开始菜单文件绝对地址 // 添加网站 Connect(); // 下面的信息为测试,可以自己编写文本框来接收用户输入信息
string serverID = "5555";
string serverComment = "QZG";
string defaultVrootPath = this.Context.Parameters["targetdir"];
if (defaultVrootPath.EndsWith(@"\")) { defaultVrootPath = defaultVrootPath.Substring(0, defaultVrootPath.Length-1);
}
string HostName = "";
string IP = "";
string Port = port;
string sReturn = CreateWebSite(serverID, serverComment, defaultVrootPath, HostName, IP, Port);
// 修改web.config if (!WriteWebConfig()) {
//throw new ApplicationException("设置数据库连接字符串时出现错误"); MessageBox.Show("设置数据库连接字符串时出现错误");
} // 写注册表 WriteRegistryKey(); }
#endregion
//删除时的方法。在本文中未详细操作,比如删除站点,删除数据库等。如果需要,请你自己补足
#region Uninstall 删除
//QZG private bool DeleteDatabase() { try { DBName = this.Context.Parameters["dbname"].ToString(); if (string.IsNullOrEmpty(DBName)) { DBName= GetDBNameFromWebConfig(); } if (string.IsNullOrEmpty(DBName)) return false; ExecuteSql("master", "USE MASTER IF EXISTS (SELECT NAME FROM SYSDATABASES WHERE NAME='" + DBName + "') DROP DATABASE "+DBName+" "); return true;
} catch { return false; } } public override void Uninstall(IDictionary savedState) { //MessageBox.Show("卸载过程...."); if (savedState == null) throw new ApplicationException("卸载数据库失败,未能卸载![qzg]"); else { base.Uninstall(savedState); //删除快捷键,删除开始菜单#region 删除快捷键,删除开始菜单 //删除快捷键 if(File.Exists(savedState["DeskQuick"].ToString())) { File.Delete(savedState["DeskQuick"].ToString()); } //删除开始菜单 if(File.Exists(savedState["StartMenueFile"].ToString())) { File.Delete(savedState["StartMenueFile"].ToString()); } //#endregion if (!DeleteDatabase()) { MessageBox.Show("卸载数据库错误,请手动删除物业管理系统的数据库!"); //throw new ApplicationException("卸载过程中发生错误,未能卸载!"); } }
} //END
#endregion
//end #endregion }
|
请发表评论