zoukankan      html  css  js  c++  java
  • InstallShield使用——几个技术问题介绍

     

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

    1         几个技术问题介绍

    1.1       数据库设置

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

    1.1.1     命令行附加数据库

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

    2.       定义变量:

    STRING psvSQLsvr, psvSQLusr, psvSQLpwd;

    BOOL bvWindowsLogin;

    3.       定义CreateDataBase函数:

    prototype CreateDataBase(STRING,STRING,STRING);

    4.       编写CreateDataBase函数:

    function CreateDataBase(svSQLsvr,svSQLusr,svSQLpwd)

         STRING szWaitTxt,szdatabase,path,path3;

    begin   

         path=TARGETDIR^"Data""a_data.MDF";

         path3=TARGETDIR^"Data""a_log.LDF";

         szWaitTxt=" 正在创建数据库....";

         SdShowMsg (szWaitTxt, TRUE);

         Delay(3);

         CopyFile(SUPPORTDIR^"a_data.MDF",path);

         CopyFile(SUPPORTDIR^"a_log.LDF",path3);

         szdatabase = "/U "+svSQLusr+" /P "+svSQLpwd+" /S "+svSQLsvr+" /Q ""exec sp_attach_db N'a' , N'"+path+"',N'"+path3+"'""";

         if (LaunchAppAndWait("osql.exe", szdatabase,WAIT)<0) then;

             MessageBox ("数据库创建失败!请确您的系统中已安装 Microsoft SQL Server 2000."n如仍无法解决,请联系系统供应商!",SEVERE);

             SdShowMsg (szWaitTxt, FALSE);

             return -1;

         endif;    

    end;       

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

    Prototype number SQLLogin(); //定义登录函数

    function SQLLogin ()

         number nResult, nSize;

         STRING sMessage, sTemp;

    begin

         Dlg_Sql:

    SQLRTInitialize2 ();              

         nResult = SQLServerSelectLogin(psvSQLsvr, psvSQLusr, psvSQLpwd, bvWindowsLogin );  

         if (nResult = BACK) return BACK;  

         nSize=MAX_PATH;

         MsiGetProperty( ISMSI_HANDLE, "IS_SQLSERVER_STATUS", sTemp, nSize );

         if(sTemp!="0") then

             nSize = _MAX_PATH;

             MsiGetProperty( ISMSI_HANDLE, "IS_SQLSERVER_STATUS_ERROR", sMessage, nSize );

             if( nSize = 0 ) then

                  sMessage = SdLoadString( IDS_IFX_SQL_ERROR_LOGIN_FAILED );

             endif;

             MessageBox( sMessage, MB_OK );    

             goto Dlg_Sql;

         endif;

         return 0;

    end;

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

    Dlg_SdSQL:

    nResult = SQLLogin();

    if (nResult = BACK) goto Dlg_Custom;

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

    function OnEnd()

    begin    

         if !MAINTENANCE then

        CreateDataBase(psvSQLsvr,psvSQLusr,psvSQLpwd); // 创建和 优化数据库

         endif;

    end;

    1.1.2     SQL Script

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

    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%)

    GO

     

    use test

    GO 

    INSERT INTO [dbo].[use_company] ( [company _name])

         VALUES ('%MY_COMPANY_NAME%')

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

    3.       OnFirstUIBefore事件添加代码:

    Dlg_UserInfo:              

        szMsg = "请正确输入用户名称及公司名称,以便本系统显示的信息正确!";

        nResult = SdRegisterUser(szTitle, szMsg, szUserInfo, szCompanyName);

        MsiSetProperty(ISMSI_HANDLE,"MY_COMPANYNAME", szCompanyName);

    if (nResult = BACK) goto Dlg_SdLicense;

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

    1.2       InstallScirpt调用动态运行库中的函数

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

    Delphi的源代码如下:

    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.

    InstallScript脚本如下:

    函数定义

    prototype stdcall FtpSetup.FtpSet (POINTER,POINTER);  

    调用函数

    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;

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

    1.3       自定义窗体

    1.3.1     Basic MSI Project工程项目

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

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

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

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

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

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

    7.       如果想将此窗体插入CustomerInformation窗体与SetupType之间,可选择CustomerInformationBehaviorNext按钮,如下图所示,将EventNewDialogArgument更改为ServerLogin窗体;

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

    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 InterfaceDialogsAll Dialogs点击右键,选择New Dialgo菜单,进入自定义窗体向导,选择Blank Dialog创建一个空白窗体,重命名NewDialog1,如SdComputerInfo,编辑窗体如下图所示:

    4.       Direct EditorDialog中查出该窗体的ID,我创建的这个自定义窗体的ID12011,在Direct EditorControl中查出各控件的ID

    5.       Property Manager中新建四个属性LOCALHOSTLOGINUSERLOGINPWDFTPPORT

    6.       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, "LOCALHOST", szComputerIP, nSize );

                    nSize=MAX_PATH;

                    MsiGetProperty( ISMSI_HANDLE, "LOGINUSER", szFTPUser, nSize ); 

                    nSize=MAX_PATH;

                    MsiGetProperty( ISMSI_HANDLE, "LOGINPWD", szFTPPwd, nSize );  

                    nSize=MAX_PATH;

                    MsiGetProperty( ISMSI_HANDLE, "FTPPORT", 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,"LOCALHOST", szComputerIP);

                 MsiSetProperty(ISMSI_HANDLE,"LOGINUSER", szFTPUser);

                 MsiSetProperty(ISMSI_HANDLE,"LOGINPWD", szFTPPwd);  

                 MsiSetProperty(ISMSI_HANDLE,"FTPPORT", 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;

    7.      OnFirstUIBefore事件中添加

    Dlg_ComputerInfo:

        szTitle = "设置服务器信息";

        nResult = SdComputerInfoDialog(szTitle); 

    if (nResult = BACK) goto Dlg_UserInfo;

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

  • 相关阅读:
    微软职位内部推荐-Software Engineer II
    微软职位内部推荐-Software Engineer II
    微软职位内部推荐-Senior NLP Scientist
    微软职位内部推荐-Software Engineer
    微软职位内部推荐-Service Engineer for Office365
    微软职位内部推荐-Software Engineer II
    微软职位内部推荐-Sr. SE
    微软职位内部推荐-Sr. SW Engineer for Privacy Id
    Kibana常用命令
    API接口规范
  • 原文地址:https://www.cnblogs.com/mm8413/p/1217428.html
Copyright © 2011-2022 走看看