Vs 2010(05,08)自带的制作安装程序工具很方便,对于一些简单的只需要安装的小程序来说,我们很方便的就能制作出来一个安装包,但是对于一些需要在安装过程进行输入或者进行数据库安装和附加的,就需要我们重写安装类了,我也是做过好多次,对这些需要自定义的地安装程序也是做一次上网查一次,这次想把制作过程,以及以及遇到的问题写下来,供自己以后查询方便,也可以和大家一起探讨;
准备:准备一个文件夹,将我们生成的程序以及用到的图片,文件都放到这个文件夹内,如果我们需要数据库,我们可以提前备份一格DB.dat的文件放到该文件夹下,
打开vs2010(08,05)新建->项目->其它项目类型-〉安装和部署-〉Visual StudioInstaller 下面我们可以选择安装项目和安装向导,
至于安装向导我就不再多说了,大家选择后可以一步一步地将文件添加上,将该设置的设置好,下面我直接选择安装项目,填写上项目名称,点击确定,创建好项目;
然后我就右键文件系统中应用程序文件夹-添加-文件夹,将我们文件中有的文件夹都先创建好,然后通过右键-添加-文件,选择到我们提前准备好的文件夹,将里面的所有文件,安装文件夹的不同都添加到应用程序文件夹内;
然后,鼠标右键该项目运行的exe文件,创建快捷方式,将快捷方式改成我们需要的名字后剪切到用户程序菜单和用户程序桌面;
分别鼠标右键用户程序菜单和用户桌面里的快捷方式-属性;
点击icon后的图标处,选择我们提前准备好的程序的ico文件即可;
然后,鼠标右键应用程序文件夹-属性在红框处设置安装默认路径;
然后鼠标放到解决方案资源管理器下面的项目名称上,点击属性菜单。修改相应的产品信息,用户信息等;
然后鼠标选中项目-右键-属性-系统必备,
选中系统安装必备的组件-点击确定;
点击用户界面编辑器
在安装-启动中右键-添加对话框,以此添加许可协议和文本框
然后选中许可协议,点击属性;在LicensFile处选中我们提前准备好的.rtf协议文件
选中文本框-右键属性 设置我们文本框内需要显示的内容
默认有四个文本框,我们把不需要的可以把visible设置成false,需要的设置成true。在label处设置我们要显示的标题,在Property处选中我们访问时用到的名称,Value处设置我们默认文本框内显示的内容;
下面就是我们一些自定义操作;首先我们要获取到输入框内输入的内容,我们首先需要在解决方案下创建一个新的类库,解决方案-右键-添加项目-VisualBasic-类库 输入类库名称(C#也行,不过C#重写安装类时老是出问题,所有就用VB了)点击确定,
然后再新建项目中,将自带的class1.vb删除掉,右键-添加-常规-安装程序类 输入类的名字,点击确定即可
然后生成类库,右键我们我们的安装程序,右键-项目输出
在项目后面选中我们刚才添加的类库,选中主输出 点击确定;然后点击自定义操作编辑器
右键单击安装-添加自定义操作-选中主输出来自*******-点击确定
然后鼠标选中安装下面的主输出来自InstalClientVB(活动)-属性
在CustomActionData修改传值方式如:/epqymc=[EPQYMC]/epqyip=[EPQYIP] /targetdir="[TARGETDIR]"
然后打开我们的安装程序类;
单击此处切换到代码试图
依次重写安装方法
Public Overrides SubInstall(ByVal stateSaverAs System.Collections.IDictionary)
MyBase.Install(stateSaver)
mySetAppConfig(Me.Context.Parameters.Item("epqymc"),Me.Context.Parameters.Item("epqyip"))
'附加数据库
'If NotInstallDB() Then
'失败,反安装
'Me.Uninstall(stateSaver)
'Exit Sub
'End If
'DeleteFile(String.Format("{0}db.dat",Me.Context.Parameters.Item("targetdir")))
End Sub
Public Overrides Sub Uninstall(ByValstateSaverAs System.Collections.IDictionary)
'执行反安装
MyBase.Uninstall(stateSaver)
DeleteFile(String.Format("{0}DB.dat",Me.Context.Parameters.Item("targetdir")))
End Sub
Private SubDeleteFile(ByVal paths AsString)
'删¦除指定的文件
Try
DimdelFile As NewSystem.IO.FileInfo(paths)
IfdelFile.Exists Then
delFile.Delete()
EndIf
Catchex As Exception
End Try
End Sub
‘创建附加数据库语句
Private Sub CreateSql(ByVal paths As String)
DimFile As System.IO.StreamWriter
'Dim db AsString = String.Format("{0}",Me.Context.Parameters.Item("dbname"))
Dim db As String = "ceshi"
Dimpath As String= String.Format("{0}",Me.Context.Parameters.Item("targetdir"))
DimDBpath As String= String.Format("{0}",Me.Context.Parameters.Item("targetdir"))
Try
Dims As NewSystem.Text.StringBuilder
s.Append("usemaster" & vbCrLf)
s.Append(""& vbCrLf)
s.Append("ifexists (select * from sysdevices where name='DBdisk')" &vbCrLf)
s.Append("BEGIN" & vbCrLf)
s.Append(" EXEC sp_dropdevice 'DBdisk'"& vbCrLf)
s.Append("END" & vbCrLf)
s.Append("Else"& vbCrLf)
s.Append("BEGIN" & vbCrLf)
s.Append(" EXEC sp_addumpdevice 'disk','DBdisk','" & path &"DB.dat'"& vbCrLf)
s.Append("END" & vbCrLf)
s.Append(""& vbCrLf)
s.Append("restoredatabase " & db & vbCrLf)
s.Append("FROMdisk='" & path &"DB.dat'"& vbCrLf)
s.Append("WITHMOVE ' ceshi ' TO '" & DBpath &"ceshi.mdf',MOVE ' ceshi _Log' TO '" & DBpath &" ceshi _Log.ldf'")
File = NewSystem.IO.StreamWriter(paths)
File.Write(s.ToString)
Catchex As Exception
Finally
File.Close()
End Try
End Sub
Private Function InstallDB() AsBoolean
'安装数据库调用自动批处理
Try
'创建临时脚本?
CreateSql(String.Format("{0}Mydb2000tp.sql",Me.Context.Parameters.Item("targetdir")))
'调用osql执行脚本
DimsqlProcess As NewSystem.Diagnostics.Process
sqlProcess.StartInfo.FileName = "osql.exe"
sqlProcess.StartInfo.Arguments = String.Format(" -Usa -P s1a2 -S (local) -i ""{0}Mydb2000tp.sql""",Me.Context.Parameters.Item("targetdir"))
sqlProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
sqlProcess.Start()
sqlProcess.WaitForExit() '等待执行
sqlProcess.Close()
'删除脚本文件
'DeleteFile(String.Format("{0}Mydb2000tp.sql",Me.Context.Parameters.Item("targetdir")))
ReturnTrue
Catchex As Exception
ReturnFalse
End Try
End Function
'获取传入的值,修改配置文件的项
Private SubmySetAppConfig(ByVal epqymc As String, ByVal epqyipAsString)
DimAppConfigFilename As String= System.Reflection.Assembly.GetExecutingAssembly.Location
AppConfigFilename =AppConfigFilename.Substring(0, AppConfigFilename.LastIndexOf("\"))
AppConfigFilename = AppConfigFilename +"\ceshi.exe.config"
If (My.Computer.FileSystem.FileExists(AppConfigFilename))Then
DimAppConfigXML As NewSystem.Xml.XmlDataDocument
WithAppConfigXML
.Load(AppConfigFilename)
DimmyList As Xml.XmlNodeList= .GetElementsByTagName("add")
ForEach myNodeAsSystem.Xml.XmlElementIn myList
IfmyNode.GetAttribute("key") ="EnterpriseName"Then
myNode.SetAttribute("value", epqymc)
EndIf
IfmyNode.GetAttribute("key") ="ServerName"Then
myNode.SetAttribute("value",epqyip)
EndIf
Next
.Save(AppConfigFilename)
EndWith
Else
ThrowNew IO.FileNotFoundException(AppConfigFilename+" file not found!")
End If
End Sub