引用: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