杉宫竹苑工作室

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 1954|回复: 0

InstallShield使用——几个技术问题介绍

[复制链接]
发表于 2019-8-27 14:16:43 | 显示全部楼层 |阅读模式

正式会员享受无限制浏览网站功能和高速网盘下载,赶快加入本站吧!

您需要 登录 才可以下载或查看,没有账号?立即注册

x
1   几个技术问题介绍
1.1 数据库设置
在安装程序中设置数据库,有两种方法:一种采用命令行附加数据库文件,一种是通过SQL Script脚本创建数据库,对于编写SQL Script过于复杂,或创建数据库时间过长时建议采用第一种方法。

1.1.1     命令行附加数据库

1. 将数据库文件(a_data.mdf和a_log.ldf)插入Support Files中;

2. 定义变量:

  1. STRING psvSQLsvr, psvSQLusr, psvSQLpwd;
  2. BOOL bvWindowsLogin;
复制代码


3. 定义CreateDataBase函数:

  1. prototype CreateDataBase(STRING,STRING,STRING);
复制代码


4. 编写CreateDataBase函数:

  1. function CreateDataBase(svSQLsvr,svSQLusr,svSQLpwd)
  2.      STRING szWaitTxt,szdatabase,path,path3;
  3. begin   
  4.      path=TARGETDIR^"Data""a_data.MDF";
  5.      path3=TARGETDIR^"Data""a_log.LDF";
  6.      szWaitTxt=" 正在创建数据库....";
  7.      SdShowMsg (szWaitTxt, TRUE);
  8.      Delay(3);
  9.      CopyFile(SUPPORTDIR^"a_data.MDF",path);
  10.      CopyFile(SUPPORTDIR^"a_log.LDF",path3);
  11.      szdatabase = "/U "+svSQLusr+" /P "+svSQLpwd+" /S "+svSQLsvr+" /Q ""exec sp_attach_db N'a' , N'"+path+"',N'"+path3+"'""";
  12.      if (LaunchAppAndWait("osql.exe", szdatabase,WAIT)<0) then;
  13.    MessageBox ("数据库创建失败!请确您的系统中已安装 Microsoft SQL Server 2000."n如仍无法解决,请联系系统供应商!",SEVERE);
  14.    SdShowMsg (szWaitTxt, FALSE);
  15.    return -1;
  16.      endif;   
  17. end;
复制代码


5. 获取数据库的登录信息,如果没有创建数据库的脚本,安装程序不会弹出SQL登录验证界面,需要编写代码:

  1. Prototype number SQLLogin(); //定义登录函数
  2. function SQLLogin ()
  3.      number nResult, nSize;
  4.      STRING sMessage, sTemp;
  5. begin
  6.      Dlg_Sql:
  7. SQLRTInitialize2 ();  
  8.      nResult = SQLServerSelectLogin(psvSQLsvr, psvSQLusr, psvSQLpwd, bvWindowsLogin );  
  9.      if (nResult = BACK) return BACK;  
  10.      nSize=MAX_PATH;
  11.      MsiGetProperty( ISMSI_HANDLE, "IS_SQLSERVER_STATUS", sTemp, nSize );
  12.      if(sTemp!="0") then
  13.    nSize = _MAX_PATH;
  14.    MsiGetProperty( ISMSI_HANDLE, "IS_SQLSERVER_STATUS_ERROR", sMessage, nSize );
  15.    if( nSize = 0 ) then
  16.   sMessage = SdLoadString( IDS_IFX_SQL_ERROR_LOGIN_FAILED );
  17.    endif;
  18.    MessageBox( sMessage, MB_OK );   
  19.    goto Dlg_Sql;
  20.      endif;
  21.      return 0;
  22. end;
复制代码


6. 在OnFirstUIBefore事件中调用SQLLogin函数:

  1. Dlg_SdSQL:
  2. nResult = SQLLogin();
  3. if (nResult = BACK) goto Dlg_Custom;
复制代码


7. 在OnEnd事件中调用CreateDataBase函数:

  1. function OnEnd()
  2. begin   
  3.      if !MAINTENANCE then
  4.     CreateDataBase(psvSQLsvr,psvSQLusr,psvSQLpwd); // 创建和 优化数据库
  5.      endif;
  6. end;
复制代码


1.1.2     SQL Script

在Installation Designer中的SQL Scripts插入创建数据库的脚本即可,值得注意的是脚本中的文本替换,如果脚本中有安装前未知信息(在安装过程中输入的),如数据库的安装路径,使用软件的公司名称等等,需要使用文本替换,方法如下:

1. 创建数据库的脚本片段

  1. 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%)
  2. GO
  3. use test
  4. GO
  5. INSERT INTO [dbo].[use_company] ( [company _name])
  6.      VALUES ('%MY_COMPANY_NAME%')
复制代码


2. 在Installation Designer中的Property Manager添加一个MY_COMPANYNAME的属性,如下图所示

3. 在OnFirstUIBefore事件中添加代码:

  1. Dlg_UserInfo:  
  2.     szMsg = "请正确输入用户名称及公司名称,以便本系统显示的信息正确!";
  3.     nResult = SdRegisterUser(szTitle, szMsg, szUserInfo, szCompanyName);
  4.     MsiSetProperty(ISMSI_HANDLE,"MY_COMPANYNAME", szCompanyName);
  5. if (nResult = BACK) goto Dlg_SdLicense;
复制代码


4. 在Installation Designer中的SQL Scripts的Text Replacement页面添加两个替换参数,如下图所示:

1.2 InstallScirpt调用动态运行库中的函数
安装过程中有些设置是InstallShield无法做到的,需要其他的编程软件实现,其他的编程软件可以编写成可执行的应用程序(EXE文件),通过LaunchApp和LaunchAppAndWait调用,也可以编写成动态运行库(DLL文件),InstallShield调用其中的函数,我使用的是Borland Delphi编程软件,我编写了一个将安装文件夹设置为FTP虚拟目录的动态运行库,在InstallShield中调用。

Delphi的源代码如下:

  1. library FtpSetup;
  2. uses
  3. SysUtils, Classes, COMOBJ, Variants;
  4. {$R *.res}
  5. procedure FtpSet(siteName, appPath: PCHAR);stdcall;
  6. var
  7. FTPSite, FTPServer, FTPRoot, FTPVDir: Variant;
  8. newSiteName, newAppPath:string;
  9. begin
  10.     newSiteName:= siteName;
  11.     newAppPath:= appPath;
  12.     FTPSite := CreateOleObject('IISNamespace');
  13.     FTPSite := FTPSite.GetObject('IIsFtpService', 'localhost/MSFTPSVC');
  14.     FTPServer := FTPSite.GetObject('IIsFtpServer', '1');
  15.     FTPRoot := FTPServer.GetObject('IIsFtpVirtualDir', 'Root');
  16.     FTPVDir := FTPRoot.Create('IIsFtpVirtualDir', newSiteName);
  17.     FTPVDir.Path := newAppPath;
  18.     FTPVDir.AccessRead := true;
  19.     FTPVDir.AccessWrite := true;
  20.     FTPVDir.SetInfo;
  21.     FTPSite := Unassigned;
  22.     FTPServer := Unassigned;
  23.     FTPRoot := Unassigned;
  24.     FTPVDir := Unassigned;
  25. end;
  26. exports
  27. FtpSet;
  28. begin
  29. end.
复制代码


InstallScript 脚本如下:

  1. 函数定义
  2. prototype stdcall FtpSetup.FtpSet (POINTER,POINTER);  
  3. 调用函数
  4. DLL_FILE= SUPPORTDIR^"FtpSetup.dll";
  5. nResult = UseDLL (DLL_FILE);
  6. if (nResult = 0) then
  7.      svString1 = "drawingfile";
  8.      svString2 = TARGETDIR^"DrawingFilePath";
  9.      psvString1 = &svString1;
  10.      psvString2 = &svString2;
  11.      FtpSet(psvString1,psvString2);
  12.      UnUseDLL (DLL_FILE);
  13. else
  14. MessageBox("创建FTP服务失败,请手工设置。",SEVERE);
  15. endif;
复制代码


值得注意的是函数的编写及调用都采用stdcall方式。

1.3 自定义窗体
1.3.1     Basic MSI Project工程项目
1. 创建自定义窗体,可参考标准窗体的各种设置,主要是窗体Behavior的设置,下面以一个例子说明创建过程;

2. 创建一个记录登录服务器的信息的自定义窗体,该窗体需要录入服务器的IP地址、用户名及口令,将录入信息记录到XML文件中;

3. 如下图所示,在User Interface的Dialogs的All Dialogs点击右键,选择New Dialgo菜单,进入自定义窗体向导;

4. 选择Blank Dialog创建一个空白窗体,重命名NewDialog1,如ServerLogin;

5. 如下图所示选择ServerLogin下的Chinse(Simplified)节,可设计此窗体;

6. 添加三个Text Area,分别将Text属性更改为服务器IP:、用户名:及口令:,添加三个Edit Field,分别录入Property Name(属性名称)为MY_SERVER_IP、MY_SERVER_USER及MY_SERVER_PWD, 将口令的录入框的Password属性的值更改为True,添加三个Push Button,分别是上一步、下一步及取消,如下图所示:

7. 如果想将此窗体插入CustomerInformation窗体与SetupType之间,可选择CustomerInformation的Behavior的Next按钮,如下图所示,将Event的NewDialog的Argument更改为ServerLogin窗体;

8. 选择ServerLogin的Behavior的Next按钮 ,新增一个NewDialog事件,将Argument更改为SetupType窗体,Condition更改为1,同理在上一步按钮中添加返回CustomerInformation窗体的事件,在取消按钮中添加Event为SpawinDialog,Argument为CancelSetup,Condiiton为1,如下图所示:

9. 可以在Behavior and Logic中的Custom Actions and Sequences中可以看出窗体的执行顺序,如下图所示:

10.   在XML File Changes节中添加记录信息,这里不再详述。

1.3.2     InstallScript MIS Project工程项目

1. 创建自定义窗体需要注意在InstallScript中如何调用自定义窗体,并将窗体的属性复制公共属性,下面以一个例子说明调用;

2. 创建一个记录登录服务器FTP的信息的自定义窗体,该窗体需要录入服务器的IP地址、FTP端口、FTP用户名及口令,将录入信息记录到XML文件中;

3. 在User Interface的Dialogs的All Dialogs点击右键,选择New Dialgo菜单,进入自定义窗体向导,选择Blank Dialog创建一个空白窗体,重命名NewDialog1,如SdComputerInfo,编辑窗体如下图所示:

4. 在Direct Editor的Dialog中查出该窗体的ID,我创建的这个自定义窗体的ID为12011,在Direct Editor的Control中查出各控件的ID;

5. 在Property Manager中新建四个属性LOCALHOST、LOGINUSER、LOGINPWD、FTPPORT;

6. 在InstallScript中新建一个名为computerinfo.rul的脚本文件,脚本如下:

  1. prototype SdComputerInfoDialog(string);
  2. #define RES_DIALOG_ID     12011   // ID of custom dialog
  3. #define RES_PBUT_NEXT   1   // ID of Next button
  4. #define RES_PBUT_CANCEL    1310   // ID of Cancel button
  5. #define RES_PBUT_BACK1308   // ID of Back button
  6. #define RES_EDITIP   1302   // ID of edit box
  7. #define RES_EDITUSER 1304
  8. #define RES_EDITPWD  1306
  9. #define RES_EDITPORT 1312
  10. function SdComputerInfoDialog(szTitle)
  11.     STRING szDialogName, svName, svCompany;
  12.     NUMBER nResult, nCmdValue;
  13.     BOOL    bDone;     
  14.     HWND    hwndDlg;
  15.     STRING szComputerIP, szFTPUser, szFTPPwd, szFTPPort;
  16.     number nSize;
  17. begin
  18.      szDialogName = "SdComputerInfo";
  19.     nResult = EzDefineDialog (szDialogName, "", "", RES_DIALOG_ID);
  20.      if (nResult < 0) then
  21.   // Report an error; then terminate.
  22.   MessageBox ("Error in defining dialog", SEVERE);
  23.   abort;
  24.     endif;
  25.      bDone = FALSE;
  26.     // Loop until done.
  27.     repeat
  28.   // Display the dialog and return the next dialog event.
  29.   nCmdValue = WaitOnDialog (szDialogName);
  30.   // Respond to the event.
  31.   switch (nCmdValue)
  32. case DLG_CLOSE:
  33.     // The user clicked the window's Close button.
  34.     Do (EXIT);
  35. case DLG_ERR:
  36.     MessageBox ("Unable to display dialog. Setup canceled.", SEVERE);
  37.     abort;
  38. case DLG_INIT:  
  39. hwndDlg = CmdGetHwndDlg( szDialogName );
  40. SdGeneralInit( szDialogName, hwndDlg, 0, szSdProduct );
  41.     SdSetDlgTitle(szDialogName, hwndDlg, szTitle);
  42.     nSize=MAX_PATH;
  43.     MsiGetProperty( ISMSI_HANDLE, "LOCALHOST", szComputerIP, nSize );
  44.     nSize=MAX_PATH;
  45.     MsiGetProperty( ISMSI_HANDLE, "LOGINUSER", szFTPUser, nSize );
  46.     nSize=MAX_PATH;
  47.     MsiGetProperty( ISMSI_HANDLE, "LOGINPWD", szFTPPwd, nSize );  
  48.     nSize=MAX_PATH;
  49.     MsiGetProperty( ISMSI_HANDLE, "FTPPORT", szFTPPort, nSize );
  50.     CtrlSetText(szDialogName, RES_EDITIP, szComputerIP);
  51.     CtrlSetText(szDialogName, RES_EDITUSER, szFTPUser);
  52.     CtrlSetText(szDialogName, RES_EDITPWD, szFTPPwd);
  53.     CtrlSetText(szDialogName, RES_EDITPORT, szFTPPort);
  54. case RES_PBUT_CANCEL:
  55.     Do (EXIT);
  56. case RES_PBUT_BACK:
  57.     bDone = TRUE;
  58. case RES_PBUT_NEXT:
  59.     CtrlGetText (szDialogName, RES_EDITIP, szComputerIP);
  60.     CtrlGetText (szDialogName, RES_EDITUSER, szFTPUser);
  61.     CtrlGetText (szDialogName, RES_EDITPWD, szFTPPwd);
  62.     CtrlGetText (szDialogName, RES_EDITPORT, szFTPPort);
  63. MsiSetProperty(ISMSI_HANDLE,"LOCALHOST", szComputerIP);
  64. MsiSetProperty(ISMSI_HANDLE,"LOGINUSER", szFTPUser);
  65. MsiSetProperty(ISMSI_HANDLE,"LOGINPWD", szFTPPwd);  
  66. MsiSetProperty(ISMSI_HANDLE,"FTPPORT", szFTPPort);
  67. bDone = TRUE;
  68.   endswitch;
  69.     until bDone;
  70.     // Close the dialog.
  71.     EndDialog (szDialogName);
  72.     // Remove the dialog from memory.
  73.     ReleaseDialog (szDialogName);
  74.     // If dialog is closed with Next button, display name and company.
  75.    
  76.     if nCmdValue = RES_PBUT_NEXT then  
  77.     return NEXT;
  78.     else
  79.   return BACK;
  80.     endif;
  81. end;
复制代码


7.在OnFirstUIBefore事件中添加

  1. Dlg_ComputerInfo:
  2.     szTitle = "设置服务器信息";
  3.     nResult = SdComputerInfoDialog(szTitle);
  4. if (nResult = BACK) goto Dlg_UserInfo;
复制代码


8. 在XML File Changes节中添加记录信息,这里不再详述。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|手机版|Archiver|SgzyStudio

GMT+8, 2024-5-14 10:10 , Processed in 0.105712 second(s), 19 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表