您的位置:首页 > 其它

(转)制作web安装程序

2008-09-28 16:38 281 查看

出处:http://www/i-blog.cn/u/chenli/archives/2006/8.html

本文参考http://blog.csdn.net/libra1983/archive/2006/09/25/1274933.aspx

1、1. 打开VS2005,创建一个新的工程,选择:其他项目类型->安装和部署->安装项目。名称为Setup,确定。

2、2. 在文件系统中加入要安装的所有文件和文件夹。可在应用程序文件夹节点上单击鼠标右键,选择添加文件或文件夹。这里注意,如果要添加的文件夹中还有子文件夹这样添加会有点麻烦。可以先选择应用程序文件夹,在资源管理器中选择所有要安装的文件和文件夹,直接将选择的文件和文件夹拖放到VS2005的应用程序文件夹中(VS2005此时中间的部分)。

3、 3. 添加一个新项目,这里选择Visual C#的类库。用来在安装过程中添加MS Sql Server数据库,以及在IIS中创建网站。命名为SetupClassLibrary,确定。

4、4. 在安装数据库时,会执行脚本。在SetupClassLibrary项目中加入一个名为DBSQL.txt的文件,将要执行的脚本放在里面。将该文件的属性中生成操作属性设为:嵌入的资源。注意该脚本只是创建表和存储过程等,不是创建数据库的,而且不要含有“GO”命令,如果有“GO”命令可以用替换的方法把“GO”换成空白。

5、5. 删除SetupClassLibrary中自动生成的Class1.cs。在SetupClassLibrary中添加新的项。选择安装程序类。命名为SetupInstaller.cs,确定。

6、6. 在SetupInstaller.cs的代码试图中可以看到SetupInstaller类继承自Installer。这里要重写Installer的几个方法,来处理安装过程中的行为。

7、7. 重写Installer的Install方法。该方法在安装时执行。还可以重写Commit(完成)、Rollback(回滚)、Uninstall(卸载)。SetupInstaller.cs中所有的代码在附录中。可以直接复制过来。需要添加的引用有:System.DirectoryServices。然后编译这个项目。

public override void Install(IDictionary stateSaver)

{

base.Install(stateSaver);

dir = this.Context.Parameters["TARGETDIR"];

DBName = this.Context.Parameters["DBNAME"].ToString();

ServerName = this.Context.Parameters["DBSERVERNAME"].ToString();

AdminName = this.Context.Parameters["USERNAME"].ToString();

AdminPwd = this.Context.Parameters["PASSWORD"].ToString();

iis = this.Context.Parameters["IISSERVER"].ToString();

port = this.Context.Parameters["PORT"].ToString();

//写入获取的安装程序中的变量,此段代码为调试用可以不添加

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))

{

throw new ApplicationException("创建数据库时出现严重错误!");

}

// 从备份数据库文件恢复数据库

/*

if (!RestoreDB(DBName))

{

throw new ApplicationException("恢复数据库时出现严重错误!");

}

*/

// 添加网站

Connect();

//string serverID = GetNextOpenID().ToString();

//string serverComment = websitenName;

// 下面的信息为测试,可以自己编写文本框来接收用户输入信息

string serverID = "5555";

string serverComment = "PortalSite";

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("设置数据库连接字符串时出现错误");

//}

// 写注册表

//WriteRegistryKey();

}

8、8. 在安装项目Setup中打开用户界面编辑器,这里要在安装向导中加入设置数据库以及IIS的地方。在启动节点单击鼠标右键,添加对话框,把文本框(A)和文本框(B)都添加进来。把他们拖到确认安装的上面。

9、9. 设置文本框(A)的属性。BodyText:输入新网站的设置;Edit1Label:服务器;Edit1Property:IISSERVER;Edit1:localhost;Edit2Label:端口;Edit2Property:PORT;Edit2:9998;Edit3Visible:False;Edit4Visible:False;

10. 设置文本框(B)的属性。BodyText:数据库设置;Edit1Label:数据库服务器;Edit1Property:DBSERVERNAME;Edit1:localhost;Edit2Label:数据库名称;Edit2Property:DBNAME;Edit2:Portal;Edit1Labe3:登录帐号;Edit3Property:USERNAME; Edit4Label:密码;Edit4Property:PASSWORD;

11 加入自定义的操作。在安装项目Setup中打开自定义操作编辑器。在安装节点单击鼠标右键,添加自定义操作。双击应用程序文件夹,点击添加程序集按钮,选择“浏览”页,找到并选择SetupClassLibrary项目生成的程序集SetupClassLibrary.dll,确定。安装节点下多了一个SetupClassLibrary.dll节点,在该节点单击鼠标右键,选择属性,设置CustomActionData属性为/DBNAME=[DBNAME] /DBSERVERNAME=[DBSERVERNAME] /USERNAME=[USERNAME] /PASSWORD=[PASSWORD] /IISSERVER=[IISSERVER] /PORT=[PORT] /TARGETDIR="[TARGETDIR]\"

12. 先重新生成SetupClassLibrary项目,然后生成Setup项目。生成完毕后在Setup项目的Debug目录下可以找到Setup.msi文件和setup.exe文件。现在可以执行安装程序看看效果了。也可以在解决方案管理器的Setup项目节点上单击鼠标右键,选择安装。

附录:SetupInstaller.cs的所有代码

using System.DirectoryServices;
using System.Management;
using System.Collections;
using System.Data;
using System;
using System.Reflection;
using System.IO;
using System.Configuration.Install;
using Microsoft.Win32;
using System.ComponentModel;

namespace SetupClassLibrary
{
[RunInstaller(true)]
public partial class SetupInstaller : Installer
{
public SetupInstaller()
{
InitializeComponent();
}

private System.Data.SqlClient.SqlConnection sqlConn=new System.Data.SqlClient.SqlConnection();

private System.Data.SqlClient.SqlCommand Command;

private string DBName;

private string ServerName;

private string AdminName;

private string AdminPwd;

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;

#region ConnectDatabase 连接数据库

private bool ConnectDatabase()
{

if (Command.Connection.State != ConnectionState.Open)
{

try
{
Command.Connection.Open();

}

catch (Exception e)
{
return false;

}

}

return true;

}

#endregion

#region GetSql 从文件中读取SQL,在读取包含SQL脚本的文件时需要用到,参考自MSDN

private string GetSql(string Name)
{

try
{

Assembly Asm = Assembly.GetExecutingAssembly();

Stream strm = Asm.GetManifestResourceStream(Asm.GetName().Name + "." + Name);

StreamReader reader = new StreamReader(strm);

return reader.ReadToEnd();

}

catch (Exception getException)
{

throw new ApplicationException(getException.Message);

}

}

#endregion

#region ExecuteSql 执行SQL语句,参考自MSDN

private void ExecuteSql(string DataBaseName, string sqlstring)
{

Command = new System.Data.SqlClient.SqlCommand(sqlstring, sqlConn);

if (ConnectDatabase())
{

try
{

Command.Connection.ChangeDatabase(DataBaseName);

Command.ExecuteNonQuery();

}
finally
{

Command.Connection.Close();

}

}

}

#endregion

#region CreateDBAndTable 创建数据库及数据库表,参考自MSDN

protected bool CreateDBAndTable(string DBName)
{

bool Restult = false;

//try
//{

ExecuteSql("master", "USE MASTER IF EXISTS (SELECT NAME FROM SYSDATABASES WHERE NAME='" + DBName + "') DROP DATABASE " + DBName);

ExecuteSql("master", "CREATE DATABASE " + DBName);

ExecuteSql(DBName, GetSql("DBSQL.txt"));

Restult = true;

//}
//catch
//{

//}

return Restult;

}

#endregion

#region RestoreDB 从备份文件恢复数据库及数据库表

///

/// 从备份文件恢复数据库及数据库表

///

///数据库名

///配件中数据库脚本资源的名称

///

protected bool RestoreDB(string DBName)
{

dir = this.Context.Parameters["targetdir"];

bool Restult = false;

string MSQL = "RESTORE DATABASE " + DBName +

" FROM DISK = '" + dir + @"data.bak' " +

" WITH MOVE 'Test' TO '" + @"c:\" + DBName + ".mdf', " +

" MOVE 'Test_log' TO '" + @"c:\" + DBName + ".ldf' ";

try
{

ExecuteSql("master", "USE MASTER IF EXISTS (SELECT NAME FROM SYSDATABASES WHERE NAME='" + DBName + "') DROP DATABASE " + DBName);

ExecuteSql("master", MSQL);

Restult = true;

}

finally
{

// 删除备份文件

try
{

File.Delete(dir + @"data.bak");

}

catch
{

}

}

return Restult;

}

#endregion

#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("Missing config file :" + this.Context.Parameters["targetdir"] + "/web.config");

}

System.Xml.XmlDocument xmlDocument = new System.Xml.XmlDocument();

xmlLoad(FileInfo.FullName);

bool FoundIt = false;

foreach (System.Xml.XmlNode Node in xmlDocument["configuration"]["appSettings"])
{

if (Node.Name == "add")
{

if (Node.Attributes.GetNamedItem("key"). == "ConnectionString")
{

Node.Attributes.GetNamedItem(""). = 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 (!FoundIt)
{

throw new InstallException("Error when writing the config web.config");

}

xmlSave(FileInfo.FullName);

return FoundIt;

}

#endregion

#region WriteRegistryKey 写注册表。安装部署中,直接有一个注册表编辑器,可以在那里面设置。

private void WriteRegistryKey()
{

// 写注册表

RegistryKey hklm = Registry.LocalMachine;

RegistryKey cqfeng = hklm.OpenSubKey("SOFTWARE", true);

RegistryKey F = cqfeng.CreateSubKey("cqfeng");

F.Set("FilePath", "kkkk");

}

#endregion

#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"]. == 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["Return"].;

}

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"]. = HostName;

serverBinding.Properties["IP"]. = IP;

serverBinding.Properties["Port"]. = Port;

serverBinding.Put();

return serverBinding;

}

catch
{

return null;

}

}

#endregion

#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["DBSERVERNAME"].ToString();

AdminName = this.Context.Parameters["USERNAME"].ToString();

AdminPwd = this.Context.Parameters["PASSWORD"].ToString();

iis = this.Context.Parameters["IISSERVER"].ToString(); ;

port = this.Context.Parameters["PORT"].ToString();

//写入获取的安装程序中的变量,此段代码为调试用可以不添加

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))
{
throw new ApplicationException("创建数据库时出现严重错误!");
}

// 从备份数据库文件恢复数据库

/*

if (!RestoreDB(DBName))

{

throw new ApplicationException("恢复数据库时出现严重错误!");

}

*/

// 添加网站

Connect();

//string serverID = GetNextOpenID().ToString();

//string serverComment = websitenName;

// 下面的信息为测试,可以自己编写文本框来接收用户输入信息

string serverID = "5555";

string serverComment = "PortalSite";

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("设置数据库连接字符串时出现错误");

//}

// 写注册表

//WriteRegistryKey();
}

#endregion

#region Uninstall 删除

public override void Uninstall(IDictionary savedState)
{

if (savedState == null)
{

throw new ApplicationException("未能卸载!");

}

else
{

base.Uninstall(savedState);

}

}

#endregion
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: