zoukankan      html  css  js  c++  java
  • 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="fishout@TOM.COM" /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 'fishout@TOM.COM', '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 'fishout@TOM.COM', '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 = "fishout@TOM.COM";  
                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 = "fishout@TOM.COM";  
                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 = "fishout@TOM.COM";
                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 = "fishout@TOM.COM";
                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 = "fishout@TOM.COM";  
        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 = "fishout@TOM.COM";
        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

  • 相关阅读:
    HDU 1847
    HDU 1717
    KMP未优化模板、
    Codeforces Round #340 (Div. 2) B. Chocolate
    HDU 1042 N!
    HDU 1018 Big Number
    HDU 1031 Design T-Shirt
    解决Windows 7删除执行过的 EXE、Bat文件有延迟的问题
    修改Android手机的“虚拟机堆大小”和android:largeHeap来防止APP内存溢出问题
    Android引用百度定位API第三方组件后导致其它.so文件无法正常加载的问题
  • 原文地址:https://www.cnblogs.com/Cindy_weiwei/p/1601767.html
Copyright © 2011-2022 走看看