VS2005 制作Web安装程序

使用VS2005制作安装包
1.在“新建项目”对话框的左侧树状图中选择“Other Project Types”->“Setup and Deployment”节点,在右侧选择“Web
Setup Project”。

2.在Solution Explorer中在Solution上点右键,选择“Add”->“Existing Web
Site”,将存放编译好的Web网站的文件夹加入Solution中。

如果添加使用aspnet_compiler编译好的网站,有可能会出现下面的提示框,点击“是”就行。
3.再添加一个新的“Class Library”,名称“CreateDB”,用以创建数据库的操作。
删除默认生成的“class1.cs”,在这个项目上点右键,选择“Add”->“New Item”,在弹出的对话框中选择“Installer
Class”,点击OK。

在类中添加如下代码:
private void ExecuteSql(string connectionString, string databaseName, string
sql)
{
SqlConnection sqlConnection = new SqlConnection(connectionString);
SqlCommand sqlCommand = new SqlCommand(sql, sqlConnection);
try
{
sqlCommand.Connection.Open();
sqlCommand.Connection.ChangeDatabase(databaseName);
sqlCommand.ExecuteNonQuery();
}
catch (Exception exception)
{
throw exception;
}
finally
{
sqlCommand.Connection.Close();
}
}

public override void Install(System.Collections.IDictionary stateSaver)
{
string server = this.Context.Parameters[“server”];
string database = this.Context.Parameters[“dbname”];
string user = this.Context.Parameters[“user”];
string password = this.Context.Parameters[“pwd”];
string targetDir = this.Context.Parameters[“targetdir”];

try
{
string connectionString = String.Format(“data source={0};user
id={1};password={2};persist security info=false;packet size=4096”,
server, user, password);

//create db
ExecuteSql(connectionString, “master”, "CREATE DATABASE " + database);

//set user
string setUserString = “sp_addlogin ‘PrinteryERP’, ‘PrinteryERP’,
‘PrinteryERP’”;
string setAccessString = “sp_grantdbaccess ‘PrinteryERP’”;
string setRole = “sp_addrolemember ‘db_owner’, ‘PrinteryERP’”;

//create new user login
try
{
ExecuteSql(connectionString, “master”, setUserString);
}
catch { }

//set default database
try
{
ExecuteSql(connectionString, “PrinteryERP”, setAccessString);
}
catch { }

//set read role
try
{
ExecuteSql(connectionString, “PrinteryERP”, setRole);
}
catch { }

//create table,store produce…
Process osqlProcess = new Process();
osqlProcess.StartInfo.FileName = targetDir + “osql.exe”;
osqlProcess.StartInfo.Arguments = String.Format(" -U {0} -P {1} -S {2} -d {3}
-i {4}createdb.sql",
user, password, server, database, targetDir);
osqlProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
osqlProcess.Start();
osqlProcess.WaitForExit();
osqlProcess.Close();

//add data
osqlProcess.StartInfo.Arguments = String.Format(" -U {0} -P {1} -S {2} -d {3}
-i {4}insertdata.sql",
user, password, server, database, targetDir);
osqlProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
osqlProcess.Start();
osqlProcess.WaitForExit();
osqlProcess.Close();
}
catch (Exception exception)
{
throw exception;
}

try
{
string configFile = targetDir + “/Web.config”;
if (!File.Exists(configFile))
{
throw new InstallException(“没有找到配置文件。”);
}

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(configFile);

GC.Collect();
File.Delete(configFile);
GC.Collect();

foreach (XmlNode xmlNode in
xmlDoc[“configuration”][“connectionStrings”].ChildNodes)
{
if (xmlNode.Name == “add”)
{
if (xmlNode.Attributes[“name”].Value == “DBConnection”)
{
xmlNode.Attributes[“connectionString”].Value = String.Format(“Data
Source={0};Initial Catalog={1};Persist Security Info=True;User
ID=PrinteryERP;Password=PrinteryERP”,
server, database);
}
if (xmlNode.Attributes[“name”].Value == “UserManageServicesConnection”)
{
xmlNode.Attributes[“connectionString”].Value = String.Format(“Data
Source={0};Initial Catalog={1};Persist Security Info=True;User
ID=PrinteryERP;Password=PrinteryERP”,
server, database);
}
}
}
xmlDoc.Save(configFile);
}
catch (Exception exception)
{
throw exception;
}
}
4.在“Web Setup Project”项目上点右键,选择“Add”->“Project
Output”,选择Project“CreateDB”,选择“Primary Output”,点击OK。重复上述动作,将选择刚才添加的Web
Site,选择“Content Files”,点击OK。
5.在“Web Setup Project”项目上点右键,选择“Add”->“File”,将创建数据库表、存储过程和视图的脚本createdb.sql加入。
重复,将向数据表中添加基础数据的脚本insertdata.sql加入。重复,将程序osql.exe加入。
6.在“Web Setup Project”项目上点右键,选择“Add”->“Merge Module”,在弹出的对话框中选择“VC_User_CRT71_
RTL_X86_—.msm”,点击OK。添加这个VC运行库是因为在一台干净的机器上测试的时候发现osql.exe这个程序需要这个库。
7.在“Web Setup Project”项目上点右键,选择“Properties”,在弹出的对话框中可以设置一些安装程序的属性。点击按钮“Prerequ
isites”,在弹出的对话框中选中“.NET Framework 2.0”和“Windows Installer 3.1”,选中“Download
prerequisites from the same location as my application”。这样就可以把这些组件和应用程序打包在一起,安
装的时候自动检测并安装了。如果需要部署的计算机如果没有打过最新的补丁的话,是没有“Windows Installer
3.1”的,如果没有这个组件,“.NET Framework 2.0”是不能安装的。

8.在“Web Setup Project”项目上点右键,选择“View”->“Custom
Actions”,在出现的树状图的节点“Install”上点右键,选择“Add Custom Actions”。在弹出的对话框中“Look
in”中选择“Web Application Folders”,在下面选择“Primary output from CreateDB
(Active)”,点击OK。
9.在“Web Setup Project”项目上点右键,选择“View”->“User
Interface”,在出现的树状图节点“Install”的子节点“Start”上点击右键,选择“Add
Dialog”,在弹出的对话框中选择“TextBoxes(A)”。

在新添加的节点“TextBoxes (A)”上点击右键,选择“Properites Window”,依次设置Edit*Property属性为“CUSTOMT
EXTA1”,“CUSTOMTEXTA2”,“CUSTOMTEXTA3”和“CUSTOMTEXTA4”。

10.在刚刚建立的“Primary output from CreateDB (Active)”节点上点右键,选择“Properties
Window”,设置“CustomActionData”属性为“/dbname=[CUSTOMTEXTA1] /server=[CUSTOMTEXTA2]
/user=[CUSTOMTEXTA3] /pwd=[CUSTOMTEXTA4] /targetdir=“[TARGETDIR]/””。

接下来对整个解决方案进行编译,会在输出目录下生成两个文件夹和两个文件。
两个文件夹中分别包含了.NET Framework 2.0和Windows
Installer3.1的安装包。另外的两个文件分别是(项目名称).msi和setup.exe。如果要进行安装,请执行setup.exe。
如果你想在“干净”的机器上成功安装和使用水晶报表,请按照下列步骤:

1)新建“安装和部署项目”–>“安装向导”
(2)选择项目类型(这里选“创建用于windows应用程序的安装程序”)–>下一步
(3)选择要包含的文件:要部署使用 Crystal Reports for Visual Studio .NET 2003
的程序,需要添加合并模块(在解决方案资源管理器中tree的顶端节点右键–>添加).
Crystal_Database_Access2003.msm
Crystal_Database_Access2003_enu.msm
Crystal_Managed2003.msm
Crystal_regwiz2003.msm
VC_User_CRT71_RTL_X86_—.msm
VC_User_STL71_RTL_X86_—.msm
你可以 ‘C:/Program Files/Common Files/Merge Modules’ 文件夹下找到替换的合并模块。
(4)打开解决方案–>右键点击Crystal_regwiz2003.msm 的属性,在“MergeMouduleProperties”里的“License
Key”填入:**************************(这个是你生成Crystal Report是用到的注册号的密码!)
(5)生成解决方案
如果没有第四步,会产生在执行打印报表时提示keycodev2.dll或者无效密码的错误。
以上的步骤,如果你的“干净”的机器上装有水晶报表,那么到这里完全就可以了。
如果你不希望在“干净”的机器上装水晶报表,继续以下的步骤:
在“添加项目输出组”中,选择“主输出”,然后单击“确定”。
将自动添加所有依赖项,如 dotnetfxredist_x86_enu.msm和dotnetcrystalreports.msm。
2.需要将dotnetcrystalreports.msm排除在项目之外,在解决方案资源管理器中右击这个模块的右键,选择“排除”。
3.在解决方案资源管理器中,右击安装项目,指向“添加”,然后单击“合并模块”。
4.在“添加模块”对话框中,选择下列要添加到安装项目的合并模块,然后单击“打开”:
reportengine.msm,
crnetruntime.msm
license.msm
mapping.msm (可选,当在报表中使用了geographic maps时)
5.在解决方案资源管理器中,右击 license.msm 文件,然后选择“属性”。
6.在“属性”窗口中,展开 MergeModuleProperties,然后在“许可证密钥”属性框中输入一个有效的许可证密钥。
注意 :  每当部署 Crystal Reports 应用程序时,必须提供许可证密钥。
7.从“生成”菜单中,选择“生成解决方案”以生成应用程序
如果以上步骤没有的化,会提示“load crpe32.dll failed”的错误。
用到的模块下载地址: [ http://support.businessobjects.com/communityCS/FilesAndUpdates/cr
9netmergemodules_chs.zip.asp ](http://support.businessobjects.com/communityCS
/FilesAndUpdates/cr9netmergemodules_chs.zip.asp)
[ http://support.businessobjects.com/communityCS/FilesAndUpdates/cr9netredist_
chs.zip.asp ](http://support.businessobjects.com/communityCS/FilesAndUpdates/
cr9netredist_chs.zip.asp)
[ http://support.businessobjects.com/communityCS/FilesAndUpdates/cr9rdcmergemo
dules_chs.zip.asp ](http://support.businessobjects.com/communityCS/FilesAndUp
dates/cr9rdcmergemodules_chs.zip.asp)
如果你的机器上装的是windows 98,不继续以下的步骤会产生"Load Report Failed" (CRQE.dll)的错误。
报表在部分Win98的客户端可以载入,在部分Win98的客户端载入报表时却提示"Load Report Failed"是因为水晶报表运行时所需的
CRQE.dll 在客户端的系统注册不正确,而原因又是ATL.dll 的版本不对(Windows 98/ME下的正确版本号应为3.0.8449)。
解决办法有两条:
1.在客户端安装 IE6.0,难怪有的客户端运行正常。
2.将 ATL.msm 模块添加到安装工程,ATL.msm 是 Visual Studio installer 1.1 的一部分,可以去微软的网站
http://msdn.microsoft.com/vstudio/downloads/tools/vsi11/download.aspx
下载,
添加办法同上。
至此,可以说打包基本完成。不过还要注意:
如果你用的是水晶报表的推模式,一般不用设置登陆信息,但是要这样写:obj.SetDataSource(this.ds.Tables[“tablename”]
);如果你写成了obj.SetDataSource(this.ds)就会有登陆框的。
如果你用的是水晶报表的拉模式,你就一定要写上登陆信息:
crReportDocument = new OracleReport();
//Set the crConnectionInfo with the current values stored in the report
crConnectionInfo =
crReportDocument.Database.Tables[0].LogOnInfo.ConnectionInfo;
/
Populate the ConnectionInfo Objects Properties with the appropriate values
for
the ServerName, User ID, Password and DatabaseName. However, since Oracle
works on Schemas, Crystal Reports does not recognize or store a DatabaseName.
Therefore, the DatabaseName property must be set to a BLANK string. */
crConnectionInfo.DatabaseName = “”;
crConnectionInfo.ServerName = “Your Server Name”;
crConnectionInfo.UserID = “Your User ID”;
crConnectionInfo.Password = “Your Password”;
//Set the CrDatabase Object to the Report’s Database
crDatabase = crReportDocument.Database;
//Set the CrTables object to the Tables collection of the Report’s dDtabase
crTables = crDatabase.Tables;
//Loop through each Table object in the Tables collection and apply the logon
info
//specified ealier. Note this sample only has one table so the loop will only
execute once
foreach (Table crTable in crTables)
{
crTableLogOnInfo = crTable.LogOnInfo;
crTableLogOnInfo.ConnectionInfo = crConnectionInfo;
crTable.ApplyLogOnInfo (crTableLogOnInfo);

// if you wish to change the schema name as well, you will need to set
Location property as follows:
// crTable.Location = “.” + crTable.Name;
}
//Set the ReportSource of the CrystalReportViewer to the strongly typed Report
included in the project
crystalReportViewer1.ReportSource = crReportDocument;
还有一点要注意:
如果你用到了子报表,一定要处理:
//Go through each sections in the main report and identify the subreport by
name
crSections = crReportDocument.ReportDefinition.Sections;

foreach(Section crSection in crSections)
{
crReportObjects = crSection.ReportObjects;
//loop through all the report objects to find all the subreports
foreach(ReportObject crReportObject in crReportObjects)
{
if (crReportObject.Kind == ReportObjectKind.SubreportObject)
{
//you will need to typecast the reportobject to a subreport
//object once you find it
crSubreportObject = (SubreportObject)crReportObject;

//open the subreport object
crSubReportDoc =
crSubreportObject.OpenSubreport(crSubreportObject.SubreportName);
//Once the correct subreport has been located pass it the
//appropriate dataset
if(crSubReportDoc.Name == “FirstSub”)
{
//crSubReportDoc.Database.Tables[0].SetDataSource(ds);
crSubReportDoc.SetDataSource(ds);
}
}
}
}
crystalReportViewer1.ReportSource = crReportDocument;

同样crSubReportDoc.SetDataSource(ds);改为:crSubReportDoc.SetDataSource(ds.Tables["
tablename"]);


按前面的方法打包后,运行生成的安装程序出现以下错误提示:
在建立与服务器连接时出错。在连接到SQL Server 2005 时,在默认的设置下SQL
Server不允许进行远程连接可能会导致此失败。(provider:命名管道提供程序,error:40 - 无法打开SQL Server的连接)

是什么原因?

在“Web Setup Project”项目上点右键,选择“Properties”,在弹出的对话框中可以设置一些安装程序的属性。点击按钮“Prerequis
ites”,在弹出的对话框中有“Crystal Reports for .Net Framework2.0”和“SQL Server 2005
Express Edittion”,选上这两个是不是就不用另外添加水晶报表和MSDE了呢?


一在现有的WEB项目里新建一个安装部署项目,安装项目
二将需要 打包的文件按照特定的目录打包
如"项目名.dll"文件放到debug目录下
其他文件同样按照相应的目录放置,不要乱了
三/如果是发布程序则,把页面文件的aspx后缀的文件打包即可
如果只是打包源程序,则建议添加所有文件
四/最后生成,
五/运行新生成的,安装文件进行安装测试,看看是不是漏掉了什么文件