InstallShield使用——InstallScript MIS Project例子
InstallShield使用——InstallScript MIS Project例子
InstallScript MIS Project工程项目
这个例子实现MS SQL SERVER数据库、asp.net网站(asp.net 3.5)、FTP虚拟目录设置。
1. 创建一个新的工程,选择Basic MSI Project工程类型,在Project Name中填入工程名称:脚本包测试,在Location中选择存放路径,并选择Create project file in ‘Project Name’ subfolder(在工程文件夹中创建子文件夹),点击OK;
2. 如果设置了Source Control(源代码管理),会弹出Add to Source Control(添加到源代码管理中)界面,可根据个人需要选择OK或Cancel;
3. 选择Installation Designer界面;
4. 在Installation Information的General Information页中的Add or Remove Programs项中更改Publisher(公司名称)属性:默默软件公司,在Porduct Properties项中更改INSTALLDIR(默认安装路径):d:"MySite;
5. 在Organization的Setup Design页中添加三个Feature:Database(Display Name:数据库;Description:安装并设置数据库)、WebSite(Display Name:网站;Description:安装并设置应用程序网站);
6. 在Organization的Components页中添加WebSite组件,在Files节点中动态添加文件夹,在向导中选中Include subfolders(包含子文件夹)及Include all files,选择网站所在文件夹;
7. 在Organization的Setup Design页中的WebSite项中关联Components的WebSite;
8. 在Behavior and Logic的Property Manager中添加五个公共属性:FTP_IP、FTP_USER、FTP_PWD、FTP_PORT、MY_COMPANYNAME;
9. 在System Configuration的XML File Changes添加网站配置文件web.config,在General页中的XML File Destination选择[INSTALLDIR],在Select Features the XML file belongs to中选择WebSite,添加一个New Root Element,并重命名为configuration,添加一个New Element,并重命名为connectionStrings,添加一个New Element,并重命名为add[@connectionString="" and @name="DBConnectString"],在此元素的General页面添加属性name,Value为DBConnectString,添加属性connectionString,Value为Server=[IS_SQLSERVER_SERVER];User id=[IS_SQLSERVER_USERNAME];Pwd=[IS_SQLSERVER_PASSWORD];DataBase=TEST;Max Pool Size=200;Connect Timeout=300;Connection Lifetime=3; ;在configuration元素下再添加一个新元素appSettings,在此元素五个新元素,分别是:add[@key="CompanyName" and @value=""](属性:key: CompanyName,value: [MY_COMPANYNAME])、add[@key="FtpPassword" and @value=""](属性:key: FtpPassword,value: [FTP_PWD])、add[@key="FtpUserName" and @value=" "](属性:key: FtpUserName,value: [FTP_USER])、add[@key=" FtpPort" and @value=" "](属性:key: FtpPort,value: [FTP_PORT])、add[@key=" FtpHost" and @value=" "](属性:key: FtpHost,value: [FTP_IP]);
10. 在Server Configuration的Internet Information Services中的Web Sites添加一个网站,重命名为默认网站,在默认网站下添加一个虚拟目录MySite,在General页面中更改ASP .NET Version为2.0.50727,在Virtual Directory页面中更改Local Path为[INSTALLDIR],Application pool(IIS 6 and later only)更改为DefaultAppPool;
11. 在SQL Scripts添加一个New SQL Connection,在此连接中添加一个New Script,在General页面中的Select Features the XML file belongs to选择Database,在Script页面中编写建库脚本,在Text Replacement页面添加替换将%INSTALL_DIR%替换为[INSTALLDIR]、%MY_COMPANY_NAME%替换为[MY_COMPANYNAME];
建库脚本:
CREATE DATABASE [test] ON (NAME = N'test_Data', FILENAME = N'%INSTALL_DIR%DATA"test_Data.MDF' , SIZE = 4, FILEGROWTH = 0) LOG ON (NAME = N'test_Log', FILENAME = N'%INSTALL_DIR%DATA"test_Log.LDF' , SIZE = 4, FILEGROWTH = 10%)
GO
use test
GO
CREATE TABLE [dbo].[test] ( [test_code] [smallint] IDENTITY (1, 1) NOT NULL , [test_name] [char] (40) NOT NULL , ) ON [PRIMARY]
GO
CREATE UNIQUE CLUSTERED INDEX [PK__test__6FE99F9F] ON [dbo].[test]([test_code]) ON [PRIMARY]
GO
INSERT INTO [dbo].[test] ( [test_name]) VALUES ('%MY_COMPANY_NAME%')
12. 在User Interface的Dialogs的All Dialogs点击右键,选择New Dialgo菜单,进入自定义窗体向导,选择Blank Dialog创建一个空白窗体,重命名NewDialog1为SdComputerInfo,在Direct Editor的Dialog中查出该窗体的ID为12011,在Direct Editor的Control中查出各控件的ID;
13. 在InstallScript中新建一个名为computerinfo.rul的脚本文件,脚本如下:
prototype SdComputerInfoDialog(string);
#define RES_DIALOG_ID 12011 // ID of custom dialog
#define RES_PBUT_NEXT 1 // ID of Next button
#define RES_PBUT_CANCEL 1310 // ID of Cancel button
#define RES_PBUT_BACK 1308 // ID of Back button
#define RES_EDITIP 1302 // ID of edit box
#define RES_EDITUSER 1304
#define RES_EDITPWD 1306
#define RES_EDITPORT 1312
function SdComputerInfoDialog(szTitle)
STRING szDialogName, svName, svCompany;
NUMBER nResult, nCmdValue;
BOOL bDone;
HWND hwndDlg;
STRING szComputerIP, szFTPUser, szFTPPwd, szFTPPort;
number nSize;
begin
szDialogName = "SdComputerInfo";
nResult = EzDefineDialog (szDialogName, "", "", RES_DIALOG_ID);
if (nResult < 0) then
// Report an error; then terminate.
MessageBox ("Error in defining dialog", SEVERE);
abort;
endif;
bDone = FALSE;
// Loop until done.
repeat
// Display the dialog and return the next dialog event.
nCmdValue = WaitOnDialog (szDialogName);
// Respond to the event.
switch (nCmdValue)
case DLG_CLOSE:
// The user clicked the window's Close button.
Do (EXIT);
case DLG_ERR:
MessageBox ("Unable to display dialog. Setup canceled.", SEVERE);
abort;
case DLG_INIT:
hwndDlg = CmdGetHwndDlg( szDialogName );
SdGeneralInit( szDialogName, hwndDlg, 0, szSdProduct );
SdSetDlgTitle(szDialogName, hwndDlg, szTitle);
nSize=MAX_PATH;
MsiGetProperty( ISMSI_HANDLE, "FTP_ID", szComputerIP, nSize );
nSize=MAX_PATH;
MsiGetProperty( ISMSI_HANDLE, "FTP_USER", szFTPUser, nSize );
nSize=MAX_PATH;
MsiGetProperty( ISMSI_HANDLE, "FTP_PWD", szFTPPwd, nSize );
nSize=MAX_PATH;
MsiGetProperty( ISMSI_HANDLE, "FTP_PORT", szFTPPort, nSize );
CtrlSetText(szDialogName, RES_EDITIP, szComputerIP);
CtrlSetText(szDialogName, RES_EDITUSER, szFTPUser);
CtrlSetText(szDialogName, RES_EDITPWD, szFTPPwd);
CtrlSetText(szDialogName, RES_EDITPORT, szFTPPort);
case RES_PBUT_CANCEL:
Do (EXIT);
case RES_PBUT_BACK:
bDone = TRUE;
case RES_PBUT_NEXT:
CtrlGetText (szDialogName, RES_EDITIP, szComputerIP);
CtrlGetText (szDialogName, RES_EDITUSER, szFTPUser);
CtrlGetText (szDialogName, RES_EDITPWD, szFTPPwd);
CtrlGetText (szDialogName, RES_EDITPORT, szFTPPort);
MsiSetProperty(ISMSI_HANDLE,"FTP_ID", szComputerIP);
MsiSetProperty(ISMSI_HANDLE,"FTP_USER", szFTPUser);
MsiSetProperty(ISMSI_HANDLE,"FTP_PWD", szFTPPwd);
MsiSetProperty(ISMSI_HANDLE,"FTP_PORT", szFTPPort);
bDone = TRUE;
endswitch;
until bDone;
// Close the dialog.
EndDialog (szDialogName);
// Remove the dialog from memory.
ReleaseDialog (szDialogName);
// If dialog is closed with Next button, display name and company.
if nCmdValue = RES_PBUT_NEXT then
return NEXT;
else
return BACK;
endif;
end;
14. 用Delphi编写设置FTP虚拟目录的代码,代码如下:
library FtpSetup;
uses
SysUtils, Classes, COMOBJ, Variants;
{$R *.res}
procedure FtpSet(siteName, appPath: PCHAR);stdcall;
var
FTPSite, FTPServer, FTPRoot, FTPVDir: Variant;
newSiteName, newAppPath:string;
begin
newSiteName:= siteName;
newAppPath:= appPath;
FTPSite := CreateOleObject('IISNamespace');
FTPSite := FTPSite.GetObject('IIsFtpService', 'localhost/MSFTPSVC');
FTPServer := FTPSite.GetObject('IIsFtpServer', '1');
FTPRoot := FTPServer.GetObject('IIsFtpVirtualDir', 'Root');
FTPVDir := FTPRoot.Create('IIsFtpVirtualDir', newSiteName);
FTPVDir.Path := newAppPath;
FTPVDir.AccessRead := true;
FTPVDir.AccessWrite := true;
FTPVDir.SetInfo;
FTPSite := Unassigned;
FTPServer := Unassigned;
FTPRoot := Unassigned;
FTPVDir := Unassigned;
end;
exports
FtpSet;
begin
end.
15. 新建一个文本文件license.txt,内容如下:
感谢安装由我公司开发的管理系统。
此版本在安装成功后需要注册,未注册版本只能用于测试及试用,在测试了100个工作单后将无法再进行文档的管理。
16. 在Behavior and Logic的Support Files/Billboards的Support Files—Language Independent下添加文件license.txt、FtpSetup.dll及dotnetfx35.exe(.NET3.5的运行库安装包);
17. 编辑InstallScript的Setup.rul文件,代码如下:
prototype stdcall FtpSetup.FtpSet (POINTER,POINTER);
prototype CheckFTP(); //检测是否安装了FTP
// Included header files ----------------------------------------------------
#include "ifx.h"
#include "ComputerInfo.rul";
number ftpSelect;
function OnMoving()
string szAppPath;
begin
// Set LOGO Compliance Application Path
// TO DO : if your application .exe is in a subfolder of TARGETDIR then add subfolder
szAppPath = TARGETDIR;
RegDBSetItem(REGDB_APPPATH, szAppPath);
//RegDBSetItem(REGDB_APPPATH_DEFAULT, szAppPath ^ @PRODUCT_KEY);
end;
//
//
//检测是否安装了FTP
//
//
function CheckFTP()
NUMBER nvType, nvSize;
STRING svvalue;
begin
RegDBSetDefaultRoot ( HKEY_LOCAL_MACHINE );
if (RegDBKeyExist ("System""CurrentControlSet""Services""MSFtpsvc" ) = 1) then
return (1);
else
return (0);
endif;
end;
//---------------------------------------------------------------------------
// OnFirstUIAfter
//
// The OnFirstUIAfter event called by the framework after the file transfer
// of the setup when the setup is running in first install mode. By default
// this event displays UI that informs the end user that the setup has been
// completed successfully.
//---------------------------------------------------------------------------
function OnFirstUIAfter()
STRING szTitle, szMsg1, szMsg2, szOption1, szOption2;
NUMBER bOpt1, bOpt2;
number nResult;
POINTER psvString1,psvString2;
STRING svString1,svString2;
string DLL_FILE;
begin
Disable(STATUSEX);
bOpt1 = FALSE;
bOpt2 = FALSE;
szMsg1 = SdLoadString(IFX_SDFINISH_MSG1);
if(ftpSelect!=0) then
DLL_FILE= SUPPORTDIR^"FtpSetup.dll";
nResult = UseDLL (DLL_FILE);
if (nResult = 0) then
svString1 = "drawingfile";
svString2 = TARGETDIR^"DrawingFilePath";
psvString1 = &svString1;
psvString2 = &svString2;
FtpSet(psvString1,psvString2);
UnUseDLL (DLL_FILE);
else
MessageBox("创建FTP服务失败,请手工设置。",SEVERE);
endif;
endif;
SdFinishEx(szTitle, szMsg1, szMsg2, szOption1, szOption2, bOpt1, bOpt2);
end;
//---------------------------------------------------------------------------
// OnFirstUIBefore
//
// The OnFirstUIBefore event is called by the framework when the setup is
// running in first install mode. By default this event displays UI allowing
// the end user to specify installation parameters.
//---------------------------------------------------------------------------
function OnFirstUIBefore()
number nResult;
string szTitle, szMsg;
string szUserInfo, szCompanyName;
string szDir;
LIST listStartCopy;
string svServer, svUser, svPassword, sTemp, sMessage;
BOOL bvWindowsLogin;
number nSize;
number dbSelect;
number nvUser;
string szLicenseFile;
begin
TARGETDIR = "D:""MySite";
szDir = TARGETDIR;
//SHELL_OBJECT_FOLDER = @FOLDER_NAME;
Dlg_Start:
// beginning of dialogs label
Dlg_SdWelcome:
szTitle = "";
szMsg = "";
nResult = SdWelcome( szTitle, szMsg );
if (nResult = BACK) goto Dlg_Start;
nResult = CheckFTP();
if (nResult = 0) then
MessageBox ("你的计算机没有安装FTP服务,请手工设置FTP!",SEVERE);
endif;
Dlg_SdLicense:
szLicenseFile = SUPPORTDIR ^ "license.txt";
szTitle = "";
szMsg = "";
nResult = SdLicense2( szTitle, "","", szLicenseFile, FALSE );
if (nResult = BACK) goto Dlg_SdWelcome;
Dlg_SelMode ://安装.net框架
szTitle = "是否安装.net 3.5框架";
szMsg = "是否要安装.net 3.5框架,如果已经安装了.net框架则不需要安装。";
szField1 = "我要安装.net框架。";
szField2 = "我已经安装了,不需要再安装。";
svEdit1 = TRUE;
svEdit2 = FALSE;
SetDialogTitle(DLG_ASK_TEXT,szTitle);
nOpt = EXCLUSIVE ;
nResult = AskOptions (nOpt,szMsg,szField1,svEdit1,szField2,svEdit2);
if (nResult = BACK) goto Dlg_SdLicense;
if (svEdit1 = TRUE) then
if(LaunchAppAndWait ( SUPPORTDIR ^"dotnetfx35.exe" , "" ,WAIT)<0) then
MessageBox ("安装.net框架时发生意外,请重新安装。",SEVERE);
goto Dlg_SelMode;
endif;
endif;
Dlg_UserInfo:
szMsg = "请正确输入用户名称及公司名称,以便本系统显示的信息正确!";
nResult = SdRegisterUser(szTitle, szMsg, szUserInfo, szCompanyName);
MsiSetProperty(ISMSI_HANDLE,"MY_COMPANYNAME", szCompanyName);
if (nResult = BACK) goto Dlg_SelMode;
Dlg_ComputerInfo:
szTitle = "设置服务器信息";
nResult = SdComputerInfoDialog(szTitle);
if (nResult = BACK) goto Dlg_UserInfo;
Dlg_Custom:
szTitle = "";
nResult = SdFeatureDialog ( szTitle, szMsg, szDir, "" );
TARGETDIR = szDir;
MsiSetProperty(ISMSI_HANDLE,"FTP_A_PATH", szDir);
if (nResult = BACK) goto Dlg_ComputerInfo;
ftpSelect = FeatureIsItemSelected ( MEDIA, "WebSite" );
dbSelect = FeatureIsItemSelected ( MEDIA, "Database" );
if(dbSelect = 0) goto Dlg_SdStartCopy;
Dlg_Sql:
nResult = OnSQLLogin(nResult);
if (nResult = BACK) goto Dlg_Custom;
Dlg_SdStartCopy:
listStartCopy = ListCreate( STRINGLIST );
ListAddString(listStartCopy,"准备安装。",AFTER);
nResult = SdStartCopy( szTitle, szMsg, listStartCopy );
ListDestroy(listStartCopy);
if (nResult = BACK) then
if(dbSelect = 0) then
goto Dlg_Custom;
else
goto Dlg_Sql;
endif;
endif;
// setup default status
SetStatusWindow(0, "");
nResult = Enable(STATUSEX);
StatusUpdate(ON, 100);
return 0;
end;
18. 选择Media的Releases,可通过向导创建安装盘。
小结
至此InstallShield的内容已经全部介绍完毕,如有错误之处请指正,如果有人需要完整的图文并茂的文档可留下Email。