陈宝刚---享受生活,追逐梦想!
理想是心中的火焰,有追求的人才是幸福的人!

引用:http://blog.csdn.net/notavailabe/archive/2005/12/13/551757.aspx

我们的软件中经常会用到MSDE数据库,软件开发完成后通常要把MSDE与我们的软件打包到一起进行分发,并能实现数据库的自动安装配置,这些功能通常在安装程序中实现,下面的脚本实现了用安装程序Installshield自动安装MSDE数据库,自动配置ODBC。


////////////////////////////////////////////////////////////////////////////////
//                                                                           
//   File Name:   Setup.rul                                                  
//                                                                           
//   Description: InstallShield script                                       
//                                                                           
//   Comments:    This script was generated based on the selections you made in
//                the Project Wizard.  Refer to the help topic entitled "Modify     
//                the script that the Project Wizard generates" for information
//                on possible next steps.
//
////////////////////////////////////////////////////////////////////////////////


// Include header files
   
#include "ifx.h"
   
////////////////////// string defines ////////////////////////////

//////////////////// installation declarations ///////////////////

// ----- DLL function prototypes -----


    // your DLL function prototypes
prototype ODBCCP32.SQLConfigDataSource ( HWND, SHORT, STRING, STRING );
prototype ODBCCP32.SQLInstallerError ( SHORT, BYREF LONG, BYREF STRING, SHORT, BYREF SHORT);
prototype ISODBCDisplaySQLInstallerErrorMsg ( STRING );
prototype AddODBC(NUMBER);
#define SQL_MAX_MESSAGE_LENGTH      512
#define SQL_SUCCESS_WITH_INFO         1
#define SQL_NO_DATA                 100
#define SQL_ERROR                    -1
#define ODBC_ADD_SYS_DSN               4    // add a system DSN
#define ODBC_REMOVE_SYS_DSN              6    // remove a system DSN

// ---- script function prototypes -----
prototype  CreateDataBase(string,string,string);

    // your script function prototypes

    // your global variables

 

//////////////////////////////////////////////////////////////////////////////////////////
//                                                                          
//  FUNCTION:   OnFirstUIBefore                                           
//                                                                          
//  EVENT:      The OnFirstUIBefore event is called by OnShowUI when the setup is
//              running in first install mode. By default this event displays UI allowing
//              the end user to specify installation parameters.
//             
//              Note: This event will not be called automatically in a
//              program...endprogram style setup.                                                            
//
//////////////////////////////////////////////////////////////////////////////////////////
function OnFirstUIBefore()
    number  nResult;
    number  nLevel;
    number  nvSize, nSetupType;
    number  nLoop;
    string  szTitle, szMsg;
    string  szOpt1, szOpt2, szLicenseFile;
    string  szName, szCompany;
    string  szTargetPath;
    string  svDir;
    string  szComponents, szTargetdir;
    string  szTargetDirAppendix;
    BOOL    bLicenseAccepted;
begin
    SetTitle( @TITLE_MAIN,24,WHITE);
    SetTitle( @TITLE_CAPTIONBAR,0,BACKGROUNDCAPTION);
    Enable(FULLWINDOWMODE);
    SetColor(BACKGROUND,RGB(58,110,165));

    nSetupType = COMPLETE;

    if ( ALLUSERS ) then  
        TARGETDIR = PROGRAMFILES ^ IFX_COMPANY_NAME ^ IFX_PRODUCT_NAME;
    else
        TARGETDIR = FOLDER_APPDATA ^ IFX_COMPANY_NAME ^ IFX_PRODUCT_NAME;
    endif;

    // Customize the default TARGETDIR for multi-instance application.
    // TODO: If you want something different customize the code below.   
    if( MAINT_OPTION = MAINT_OPTION_MULTI_INSTANCE  && MULTI_INSTANCE_COUNT > 0) then
        nLoop = 1;
        svDir = TARGETDIR;
        while(ExistsDir(TARGETDIR) = EXISTS)           
            NumToStr(szTargetDirAppendix,nLoop);
            TARGETDIR = svDir + szTargetDirAppendix;
            nLoop = nLoop + 1;
        endwhile;                       
    endif;

    svDir = TARGETDIR;
    szName = "";
    szCompany = "";
    bLicenseAccepted = FALSE;

// Beginning of UI Sequence
Dlg_Start:

Dlg_SdWelcome:
    szTitle = "";
    szMsg = "";
    nResult = SdWelcome( szTitle, szMsg );
    if (nResult = BACK) goto Dlg_Start;

Dlg_SdLicense2:
    szTitle = "";
    szOpt1 = "";
    szOpt2 = "";
    szLicenseFile = SUPPORTDIR ^ "license.txt";
    nResult = SdLicense2( szTitle, szOpt1, szOpt2, szLicenseFile, bLicenseAccepted );
    if (nResult = BACK) then
        goto Dlg_SdWelcome;
    else
        bLicenseAccepted = TRUE;
    endif;

Dlg_SdRegisterUser:
    szMsg = "";
    szTitle = "";   
    nResult = SdRegisterUser( szTitle, szMsg, szName, szCompany );
    if (nResult = BACK) goto Dlg_SdLicense2;

Dlg_SetupType2:  
    szTitle = "";
    szMsg = "";
    nResult = SetupType2( szTitle, szMsg, "", nSetupType, 0 );
    if (nResult = BACK) then
        goto Dlg_SdRegisterUser;
    else
        nSetupType = nResult;
        if (nSetupType != CUSTOM) then
            szTargetPath = TARGETDIR;
            nvSize = 0;
            FeatureCompareSizeRequired( MEDIA, szTargetPath, nvSize );
            if (nvSize != 0) then     
                MessageBox( szSdStr_NotEnoughSpace, WARNING );
                goto Dlg_SetupType2;
            endif;
        endif;  
    endif;

Dlg_SdAskDestPath2:
    if ((nResult = BACK) && (nSetupType != CUSTOM)) goto Dlg_SetupType2;
    szTitle = "";
    szMsg = "";
    if (nSetupType = CUSTOM) then
        nResult = SdAskDestPath2( szTitle, szMsg, svDir );
        TARGETDIR = svDir;
    endif;
    if (nResult = BACK) goto Dlg_SetupType2;

Dlg_SdComponentTree:
    if ((nResult = BACK) && (nSetupType != CUSTOM)) goto Dlg_SdAskDestPath2;
    szTitle = "";
    szMsg = "";
    szTargetdir = TARGETDIR;
    szComponents = "";
    nLevel = 2;
    if (nSetupType = CUSTOM) then
        nResult = SdFeatureTree( szTitle, szMsg, szTargetdir, szComponents, nLevel );
        if (nResult = BACK) goto Dlg_SdAskDestPath2; 
    endif;

Dlg_ObjDialogs:
    nResult = ShowObjWizardPages( nResult );
    if (nResult = BACK) goto Dlg_SdComponentTree;
   
Dlg_SdStartCopy2:
    szTitle = "";
    szMsg = "";
    nResult = SdStartCopy2( szTitle, szMsg );   
    if (nResult = BACK) goto Dlg_ObjDialogs;

    return 0;
end;
 
//---------------------------------------------------------------------------
// OnFirstUIAfter
//
// First Install UI Sequence - After Move Data
//
// The OnFirstUIAfter event called by OnShowUI 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.
//
// Note: This event will not be called automatically in a
// program...endprogram style setup.
//---------------------------------------------------------------------------
function OnFirstUIAfter()
    STRING szTitle, szMsg1, szMsg2, szOpt1, szOpt2;
    string    szSQLsvr, szSQLusr, szSQLpwd;        //added
    string szServiceName, szServiceDisplayName, szServiceDescription, szServicePathFile, szStartServiceArgs;
    string szTemp;
    string szMsde2000, szCmdLine;
    string szWaitTxt;
    BOOL bStartService;
    NUMBER bvOpt1, bvOpt2;
    number svServiceState;
     /******************************/
    string szName, szValue;
    number nType;
    /**************************/
begin
    //安装MSDE2000 
    szWaitTxt = "正在安装MSDE2000,请稍等...";
    SdShowMsg(szWaitTxt,TRUE);
    szMsde2000 = SRCDIR ^ "MSDE" ^ "setup.exe";
    szCmdLine = "/q /wait  SECURITYMODE=SQL";
    if (LaunchAppAndWait(szMsde2000, szCmdLine,LAAW_OPTION_WAIT|LAAW_OPTION_MAXIMIZED) < 0) then
        MessageBox ("安装MSDE2000失败.\n如仍无法解决,请联系系统供应商!",SEVERE);
        abort;
    endif;
    SdShowMsg(szWaitTxt,FALSE); 
    //启动服务
    szServiceName = "MSSQL$TEST";
    /*szServiceDisplayName = "MSSQL$TEST";
    szServiceDescription = "MSSQLServer";
    szServicePathFile = PROGRAMFILES ^ "Microsoft SQL Server" ^ "MSSQL$TEST"^ "Binn" ^ "sqlservr.exe -sTEST";
    bStartService = TRUE;
    szTemp = PROGRAMFILES ^ "Microsoft SQL Server" ^ "MSSQL$TEST";
    szStartServiceArgs = "-c " + "-d" + szTemp ^ "Data" ^ "master.mdf " +
                        "-e" + szTemp ^ "LOG" ^ "errorlog " +
                        "-l" + szTemp ^ "Data" ^ "mastlog.ldf";
    ServiceAddService (szServiceName, szServiceDisplayName, szServiceDescription, szServicePathFile, bStartService,
szStartServiceArgs);*/
    szStartServiceArgs = ""; 
    if (ServiceGetServiceState(szServiceName, svServiceState) < ISERR_SUCCESS ) then
        MessageBox ("获取服务" + szServiceName + "出错,程序将试着启动该服务。", SEVERE);
        if (ServiceStartService (szServiceName, szStartServiceArgs) < ISERR_SUCCESS ) then
             MessageBox ("启动服务" + szServiceName + "出错。", SEVERE);
        endif;
    else
        if (svServiceState != SERVICE_RUNNING) then   
            if (ServiceStartService (szServiceName, szStartServiceArgs) < ISERR_SUCCESS ) then
             MessageBox ("启动服务" + szServiceName + "出错。", SEVERE);
            endif;
        endif;
    endif;

    //加载自己的数据库
    szSQLsvr = "(local)" ^ "TEST";
    szSQLusr = "sa";
    szSQLpwd = "sa";
    CreateDataBase(szSQLsvr,szSQLusr,szSQLpwd);    
    //创建系统DSN
    AddODBC(ODBC_ADD_SYS_DSN);
  
   //在注册表中设置应用程序信息
    szName = "CurrentVersion";
    szValue = IFX_PRODUCT_VERSION;
    nType = REGDB_STRING;
    if (RegDBSetAppInfo(szName,nType,szValue,-1) <0) then
        MessageBox ( "在注册表中设置应用程序版本信息出错", WARNING );
    endif;
   
    szName = "ProductKey";
    szValue = IFX_PRODUCT_KEY;
    nType = REGDB_STRING;
    if (RegDBSetAppInfo(szName,nType,szValue,-1) <0) then
        MessageBox ( "在注册表中设置应用程序名称信息出错", WARNING );
    endif;
   

    ShowObjWizardPages(NEXT);
   
    szTitle = "";
    szMsg1 = "";
    szMsg2 = "";
    szOpt1 = "";
    szOpt2 = "";
    bvOpt1   = FALSE;
    bvOpt2   = FALSE;   
   
    if ( BATCH_INSTALL ) then
        SdFinishReboot ( szTitle , szMsg1 , SYS_BOOTMACHINE , szMsg2 , 0 );
    else
       
        // If the update service is enabled, show finish dialog that includes
        // update check option.
        if( ENABLED_ISERVICES & SERVICE_ISUPDATE ) then

            if( SdFinishUpdateEx( szTitle, szMsg1, szMsg2, szOpt1, szOpt2, TRUE ) ) then

                // Don't check for updates in silent mode.
                if( MODE != SILENTMODE ) then
                    UpdateServiceCheckForUpdates( "", FALSE );
                endif;

            endif;

        else
            SdFinish ( szTitle , szMsg1 , szMsg2 , szOpt1 , szOpt2 , bvOpt1 , bvOpt2 );
        endif;

    endif;
end;

//////////////////////////
// 创建数据库        added at 2003/07/23
//////////////////////////
function CreateDataBase(szSQLsvr,szSQLusr,szSQLpwd)
string szCmd,szCmdLine,szWaitTxt;
begin
szWaitTxt=" 正在创建所需数据库....";
SdShowMsg (szWaitTxt, TRUE);
Delay(2);
szCmdLine = "-U "+szSQLusr+" -P "+szSQLpwd+" -S "+szSQLsvr+" -Q \"exec sp_detach_db 'TEST' \"";
if (LaunchAppAndWait("osql.exe ", szCmdLine,LAAW_OPTION_WAIT|LAAW_OPTION_HIDDEN) < 0) then
MessageBox ("分离原来的数据库失败!请确您的系统中已安装 Microsoft SQL Server 2000或服务已启动.\n如仍无法解决,请联系系统供应商!",SEVERE);
endif;
 
szCmdLine = "-U "+szSQLusr+" -P "+szSQLpwd+" -S "+szSQLsvr+" -Q \"exec sp_attach_db 'TEST','"+TARGETDIR ^ "data"
^ "TEST_data.mdf', '" +
                                TARGETDIR ^ "data" ^ "TEST_log.ldf' \0";
if (LaunchAppAndWait("osql.exe ", szCmdLine,LAAW_OPTION_WAIT|LAAW_OPTION_HIDDEN) < 0) then
MessageBox ("数据库创建失败!请确您的系统中已安装 Microsoft SQL Server 2000.\n如仍无法解决,请联系系统供应商!",SEVERE);
endif; 

SdShowMsg (szWaitTxt, FALSE);
return 0;
end;     

/////////////////////////////////////////////////////////////
function AddODBC(nvType)  
    HWND hwnd;
    NUMBER nRes,nError,nvLen,nCount;
    STRING szArgs,szDBQ,szDriver;
begin
    UseDLL(WINSYSDIR ^ "odbccp32.dll");
    szDriver = "SQL Server";
    //参数Network=dbnmpntw   ???     dbmssocn
    /*szArgs  = "DSN=test|"+
            "Description=SQLConfigDSN Sample|"+
            "SERVER=(local)|" +
            "ADDRESS=192.168.7.199|" +
            "NETWORK=dbmssocn|" +
            "DATABASE=pubs|";*/
    szArgs  = "DSN=TEST|"+  
            "Description=SQLConfigDSN Sample|"+
            "SERVER=(local)" ^ "TEST|" +
            "DATABASE=TEST|" ;
    // Replace all semicolons with NULL characters to create null-delimited,
    // double-NULL terminated string, which is the format needed to pass to SQL functions.
    szArgs = szArgs + '|;';
    nvLen = StrLength ( szArgs );
    nvLen = nvLen - 1;
    nCount = 0;
    for nCount = 0 to nvLen
        if ( szArgs[nCount] = '|' ) then
            szArgs[nCount] = '\0';
        endif;
    endfor;

    //hwnd = GetWindowHandle ( HWND_INSTALL );
    nRes = SQLConfigDataSource(hwnd ,nvType,szDriver,szArgs);
   
    if (nRes = FALSE) then
        nError = ISODBCDisplaySQLInstallerErrorMsg ( "whocares" );
    endif;
   
    UnUseDLL(WINSYSDIR ^ "odbccp32.dll");
end;
/////////////////////////////////////////////////////////////
function ISODBCDisplaySQLInstallerErrorMsg ( szODBCComponent )
    LONG    fErrorCode;
    NUMBER  nvResult;
    STRING szErrorMsg[SQL_MAX_MESSAGE_LENGTH];
    SHORT cbErrorMsg, cbErrorMsgMax, iError;
    POINTER pfErrorCode, pcbErrorMsg;
 begin

    pfErrorCode = &fErrorCode;
    pcbErrorMsg = &cbErrorMsg;
    iError = 1;
    cbErrorMsgMax = SQL_MAX_MESSAGE_LENGTH;
    nvResult = SQLInstallerError ( iError, fErrorCode, szErrorMsg,
                                  cbErrorMsgMax, pcbErrorMsg );
    if ( TRUE ) then
        if ( nvResult = SQL_NO_DATA || nvResult = SQL_ERROR ) then
            MessageBox ( @ISODBC_ERR_NOERRDATA + "\n" + szODBCComponent, SEVERE );
        elseif ( nvResult = SQL_SUCCESS_WITH_INFO ) then
            SprintfBox ( SEVERE, "", @ISODBC_ERR_ERRBUFFSHORT + "\n" +
                        @ISODBC_ERR_NUMBER + "\n" + szODBCComponent, fErrorCode );
        else
            MessageBox ( szErrorMsg + "\n" + szODBCComponent, SEVERE );
        endif;
    endif;

    return ( fErrorCode );

 end;    
 
//---------------------------------------------------------------------------
// OnBegin
//
// The OnBegin event is called directly by the framework after the setup
// initializes.
//
// Note: This event will not be called automatically in a
// program...endprogram style setup.
//---------------------------------------------------------------------------
function OnBegin()
    /******************************/
    number nRootKey;
    string szKeySQLServer;
    string szKey,szRegName,svValue;
    number nvType,nvRegSize;  
    /******************************/ 
begin
    if (!MAINTENANCE) then
     /************************************************/
     //检测是否安装过本程序的以前版本
    
         nRootKey = HKEY_LOCAL_MACHINE;
         szKey = "SOFTWARE\\TEST" ^ IFX_PRODUCT_NAME;
         if (RegDBSetDefaultRoot(nRootKey) < 0) then
              MessageBox ("调用RegDBSetDefaultRoot函数失败。", SEVERE);
           endif;
        if (RegDBKeyExist(szKey) == 1) then
              MessageBox ("安装程序检测到系统安装过本程序的以前版本,\n请先卸载以前版本再继续此次安装。", WARNING);
              abort;
           endif;
      
     /************************************************/
   endif;
end;


// --- include script file section ---


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/notavailabe/archive/2005/12/13/551757.aspx

posted on 2010-01-25 23:33  追梦人RUBY  阅读(600)  评论(0编辑  收藏  举报