这几天在打包一个web项目,在制作安装包过程中遇到一些问题,写下来和大家共同探讨:

1.我需要在安装时对数据库进行操作,如何进行?
在MSDN里面,有专门的一个演练讲到操作数据库,地址是ms-help://MS.MSDNQTR.2003FEB.2052/vsintro7/html/vxwlkwalkthroughusingcustomactiontocreatedatabaseduringinstallation.htm,你可以在你的VS.NET配套的MSDN地址栏中输入刚才的地址,就是安装期间使用自定义操作创建数据库的演练.
呵呵,当然,如果一切都这么简单的话,我的这个问题就不用写了.
如果你的Sql语句很简单,只是创建数据库的话,看MSDN的演练估计可以解决问题,但是如果涉及到存储过程的话,就要关注下面的步骤了.
在我们自己的安装程序类中,都是利用SqlCommand的ExecuteNonQuery方法来执行Sql语句,从而达到操作数据库的目的.Sql语句从哪里来?对于存储过程,我相信大部分人都是从数据库里面导出的脚本吧.
如果图省事,将所有的存储过程导在一个脚本里面的话,自定义操作在安装的时候会出错,提示说Create 语句应该放在第一行.这时因为SqlCommand不支持在一个Sql语句里面创建多个存储过程,必须将每一个存储过程的脚本都做为一个文件签入到项目输出里面去.(嵌入方法还请参见MSDN的那个演练)
但是,如果存储过程有几十个的话,难道要将所有的存储过程的名称都硬编码进安装程序类里面?
我的思路是将所有的存储过程编上序号,文件名称改为形如01.sql这样的名称,在一个循环里面将所有的脚本都执行一遍,循环的条件就是文件的最大序号,用一个静态变量来保存就可以了.
还要注意的地方就是:在你采用了命名空间的时候,要注意GetManifestResourceStream方法的调用,如果参数不正确,就无法得到嵌入的脚本,使用来读取的Stream是null.
另外的解决方案是用生成一个cmd脚本,在shell里面直接调用,不过这样会把sql暴露给用户,但好处是简单.

2.如何根据用户的数据修改web.config文件以配置数据库连接字符串?
这个问题倒是不难,请参考这个演练ms-help://MS.MSDNQTR.2003FEB.2052/vsintro7/html/vxwlkwalkthroughpassingdatatocustomaction.htm,不过,在编码的时候,我发现使用C#下面的语句会无法通过编译.
XmlDocument.Item("configuration").Item("appSettings"),提示说没有这样的属性,不知道使用VB.NET会不会出错,我猜想可能是FrameWork1.0中的语法吧,需要手工修改一下代码,不用这种方法来设置Web.config文件.
需要注意的是,web.config文件一般是在web文件夹下面,而用GetExecutingAssembly方法得到的配件是在web\bin目录下面,读取web.config文件时需要注意哦

3.怎样在安装结束后打开一个web页面,比如Readme.html或者连接到公司网站?
我使用C#在安装程序类中使用Process.Start("http://www.mycompany.com")的时候,会报"在活动的激活上下文中没有找到任何查找密钥"的错误,而用Process.Start("IExplore.exe","http://www.mycompany.com")就不会出错,正常地启用IE打开了想要的页面,很怪的问题哦.前者使用用户默认的浏览器打开web页面,会给用户更好的使用体验,但是为什么会报错,还没有搞清楚这个问题.

4.想使用安装地址的port属性?
MSDN中说"可以使用 [TARGETVDIR] 和 [PORT] 属性在自定义操作中检索输入到这些字段中的值。该对话框只适用于 Web 安装项目",但是我在安装程序类中只能得到TARGETVDIR,得不到PORT的值.不知道是不是还有其他办法?原文在这里:ms-help://MS.MSDNQTR.2003FEB.2052/vsintro7/html/vxconInstallationAddressUserInterfaceDialogBox.htm
这样的就会造成一个问题:如果用户更改端口为8001,同时我们安装结束后又要打开这个名为"mydir"的虚拟目录,那么用"http://localhost/mydir"打开的话,肯定会报错.只能让用户改成"http://localhost:8001/mydir"才行.
(今天将这个问题反馈给微软动力营了,看看他们有没有什么解决方案)

5.想创建一个指向虚拟目录的快捷方式?
如果想在安装完成后在桌面上放一个指向地址"http://localhost:8002/mydir"的快捷方式,用户双击后就会打开默认的web浏览器打开这个虚拟目录,除了在安装程序类中自己用笨办法创建以外好像没有一个简洁的解决方案.
在自定义操作的时候,用/port=[TARGETPORT]来取得用户录入的端口,而不是MSDN上说的[PORT],这样在自定义程序类里面就可以取得port参数的值了
下面是一些补充:
如果你选择嵌入SQL脚本,要注意你的编码格式,如果脚本里面有中文,就要先用VS.NET或者其他工具把它的编码改成UTF8,因为从SQLSERVER导出的脚本默认是unicode,如果不转换,中文就会成乱码了
我就是被这个问题搞得半死,查了好久才知道.net中的StearmReader默认的编码格式就是UTF8