原文:InstallShield集成安装MSDE2000最小版本(三) fishout特许授权发布
原帖地址:http://blog.csdn.net/fishout/archive/2009/11/09/4790564.aspx
在这一节里,我们讨论如何在安装目录的任意指定基础上实现实例名及sa密码的更改,这样,就继承了原有微软80多兆安装包的功能,但是,现有的安装包体积小多了,仅有原来的1/6,当然,这仅是全新安装而言,对于升级安装是不适应的,不过,实际上我们大多数时候都是使用全新安装,何况,MSDE2000还支持多实例安装,所以,这种方法还是非常有实际意义的。
我们先看看默认实例和命名实例在安装上有何区别:
1、安装目录的区别;
默认安装的子目录名称是:C:\Program Files\Microsoft SQL Server\MSSQL\。
命名实例的子目录名称是:C:\Program Files\Microsoft SQL Server\实例名\。
2、注册表中的区别:
默认实例的注册表位置:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer及Microsoft SQL Server子键。
命名实例的注册表位置:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\实例名。
看来默认实例和命名实例在安装上无论是目录名还是注册表都还是有很大区别。
主要设计思路:
首先,安装子目录的区别可以在Components中的Destination统一设定为<TARGETDIR>,通过自定义窗口根据用户选择用脚本进行控制。
然而,注册表的区别就没有可以直接设置的地方了,因为,我们先前采用的是注册表导入的方式并与相关Components进行关联这种方式进行的,如果采用脚本写注册表入口的方式实现,固然可行,可是,这个工作量太大了,有没有更为简便的办法来实现呢?通过查询联机帮助,发现,CreateRegistrySet这个注册表函数就可以实现注册表入口与特定component的关联。
好了,关键问题的解决思路明确了,让我们来具体实现吧!
目标:实现实例名及sa密码的安装时指定。
一、注册表准备
1、如前所述,在运行中浏览至c:\SQL2KSP4\MSDE,让我们以这个命令行安装使用混合模式身份验证的默认实例:setup.exe SECURITYMODE=SQL SAPWD="[email protected]" /L*v C:\MSDELog.log,等待安装完毕。
2、打开注册表编辑器,导航至:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer,ProtocolList属性中增加tcp/np键值以加快连接速度,删除多余的子健,将MSSQLServer子键下的内容导出,导航至HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server,同样也删除多余的子健并导出,合并两个注册表文件,编辑修改其中的安装路径,使其如下:
(1)、“默认实例”注册表设置:
view plaincopy to clipboardprint?
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server]
"InstalledInstances"=hex(7):4d,00,53,00,53,00,51,00,4c,00,53,00,45,00,52,00,56,\
00,45,00,52,00,00,00,00,00
"SsrpActiveServer"=""
"SqlMdacRegRefCount"=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\MSSQLServer]
"AuditLevel"=dword:00000000
"DefaultLogin"="guest"
"ListenOn"=hex(7):53,00,53,00,4d,00,53,00,53,00,48,00,37,00,30,00,00,00,53,00,\
53,00,4e,00,45,00,54,00,4c,00,49,00,42,00,00,00,00,00
"LoginMode"=dword:00000000
"Map_"="\\"
"Map#"="-"
"Map$"=""
"SetHostName"=dword:00000000
"Tapeloadwaittime"=dword:ffffffff
"uptime_pid"=dword:00000e30
"uptime_time_utc"=hex:de,57,29,6f,c2,5e,ca,01
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\MSSQLServer\CurrentVersion]
"CurrentVersion"="8.00.194"
"RegisteredOwner"=""
"SerialNumber"=""
"CSDVersionNumber"=dword:00000400
"CSDVersion"="8.00.1100"
"Language"=dword:00000804
"checksum"=hex:37,38,32,32,63,31,35,38,61,65,37,64,34,63,64,37,35,30,64,61,30,\
33,34,62,37,64,63,33,37,66,33,36,33,62,37,36,35,65,35,39,66,37,31,30,32,36,\
62,34,37,64,66,36,33,30,63,37,63,64,62,38,64,65,34,37,65,36,30,62,37,32,36,\
39,63,36,34,64,31,65,65,38,33,62,33,62,35,35,31,33,61,36,63,64,61,36,66,63,\
66,32,65,64,64,39,31,36,62,63,62,39,36,66,34,63,32,61,36,34,34,63,64,64,35,\
35,33,34,31,37,36,31,66,62,30,61,64,61,33,32,64,63,64,32,34,39,64,34,31,31,\
31,33,38,63,36,38,61,62,31,64,39,63,00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\MSSQLServer\Parameters]
"SQLArg0"="-d<TARGETDIR>\\Data\\master.mdf"
"SQLArg1"="-e<TARGETDIR>\\LOG\\ERRORLOG"
"SQLArg2"="-l<TARGETDIR>\\Data\\mastlog.ldf"
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\MSSQLServer\SuperSocketNetLib]
"ProtocolList"=hex(7):74,00,63,00,70,00,00,00,6e,00,70,00,00,00,00,00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\MSSQLServer\SuperSocketNetLib\Np]
"PipeName"="\\\\.\\pipe\\\\sql\\query"
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\MSSQLServer\SuperSocketNetLib\Tcp]
"TcpHideFlag"=dword:00000000
"TcpDynamicPorts"="0"
"TcpPort"="1433"
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Setup]
"FeatureName"="SqlRun"
"FirstStart"=dword:00000000
"ProductCode"="{E09B48B5-E141-427A-AB0C-D3605127224A}"
"SQLDataRoot"="<TARGETDIR>"
"SQLPath"="<TARGETDIR>"
"Edition"="Desktop Engine"
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server]
"InstalledInstances"=hex(7):4d,00,53,00,53,00,51,00,4c,00,53,00,45,00,52,00,56,\
00,45,00,52,00,00,00,00,00
"SsrpActiveServer"=""
"SqlMdacRegRefCount"=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\MSSQLServer]
"AuditLevel"=dword:00000000
"DefaultLogin"="guest"
"ListenOn"=hex(7):53,00,53,00,4d,00,53,00,53,00,48,00,37,00,30,00,00,00,53,00,\
53,00,4e,00,45,00,54,00,4c,00,49,00,42,00,00,00,00,00
"LoginMode"=dword:00000000
"Map_"="\\"
"Map#"="-"
"Map$"=""
"SetHostName"=dword:00000000
"Tapeloadwaittime"=dword:ffffffff
"uptime_pid"=dword:00000e30
"uptime_time_utc"=hex:de,57,29,6f,c2,5e,ca,01
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\MSSQLServer\CurrentVersion]
"CurrentVersion"="8.00.194"
"RegisteredOwner"=""
"SerialNumber"=""
"CSDVersionNumber"=dword:00000400
"CSDVersion"="8.00.1100"
"Language"=dword:00000804
"checksum"=hex:37,38,32,32,63,31,35,38,61,65,37,64,34,63,64,37,35,30,64,61,30,\
33,34,62,37,64,63,33,37,66,33,36,33,62,37,36,35,65,35,39,66,37,31,30,32,36,\
62,34,37,64,66,36,33,30,63,37,63,64,62,38,64,65,34,37,65,36,30,62,37,32,36,\
39,63,36,34,64,31,65,65,38,33,62,33,62,35,35,31,33,61,36,63,64,61,36,66,63,\
66,32,65,64,64,39,31,36,62,63,62,39,36,66,34,63,32,61,36,34,34,63,64,64,35,\
35,33,34,31,37,36,31,66,62,30,61,64,61,33,32,64,63,64,32,34,39,64,34,31,31,\
31,33,38,63,36,38,61,62,31,64,39,63,00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\MSSQLServer\Parameters]
"SQLArg0"="-d<TARGETDIR>\\Data\\master.mdf"
"SQLArg1"="-e<TARGETDIR>\\LOG\\ERRORLOG"
"SQLArg2"="-l<TARGETDIR>\\Data\\mastlog.ldf"
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\MSSQLServer\SuperSocketNetLib]
"ProtocolList"=hex(7):74,00,63,00,70,00,00,00,6e,00,70,00,00,00,00,00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\MSSQLServer\SuperSocketNetLib\Np]
"PipeName"="\\\\.\\pipe\\\\sql\\query"
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\MSSQLServer\SuperSocketNetLib\Tcp]
"TcpHideFlag"=dword:00000000
"TcpDynamicPorts"="0"
"TcpPort"="1433"
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Setup]
"FeatureName"="SqlRun"
"FirstStart"=dword:00000000
"ProductCode"="{E09B48B5-E141-427A-AB0C-D3605127224A}"
"SQLDataRoot"="<TARGETDIR>"
"SQLPath"="<TARGETDIR>"
"Edition"="Desktop Engine"
(2)、“命名实例”注册表设置:
view plaincopy to clipboardprint?
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server]
"InstalledInstances"=hex(7):46,00,49,00,53,00,48,00,4f,00,55,00,54,00,00,00,00,\
00
"SsrpActiveServer"=""
"SqlMdacRegRefCount"=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\<ID_INSTANCENAME>]
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\<ID_INSTANCENAME>\MSSQLServer]
"AuditLevel"=dword:00000000
"DefaultLogin"="guest"
"ListenOn"=hex(7):53,00,53,00,4d,00,53,00,53,00,48,00,37,00,30,00,00,00,53,00,\
53,00,4e,00,45,00,54,00,4c,00,49,00,42,00,00,00,00,00
"LoginMode"=dword:00000000
"Map_"="\\"
"Map#"="-"
"Map$"=""
"SetHostName"=dword:00000000
"Tapeloadwaittime"=dword:ffffffff
"uptime_pid"=dword:00000e10
"uptime_time_utc"=hex:23,ac,f1,ec,70,5f,ca,01
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\<ID_INSTANCENAME>\MSSQLServer\CurrentVersion]
"CurrentVersion"="8.00.194"
"RegisteredOwner"=""
"SerialNumber"=""
"CSDVersionNumber"=dword:00000400
"CSDVersion"="8.00.1100"
"Language"=dword:00000804
"checksum"=hex:37,38,32,32,63,31,35,38,61,65,37,64,34,63,64,37,35,30,64,61,30,\
33,34,62,36,30,31,34,32,64,30,61,34,32,61,65,31,37,31,34,33,37,32,63,63,37,\
65,30,61,64,31,66,30,31,32,32,33,64,31,66,36,66,30,32,65,31,32,37,63,38,35,\
38,64,62,39,35,30,34,31,63,32,66,66,38,30,63,38,37,37,66,34,36,66,61,34,34,\
36,32,35,33,33,39,61,38,63,34,62,63,38,36,30,65,31,32,37,66,39,64,34,34,32,\
37,36,32,37,39,36,66,31,38,33,30,64,32,64,32,32,30,63,62,66,63,61,64,30,34,\
32,30,64,35,63,30,30,33,34,33,65,34,00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\<ID_INSTANCENAME>\MSSQLServer\Parameters]
"SQLArg0"="-d<TARGETDIR>\\Data\\master.mdf"
"SQLArg1"="-e<TARGETDIR>\\LOG\\ERRORLOG"
"SQLArg2"="-l<TARGETDIR>\\Data\\mastlog.ldf"
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\<ID_INSTANCENAME>\MSSQLServer\SuperSocketNetLib]
"ProtocolList"=hex(7):74,00,63,00,70,00,00,00,6e,00,70,00,00,00,00,00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\<ID_INSTANCENAME>\MSSQLServer\SuperSocketNetLib\Np]
"PipeName"="\\\\.\\pipe\\MSSQL$FISHOUT\\sql\\query"
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\<ID_INSTANCENAME>\MSSQLServer\SuperSocketNetLib\Tcp]
"TcpHideFlag"=dword:00000000
"TcpDynamicPorts"="0"
"TcpPort"="0"
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\<ID_INSTANCENAME>\Setup]
"FeatureName"="SqlRun"
"FirstStart"=dword:00000000
"ProductCode"="{E09B48B5-E141-427A-AB0C-D3605127224A}"
"SQLDataRoot"="<TARGETDIR>"
"SQLPath"="<TARGETDIR>"
"Edition"="Desktop Engine"
"PatchLevel"="8.4.2039"
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server]
"InstalledInstances"=hex(7):46,00,49,00,53,00,48,00,4f,00,55,00,54,00,00,00,00,\
00
"SsrpActiveServer"=""
"SqlMdacRegRefCount"=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\<ID_INSTANCENAME>]
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\<ID_INSTANCENAME>\MSSQLServer]
"AuditLevel"=dword:00000000
"DefaultLogin"="guest"
"ListenOn"=hex(7):53,00,53,00,4d,00,53,00,53,00,48,00,37,00,30,00,00,00,53,00,\
53,00,4e,00,45,00,54,00,4c,00,49,00,42,00,00,00,00,00
"LoginMode"=dword:00000000
"Map_"="\\"
"Map#"="-"
"Map$"=""
"SetHostName"=dword:00000000
"Tapeloadwaittime"=dword:ffffffff
"uptime_pid"=dword:00000e10
"uptime_time_utc"=hex:23,ac,f1,ec,70,5f,ca,01
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\<ID_INSTANCENAME>\MSSQLServer\CurrentVersion]
"CurrentVersion"="8.00.194"
"RegisteredOwner"=""
"SerialNumber"=""
"CSDVersionNumber"=dword:00000400
"CSDVersion"="8.00.1100"
"Language"=dword:00000804
"checksum"=hex:37,38,32,32,63,31,35,38,61,65,37,64,34,63,64,37,35,30,64,61,30,\
33,34,62,36,30,31,34,32,64,30,61,34,32,61,65,31,37,31,34,33,37,32,63,63,37,\
65,30,61,64,31,66,30,31,32,32,33,64,31,66,36,66,30,32,65,31,32,37,63,38,35,\
38,64,62,39,35,30,34,31,63,32,66,66,38,30,63,38,37,37,66,34,36,66,61,34,34,\
36,32,35,33,33,39,61,38,63,34,62,63,38,36,30,65,31,32,37,66,39,64,34,34,32,\
37,36,32,37,39,36,66,31,38,33,30,64,32,64,32,32,30,63,62,66,63,61,64,30,34,\
32,30,64,35,63,30,30,33,34,33,65,34,00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\<ID_INSTANCENAME>\MSSQLServer\Parameters]
"SQLArg0"="-d<TARGETDIR>\\Data\\master.mdf"
"SQLArg1"="-e<TARGETDIR>\\LOG\\ERRORLOG"
"SQLArg2"="-l<TARGETDIR>\\Data\\mastlog.ldf"
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\<ID_INSTANCENAME>\MSSQLServer\SuperSocketNetLib]
"ProtocolList"=hex(7):74,00,63,00,70,00,00,00,6e,00,70,00,00,00,00,00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\<ID_INSTANCENAME>\MSSQLServer\SuperSocketNetLib\Np]
"PipeName"="\\\\.\\pipe\\MSSQL$FISHOUT\\sql\\query"
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\<ID_INSTANCENAME>\MSSQLServer\SuperSocketNetLib\Tcp]
"TcpHideFlag"=dword:00000000
"TcpDynamicPorts"="0"
"TcpPort"="0"
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\<ID_INSTANCENAME>\Setup]
"FeatureName"="SqlRun"
"FirstStart"=dword:00000000
"ProductCode"="{E09B48B5-E141-427A-AB0C-D3605127224A}"
"SQLDataRoot"="<TARGETDIR>"
"SQLPath"="<TARGETDIR>"
"Edition"="Desktop Engine"
"PatchLevel"="8.4.2039"
3、在安装工程中,新建注册表入口,重命名为:MDSE2000_Default,右击它,点击:Import REG File...,导入刚才已修改好的“默认实例”注册表设置,再次新建注册表入口,重命名为:MSDE2000_Custom,导入为“命名实例”注册表设置,注意:不要在右边勾选与此关联的安装文件组。
二、实例名的变更
实例名的变更通过两个地方进行设置,一是Components的安装路径仅设置为<TARGETDIR>,通过自定义窗口的脚本根据实例名的选择不同而设置不同的路径,二是注册表设置,根据选择的实例名使用CreateRegistrySet函数关联不同的注册表入口。
三、SA密码的修改方法
在“MSDE2000.sql”脚本内容中增加一行:exec sp_password NULL, ‘<SAPASSWORD>‘, ‘sa‘,使其看上去如下:
view plaincopy to clipboardprint?
if not exists (select name from master.dbo.sysdatabases where name = ‘model‘)
begin
exec master..sp_attach_db ‘model‘,‘C:\Program Files\Microsoft SQL Server\MSSQL$FISHOUT\Data\model.mdf‘,‘C:\Program Files\Microsoft SQL Server\MSSQL$FISHOUT\Data\modellog.ldf‘
exec master..sp_attach_db ‘msdb‘,‘C:\Program Files\Microsoft SQL Server\MSSQL$FISHOUT\Data\msdbdata.mdf‘,‘C:\Program Files\Microsoft SQL Server\MSSQL$FISHOUT\Data\msdblog.ldf‘
exec master..sp_resetstatus tempdb
Alter database tempdb modify file (name = tempdev, filename = ‘C:\Program Files\Microsoft SQL Server\MSSQL$FISHOUT\Data\tempdb.mdf‘)
Alter database tempdb modify file (name = templog, filename = ‘C:\Program Files\Microsoft SQL Server\MSSQL$FISHOUT\Data\templog.ldf‘)
exec master..sp_password ‘[email protected]‘, ‘new_password‘, ‘sa‘
use master
exec sp_configure ‘allow updates‘,1
reconfigure with override
update sysdatabases set [filename]=‘C:\Program Files\Microsoft SQL Server\MSSQL$FISHOUT\Data\master.mdf‘ where [name]=‘master‘
exec sp_configure ‘allow updates‘,0
reconfigure with override
end
if not exists (select name from master.dbo.sysdatabases where name = ‘model‘)
begin
exec master..sp_attach_db ‘model‘,‘C:\Program Files\Microsoft SQL Server\MSSQL$FISHOUT\Data\model.mdf‘,‘C:\Program Files\Microsoft SQL Server\MSSQL$FISHOUT\Data\modellog.ldf‘
exec master..sp_attach_db ‘msdb‘,‘C:\Program Files\Microsoft SQL Server\MSSQL$FISHOUT\Data\msdbdata.mdf‘,‘C:\Program Files\Microsoft SQL Server\MSSQL$FISHOUT\Data\msdblog.ldf‘
exec master..sp_resetstatus tempdb
Alter database tempdb modify file (name = tempdev, filename = ‘C:\Program Files\Microsoft SQL Server\MSSQL$FISHOUT\Data\tempdb.mdf‘)
Alter database tempdb modify file (name = templog, filename = ‘C:\Program Files\Microsoft SQL Server\MSSQL$FISHOUT\Data\templog.ldf‘)
exec master..sp_password ‘[email protected]‘, ‘new_password‘, ‘sa‘
use master
exec sp_configure ‘allow updates‘,1
reconfigure with override
update sysdatabases set [filename]=‘C:\Program Files\Microsoft SQL Server\MSSQL$FISHOUT\Data\master.mdf‘ where [name]=‘master‘
exec sp_configure ‘allow updates‘,0
reconfigure with override
end
四、自定义对话框用户接口的实现
编辑修改原有的SdAskDestPath2对话框,使其如图所示:
将以下自定义对话框脚本另存为:SdAskDestPath2DlgEx.rul,在工程中导入,实现安装路径、实例名和SA密码的设置。
view plaincopy to clipboardprint?
//////////////////////////////////////////////////////////////////////////////////////////
//
// File Name: SdAskDestPath2DlgEx.rul
//
// Description: This file contains the InstallShield script for the SdAskDestPath2
// dialog function.
//
/////////////////////////////////////////////////////////////////////////////////////////
#include "Dialogs.h"
#include "CustomDlg.h"
#include "Winapi.h"
#include "ISRTDefs.h"
#include "Silent.h"
#include "sdrc.h"
#include "sdint.h"
#include "DialogsPriv.h"
// 对话框ID定义
#define SD_Radio1 1322
#define SD_Radio2 1323
#define SD_Text1 1324
#define SD_Text2 1325
#define SD_EditInstanceName 1326
#define SD_EditSaPassword 1327
prototype SdAskDestPath2Ex(STRING, STRING, BYREF STRING, BYREF STRING, BYREF STRING);
function SdAskDestPath2Ex(szTitle, szMsg, svDir, svInstanceName, svSaPassword)
STRING szDlg, svDirLoc, szTemp;
INT nId, nTemp, nSdDialog, nStyle;
HWND hwndDlg;
BOOL bDone;
STRING svRadioChoice;
begin
szDlg = SD_DLG_ASKDESTPATH2;
nSdDialog = SD_NDLG_ASKDESTPATH2;
svDirLoc = svDir;
// 读静默安装参数
if (MODE=SILENTMODE) then
SdMakeName( szAppKey, szDlg, szTitle, nSdAskDestPath2 );
SilentReadData( szAppKey, "Result", DATA_NUMBER, szTemp, nId );
if ((nId != BACK) && (nId != CANCEL)) then
SilentReadData( szAppKey, "szDir", DATA_STRING, svDir, nTemp );
SilentReadData( szAppKey, "szInstanceName", DATA_STRING, svInstanceName, nTemp );
SilentReadData( szAppKey, "szSaPassword", DATA_STRING, svSaPassword, nTemp );
endif;
return nId;
endif;
// 确保初始化完成
if (!bSdInit) then
SdInit();
endif;
if (EzDefineDialog( szDlg, "", "", SD_NDLG_ASKDESTPATH2 ) = DLG_ERR) then
return -1;
endif;
// 循环开始直至用户选择标准按钮
bDone = FALSE;
while (!bDone)
nId = WaitOnDialog( szDlg );
switch (nId)
case DLG_INIT:
hwndDlg = CmdGetHwndDlg( szDlg );
TextSubGetValue ( "<ID_RADIOCHOICE>", svRadioChoice, TRUE, TRUE );
if (svRadioChoice = "") then
_WinSubEnableControl (hwndDlg, SD_EditInstanceName, 0); // 禁止控件修改
CtrlSetState(szDlg, SD_Radio1, BUTTON_CHECKED); // 设置初始状态
else
CtrlSetState(szDlg, SD_Radio2, BUTTON_CHECKED);
endif;
TextSubGetValue ( "<ID_INSTANCENAME>", svInstanceName, TRUE, TRUE );
TextSubGetValue ( "<ID_SAPASSWORD>", svSaPassword, TRUE, TRUE );
if (svSaPassword = "") then
svSaPassword = "[email protected]";
endif;
CtrlSetText(szDlg, SD_EditInstanceName, svInstanceName); // 设置初始值
CtrlSetText(szDlg, SD_EditSaPassword, svSaPassword);
CtrlSetText( szDlg, 0x80000000 | SD_STA_DESTDIR, svDirLoc );
if(szMsg != "") then
SdSetStatic( szDlg, SD_STA_CHANGEDIRMSG, szMsg );
endif;
SdGeneralInit( szDlg, hwndDlg, nStyle, szSdProduct );
SdSetDlgTitle(szDlg, hwndDlg, szTitle);
case SD_Radio1:
svRadioChoice = "";
svInstanceName = "";
svSaPassword = "[email protected]";
CtrlSetText(szDlg, SD_EditInstanceName, svInstanceName);
CtrlSetText(szDlg, SD_EditSaPassword, svSaPassword);
_WinSubEnableControl (hwndDlg, SD_EditInstanceName, 0); // 禁止修改
case SD_Radio2:
svRadioChoice = "CustomInstanceName";
svInstanceName = "fishout";
CtrlSetText(szDlg, SD_EditInstanceName, svInstanceName);
_WinSubEnableControl (hwndDlg, SD_EditInstanceName, 1); // 允许修改
case SD_PBUT_CHANGEDIR:
SelectDirNoLog( "", "", svDirLoc, TRUE );
CtrlSetText( szDlg, 0x80000000 | SD_STA_DESTDIR, svDirLoc );
case SD_PBUT_CONTINUE:
svDir = svDirLoc;
CtrlGetText(szDlg, SD_EditInstanceName, svInstanceName);
CtrlGetText(szDlg, SD_EditSaPassword, svSaPassword);
StrToUpper(svInstanceName, svInstanceName);
TextSubSetValue ( "<ID_INSTANCENAME>", svInstanceName, TRUE );
TextSubSetValue ( "<ID_SAPASSWORD>", svSaPassword, TRUE );
TextSubSetValue ( "<ID_RADIOCHOICE>", svRadioChoice, TRUE );
// 根据实例名的不同,确定不同的安装路径
if (svRadioChoice = "") then
svDir = svDir + "\\mssql";
else
svDir = svDir + "\\mssql$" + svInstanceName;
endif;
nId = NEXT;
bDone = TRUE;
case BACK:
CtrlGetText(szDlg, SD_EditInstanceName, svInstanceName);
CtrlGetText(szDlg, SD_EditSaPassword, svSaPassword);
TextSubSetValue ( "<ID_INSTANCENAME>", svInstanceName, TRUE );
TextSubSetValue ( "<ID_SAPASSWORD>", svSaPassword, TRUE );
TextSubSetValue ( "<ID_RADIOCHOICE>", svRadioChoice, TRUE );
nId = BACK;
bDone = TRUE;
case DLG_ERR:
SdError( -1, "SdAskDestPath2" );
nId = -1;
bDone = TRUE;
case DLG_CLOSE:
SdCloseDlg( hwndDlg, nId, bDone );
default:
// 检查标准按钮句柄
if (SdIsStdButton( nId ) && SdDoStdButton( nId )) then
bDone = TRUE;
endif;
endswitch;
endwhile;
EndDialog( szDlg );
ReleaseDialog( szDlg );
SdUnInit( );
// 保存静默安装参数
if (MODE=RECORDMODE) then
SdMakeName( szAppKey, szDlg, szTitle, nSdAskDestPath2 );
SilentWriteData( szAppKey, "szDir", DATA_STRING, svDir, 0 );
SilentWriteData( szAppKey, "szInstanceName", DATA_STRING, svInstanceName, 0 );
SilentWriteData( szAppKey, "szSaPassword", DATA_STRING, svSaPassword, 0 );
SilentWriteData( szAppKey, "Result", DATA_NUMBER, "", nId );
endif;
return nId;
end;
//////////////////////////////////////////////////////////////////////////////////////////
//
// File Name: SdAskDestPath2DlgEx.rul
//
// Description: This file contains the InstallShield script for the SdAskDestPath2
// dialog function.
//
/////////////////////////////////////////////////////////////////////////////////////////
#include "Dialogs.h"
#include "CustomDlg.h"
#include "Winapi.h"
#include "ISRTDefs.h"
#include "Silent.h"
#include "sdrc.h"
#include "sdint.h"
#include "DialogsPriv.h"
// 对话框ID定义
#define SD_Radio1 1322
#define SD_Radio2 1323
#define SD_Text1 1324
#define SD_Text2 1325
#define SD_EditInstanceName 1326
#define SD_EditSaPassword 1327
prototype SdAskDestPath2Ex(STRING, STRING, BYREF STRING, BYREF STRING, BYREF STRING);
function SdAskDestPath2Ex(szTitle, szMsg, svDir, svInstanceName, svSaPassword)
STRING szDlg, svDirLoc, szTemp;
INT nId, nTemp, nSdDialog, nStyle;
HWND hwndDlg;
BOOL bDone;
STRING svRadioChoice;
begin
szDlg = SD_DLG_ASKDESTPATH2;
nSdDialog = SD_NDLG_ASKDESTPATH2;
svDirLoc = svDir;
// 读静默安装参数
if (MODE=SILENTMODE) then
SdMakeName( szAppKey, szDlg, szTitle, nSdAskDestPath2 );
SilentReadData( szAppKey, "Result", DATA_NUMBER, szTemp, nId );
if ((nId != BACK) && (nId != CANCEL)) then
SilentReadData( szAppKey, "szDir", DATA_STRING, svDir, nTemp );
SilentReadData( szAppKey, "szInstanceName", DATA_STRING, svInstanceName, nTemp );
SilentReadData( szAppKey, "szSaPassword", DATA_STRING, svSaPassword, nTemp );
endif;
return nId;
endif;
// 确保初始化完成
if (!bSdInit) then
SdInit();
endif;
if (EzDefineDialog( szDlg, "", "", SD_NDLG_ASKDESTPATH2 ) = DLG_ERR) then
return -1;
endif;
// 循环开始直至用户选择标准按钮
bDone = FALSE;
while (!bDone)
nId = WaitOnDialog( szDlg );
switch (nId)
case DLG_INIT:
hwndDlg = CmdGetHwndDlg( szDlg );
TextSubGetValue ( "<ID_RADIOCHOICE>", svRadioChoice, TRUE, TRUE );
if (svRadioChoice = "") then
_WinSubEnableControl (hwndDlg, SD_EditInstanceName, 0); // 禁止控件修改
CtrlSetState(szDlg, SD_Radio1, BUTTON_CHECKED); // 设置初始状态
else
CtrlSetState(szDlg, SD_Radio2, BUTTON_CHECKED);
endif;
TextSubGetValue ( "<ID_INSTANCENAME>", svInstanceName, TRUE, TRUE );
TextSubGetValue ( "<ID_SAPASSWORD>", svSaPassword, TRUE, TRUE );
if (svSaPassword = "") then
svSaPassword = "[email protected]";
endif;
CtrlSetText(szDlg, SD_EditInstanceName, svInstanceName); // 设置初始值
CtrlSetText(szDlg, SD_EditSaPassword, svSaPassword);
CtrlSetText( szDlg, 0x80000000 | SD_STA_DESTDIR, svDirLoc );
if(szMsg != "") then
SdSetStatic( szDlg, SD_STA_CHANGEDIRMSG, szMsg );
endif;
SdGeneralInit( szDlg, hwndDlg, nStyle, szSdProduct );
SdSetDlgTitle(szDlg, hwndDlg, szTitle);
case SD_Radio1:
svRadioChoice = "";
svInstanceName = "";
svSaPassword = "[email protected]";
CtrlSetText(szDlg, SD_EditInstanceName, svInstanceName);
CtrlSetText(szDlg, SD_EditSaPassword, svSaPassword);
_WinSubEnableControl (hwndDlg, SD_EditInstanceName, 0); // 禁止修改
case SD_Radio2:
svRadioChoice = "CustomInstanceName";
svInstanceName = "fishout";
CtrlSetText(szDlg, SD_EditInstanceName, svInstanceName);
_WinSubEnableControl (hwndDlg, SD_EditInstanceName, 1); // 允许修改
case SD_PBUT_CHANGEDIR:
SelectDirNoLog( "", "", svDirLoc, TRUE );
CtrlSetText( szDlg, 0x80000000 | SD_STA_DESTDIR, svDirLoc );
case SD_PBUT_CONTINUE:
svDir = svDirLoc;
CtrlGetText(szDlg, SD_EditInstanceName, svInstanceName);
CtrlGetText(szDlg, SD_EditSaPassword, svSaPassword);
StrToUpper(svInstanceName, svInstanceName);
TextSubSetValue ( "<ID_INSTANCENAME>", svInstanceName, TRUE );
TextSubSetValue ( "<ID_SAPASSWORD>", svSaPassword, TRUE );
TextSubSetValue ( "<ID_RADIOCHOICE>", svRadioChoice, TRUE );
// 根据实例名的不同,确定不同的安装路径
if (svRadioChoice = "") then
svDir = svDir + "\\mssql";
else
svDir = svDir + "\\mssql$" + svInstanceName;
endif;
nId = NEXT;
bDone = TRUE;
case BACK:
CtrlGetText(szDlg, SD_EditInstanceName, svInstanceName);
CtrlGetText(szDlg, SD_EditSaPassword, svSaPassword);
TextSubSetValue ( "<ID_INSTANCENAME>", svInstanceName, TRUE );
TextSubSetValue ( "<ID_SAPASSWORD>", svSaPassword, TRUE );
TextSubSetValue ( "<ID_RADIOCHOICE>", svRadioChoice, TRUE );
nId = BACK;
bDone = TRUE;
case DLG_ERR:
SdError( -1, "SdAskDestPath2" );
nId = -1;
bDone = TRUE;
case DLG_CLOSE:
SdCloseDlg( hwndDlg, nId, bDone );
default:
// 检查标准按钮句柄
if (SdIsStdButton( nId ) && SdDoStdButton( nId )) then
bDone = TRUE;
endif;
endswitch;
endwhile;
EndDialog( szDlg );
ReleaseDialog( szDlg );
SdUnInit( );
// 保存静默安装参数
if (MODE=RECORDMODE) then
SdMakeName( szAppKey, szDlg, szTitle, nSdAskDestPath2 );
SilentWriteData( szAppKey, "szDir", DATA_STRING, svDir, 0 );
SilentWriteData( szAppKey, "szInstanceName", DATA_STRING, svInstanceName, 0 );
SilentWriteData( szAppKey, "szSaPassword", DATA_STRING, svSaPassword, 0 );
SilentWriteData( szAppKey, "Result", DATA_NUMBER, "", nId );
endif;
return nId;
end;
五、修改脚本文件
1、将Setup.rul中Dlg_SdAskDestPath2标号处的内容修改为以下代码:
view plaincopy to clipboardprint?
Dlg_SdAskDestPath2:
if ((nResult = BACK) && (nSetupType != CUSTOM)) goto Dlg_SetupType2;
szTitle = "";
szMsg = "";
// 还原保存的路径,用于自定义对话框
szDir = szCustomDir;
if (nSetupType = CUSTOM) then
//{{IS_SCRIPT_TAG(Dlg_SdAskDestPath2)
nResult = SdAskDestPath2Ex( szTitle, szMsg, szDir, svInstanceName, svSaPassword );
//}}IS_SCRIPT_TAG(Dlg_SdAskDestPath2)
TARGETDIR = szDir;
else
TARGETDIR = szDir + "\\mssql";
svInstanceName = "";
svSaPassword = "[email protected]";
endif;
if (nResult = BACK) goto Dlg_SetupType2;
Dlg_SdAskDestPath2:
if ((nResult = BACK) && (nSetupType != CUSTOM)) goto Dlg_SetupType2;
szTitle = "";
szMsg = "";
// 还原保存的路径,用于自定义对话框
szDir = szCustomDir;
if (nSetupType = CUSTOM) then
//{{IS_SCRIPT_TAG(Dlg_SdAskDestPath2)
nResult = SdAskDestPath2Ex( szTitle, szMsg, szDir, svInstanceName, svSaPassword );
//}}IS_SCRIPT_TAG(Dlg_SdAskDestPath2)
TARGETDIR = szDir;
else
TARGETDIR = szDir + "\\mssql";
svInstanceName = "";
svSaPassword = "[email protected]";
endif;
if (nResult = BACK) goto Dlg_SetupType2;
2、修改“featureevents.rul”中的内容,实现注册表入口关联及SQL脚本的执行,代码如下:
view plaincopy to clipboardprint?
//---------------------------------------------------------------------------
// The Installed event is sent after the feature DefaultFeature
// is installed.
//---------------------------------------------------------------------------
#include "ShutDownRunningApp.rul"
export prototype DefaultFeature_Installed();
function DefaultFeature_Installed()
number nvServiceState, nResult;
string szServiceName, szServiceDisplayName, szServiceDescription, szServicePathFile, szStartServiceArgs;
BOOL bStartService;
LIST listConnections;
string szMsg, szKey, szConnection, szCmdLine, szServer, svInstanceName;
begin
szCmdLine = TARGETDIR ^ "Binn\\sqlservr.exe";
// 转换为短路经
LongPathToShortPath(szCmdLine);
// 实例名
TextSubGetValue ( "<ID_INSTANCENAME>", svInstanceName, TRUE, TRUE );
if (svInstanceName = "") then
szServer = "(local)";
szServiceName = "MSSQLSERVER";
szServiceDisplayName = "MSSQLSERVER";
szServicePathFile = TARGETDIR ^ "Binn\\sqlservr.exe -sMSSQLSERVER";
szCmdLine = "/c " + szCmdLine + " -sMSSQLSERVER -c -f -T3608 -T4022";
CreateRegistrySet("MSDE2000_Default"); // 写注册表入口
else
szServer = "(local)\\" + svInstanceName;
szServiceName = "MSSQL$" + svInstanceName;
szServiceDisplayName = szServiceName;
szServicePathFile = TARGETDIR ^ "Binn\\sqlservr.exe -s" + svInstanceName;
szCmdLine = "/c " + szCmdLine + " -s" + svInstanceName + " -c -f -T3608 -T4022";
CreateRegistrySet("MSDE2000_Custom");
endif;
// SQL Server 以单用户模式启动,允许对系统目录进行更新,在新目录附加数据库
LaunchApplication(WINSYSDIR ^ "cmd.exe", szCmdLine, "", SW_HIDE, LAAW_OPTION_WAIT, LAAW_OPTION_FIXUP_PROGRAM);
// SQL运行时初始化
SQLRTInitialize2();
// 获取连接信息
listConnections = SQLRTGetConnections();
ListGetFirstString (listConnections, szConnection);
// Windows认证方式
SQLRTPutConnectionAuthentication( szConnection, TRUE );
// 打开连接
nResult = SQLRTConnect( szConnection, szServer, TRUE, "", "" );
if( nResult < ISERR_SUCCESS ) then
// 获取错误信息
SQLRTGetErrorMessage( szMsg );
// 显示错误信息
MessageBox( szMsg, MB_OK );
else
// SQL Server登录成功,保存连接信息
szKey = "";
Sprintf( szKey, SQL_FORMATSTRING_CONNECTION_SERVER, szConnection );
LogWriteCustomString( szKey, szServer );
Sprintf( szKey, SQL_FORMATSTRING_CONNECTION_USER, szConnection );
LogWriteCustomString( szKey, "" );
Sprintf( szKey, SQL_FORMATSTRING_CONNECTION_AUTH, szConnection );
LogWriteCustomNumber( szKey, SQL_AUTH_WINDOWS );
Sprintf( szKey, SQL_FORMATSTRING_CONNECTION_DB, szConnection );
LogWriteCustomString( szKey, "" );
endif;
// 执行SQL脚本
SQLRTComponentInstall("MSDE2000.sql_SQLComponent");
// 中止SQL Server单用户、跟踪进程
if ProcessRunning("sqlservr") then
ProcessEnd("sqlservr");
endif;
// 安装SQL Server服务
szMsg = "正在启动 MSDE2000 SP4服务......";
SdShowMsg(szMsg, TRUE);
// 安装服务
szServiceDescription = "";
bStartService = TRUE;
szStartServiceArgs = "";
if (ServiceGetServiceState (szServiceName, nvServiceState ) >= ISERR_SUCCESS) then
// 停止并卸载原来的服务
ServiceStopService ( szServiceName );
ServiceRemoveService ( szServiceName );
endif;
ServiceAddService ( szServiceName, szServiceDisplayName, szServiceDescription, szServicePathFile, bStartService, szStartServiceArgs );
SdShowMsg(szMsg, FALSE);
end;
//---------------------------------------------------------------------------
// The Installed event is sent after the feature DefaultFeature
// is installed.
//---------------------------------------------------------------------------
#include "ShutDownRunningApp.rul"
export prototype DefaultFeature_Installed();
function DefaultFeature_Installed()
number nvServiceState, nResult;
string szServiceName, szServiceDisplayName, szServiceDescription, szServicePathFile, szStartServiceArgs;
BOOL bStartService;
LIST listConnections;
string szMsg, szKey, szConnection, szCmdLine, szServer, svInstanceName;
begin
szCmdLine = TARGETDIR ^ "Binn\\sqlservr.exe";
// 转换为短路经
LongPathToShortPath(szCmdLine);
// 实例名
TextSubGetValue ( "<ID_INSTANCENAME>", svInstanceName, TRUE, TRUE );
if (svInstanceName = "") then
szServer = "(local)";
szServiceName = "MSSQLSERVER";
szServiceDisplayName = "MSSQLSERVER";
szServicePathFile = TARGETDIR ^ "Binn\\sqlservr.exe -sMSSQLSERVER";
szCmdLine = "/c " + szCmdLine + " -sMSSQLSERVER -c -f -T3608 -T4022";
CreateRegistrySet("MSDE2000_Default"); // 写注册表入口
else
szServer = "(local)\\" + svInstanceName;
szServiceName = "MSSQL$" + svInstanceName;
szServiceDisplayName = szServiceName;
szServicePathFile = TARGETDIR ^ "Binn\\sqlservr.exe -s" + svInstanceName;
szCmdLine = "/c " + szCmdLine + " -s" + svInstanceName + " -c -f -T3608 -T4022";
CreateRegistrySet("MSDE2000_Custom");
endif;
// SQL Server 以单用户模式启动,允许对系统目录进行更新,在新目录附加数据库
LaunchApplication(WINSYSDIR ^ "cmd.exe", szCmdLine, "", SW_HIDE, LAAW_OPTION_WAIT, LAAW_OPTION_FIXUP_PROGRAM);
// SQL运行时初始化
SQLRTInitialize2();
// 获取连接信息
listConnections = SQLRTGetConnections();
ListGetFirstString (listConnections, szConnection);
// Windows认证方式
SQLRTPutConnectionAuthentication( szConnection, TRUE );
// 打开连接
nResult = SQLRTConnect( szConnection, szServer, TRUE, "", "" );
if( nResult < ISERR_SUCCESS ) then
// 获取错误信息
SQLRTGetErrorMessage( szMsg );
// 显示错误信息
MessageBox( szMsg, MB_OK );
else
// SQL Server登录成功,保存连接信息
szKey = "";
Sprintf( szKey, SQL_FORMATSTRING_CONNECTION_SERVER, szConnection );
LogWriteCustomString( szKey, szServer );
Sprintf( szKey, SQL_FORMATSTRING_CONNECTION_USER, szConnection );
LogWriteCustomString( szKey, "" );
Sprintf( szKey, SQL_FORMATSTRING_CONNECTION_AUTH, szConnection );
LogWriteCustomNumber( szKey, SQL_AUTH_WINDOWS );
Sprintf( szKey, SQL_FORMATSTRING_CONNECTION_DB, szConnection );
LogWriteCustomString( szKey, "" );
endif;
// 执行SQL脚本
SQLRTComponentInstall("MSDE2000.sql_SQLComponent");
// 中止SQL Server单用户、跟踪进程
if ProcessRunning("sqlservr") then
ProcessEnd("sqlservr");
endif;
// 安装SQL Server服务
szMsg = "正在启动 MSDE2000 SP4服务......";
SdShowMsg(szMsg, TRUE);
// 安装服务
szServiceDescription = "";
bStartService = TRUE;
szStartServiceArgs = "";
if (ServiceGetServiceState (szServiceName, nvServiceState ) >= ISERR_SUCCESS) then
// 停止并卸载原来的服务
ServiceStopService ( szServiceName );
ServiceRemoveService ( szServiceName );
endif;
ServiceAddService ( szServiceName, szServiceDisplayName, szServiceDescription, szServicePathFile, bStartService, szStartServiceArgs );
SdShowMsg(szMsg, FALSE);
end;
好了!一个相对比较完美的MSDE2000最小版本就实现了,这下可以将其集成在自己的应用程序中,以下问题全部解决:
1、无法与应用程序的安装一并卸载;
2、无法实现MSDE2000的最小安装;
3、如果用户中途取消安装,程序不能完全回滚;
4、无法与应用程序安装到同一个目录。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/fishout/archive/2009/11/09/4790564.aspx
InstallShield集成安装MSDE2000最小版本(三) fishout特许授权发布