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
}