打包:InstallShield

打包:InstallShield,由windows提供, 安装包开发的制作工具 。

1.新建工程:File---->New---->Windows Installer----> Installscript MSI Project

2.配置工程:把界面切到 Project Assistant,跟着底部的进度条一步一步完成。

(1) Application Information:公司名称,软件名称,版本号,公司网址(必填),更新是否自动通知用户,图标

(2)Installation Requirement:操作系统和所需的软件等

(3) Installation Architecture: 用户可以自由选择安装某些功能。(可参考下面第三个网址)

如果为Yes,在此处设置好以后, 把界面切到 Installation Designer ----> Organization ----> Features 重新修改一遍名称。

(4) Application Files : 安装路径,默认路径为C:\Program Files (x86)\公司名称\项目名称,现改为C:\Program Files (x86)\项目名称

(5) Application Shortcuts :快捷方式

左侧: More Options下Create an uninstallation shortcut:卸载快捷方式。

右侧勾选按钮分别为: a.开始菜单快捷方式。 b. 桌面快捷方式 。c. 替换快捷方式的图标 。d.

将文件扩展名与快捷方式的目标关联

然后,把界面切到 Installation Designer ----> System Configuration ---->Shortcuts就可以看到添加的快捷方式.exe

(6) Application Registry :注册表写key和value

(7) Installation Location : 安装包的语言

然后,把界面切到 Installation Designer ----> Installation Information ----> General Information 可以看到勾选的语言, 右键,选择Make Default 可以设置默认语言。

(8) Build Installation:打包安装盘的设置,当然你也可以用工具条上的Release Wizard,自己写脚本。

3.通过工具制作的安装包也许不能实现所有的要求,接下来就要通过脚本来弥补不足的地方。先回到Installation Designer界面。

(1)软件许可协议: Behavior and Logic ----> Support Files/Billboards ----> Support Files ----> Language Independent (在此设置后,所有语言都有效),Files部分, 右键 Insert Files打开事先写好的许可协议( txt,rtf 格式)。

(2)安装脚本:Behavior and Logic ----> Installscript ---->Files ---->Setup.Rul



//                                                                            
//  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"
#include "AppOperate.rul" 

// string defines 
#define LICENSE_PATH 	 "License.txt"		    			  	   //  自定义许可文件
#define SRC_BIN_FOLDER	 "Bin"  								   //  数据源Bin目录
#define DES_BIN_FOLDER	 "Bin"				   					   //  Bin
#define SRC_DIST_FOLDER  "Dist"                                    //  数据源Dist目录
#define DES_DIST_FOLDER  "dist"                                    //  dist
#define DES_PRJ_FOLDER	 "Project"                                 //  Project
#define DES_MENU_FOLDER  "Menu"                      			   //  Menu
#define LANUCH_FOLDER	 "dist"                                    //  dist
#define LANUCH_INI		 "config.ini"							   //  程序启动配置文件
#define LANUCH_APPNAME   "LiveUpdate.exe"                   	   //  应用程序启动名称
#define PRODOUCT_NAME	 "XX客户端"                                //  应用软件名称
#define PROFILES_NAME	 "HHWYGISELECDATAEDIT"					   //  AutoCAD配置模板名称
#define REGISTER_DLLDIR	 "Bin\\Arx\\reg.bat"					   //  主要注册的dll路径
#define VC_REDIST_DIR	 "Support\\Drivers\\vcredist"              //  运行时的分发包目录
//#define ACCESSDRIVER_X64_DIR  "Support\\Drivers\\AceRedist.msi"    //  运行时的分发包目录
#define VC_REDIST_11	 "{1D8E6291-B0D5-35EC-8441-6616F567A0F7}"  //  VC11.0运行时          
//#define VCREDIST_x86_2005 "vcredist_x86_2005.exe"                  //  vc
//#define VCREDIST_x64_2005 "vcredist_x64_2005.exe"                  //  vc
//#define VCREDIST_x86_2008 "vcredist_x86_2008.exe"                  //  vc
//#define VCREDIST_x64_2008 "vcredist_x64_2008.exe"                  //  vc
//#define VCREDIST_x86_2010 "vcredist_x86_2010.exe"                  //  vc
//#define VCREDIST_x64_2010 "vcredist_x64_2010.exe"                  //  vc
#define VCREDIST_x86_2016 "vcredist_x86_2016.exe"                  //  vc
#define VCREDIST_x64_2016 "vcredist_x64_2016.exe"                  //  vc
	
 installation declarations ///

// ----- DLL function prototypes -----
	
 // your DLL function prototypes			
    
// ---- script function prototypes -----
    // your script function prototypes   
      prototype BOOL InitVcredist(STRING);
      prototype BOOL InitCADVerInfo();
      prototype string GetUpperDir(string);
      prototype BOOL IsInstallCADVersion(STRING,STRING,STRING); 						// OutVer.InVer.CurVer
	  prototype BOOL GetCADVerInfo(STRING, BYREF STRING, BYREF STRING,BYREF STRING,BYREF STRING); 	// OutVer.InVer.CurVer
	  prototype BOOL SearchRoamableRootFolder(STRING, STRING,BYREF STRING); 			// InVer.CurVer.RoamableRootFolder
	  prototype BOOL InitSelectVerionInstallPara(STRING);								// OutVer
	  prototype BOOL SearchCADPath(STRING,STRING,BYREF STRING,BYREF STRING);			//InVer.CurVer.ACADPath.ACADSearchPath
	  prototype BOOL CreateUninstShortCut();      						     			//uninstll shortCut
	  prototype BOOL LaunchAppAcad();	                                                //Start App										
	  prototype ModifyFileData(STRING,STRING ,STRING );
	  prototype RecursionModifyFileData(OBJECT,STRING ,STRING  );
	   												
	   
      prototype BOOL WriteReg();			
      prototype BOOL InstallDogDirver();		
      prototype BOOL SetupFolders();
      prototype BOOL CopyVersionFiles();
      prototype BOOL RegisterDll();
      prototype BOOL SetCompatModel(STRING,STRING);                       				//Set App 兼容模式 
      prototype BOOL UninstallFiles();
      prototype	BOOL WindowsUnstallInfo(STRING);										//卸载信息
      prototype BOOL InstallSoftSilent(STRING,STRING);									//静默式安装某个程序
      
      //Use to Uninstall OldVersion
      prototype BOOL UninstallOldVersion(STRING);
      prototype BOOL CheckOldVersion(STRING,BYREF STRING);				                                                                                           
                                                                                                 
    // your global variables
    typedef CADVERSIONINFO				//Define CAD Version Info
	begin  
		LIST listOutVerID; 					//CAD Outside Verion Name    AutoCAD 2007
		LIST listInVerID;					//CAD Inside Verion Name     R17.0
		LIST listCurVerID;					//CAD Current Version Name   ACAD-201:804
		LIST listCustomID;					//CAD  Custom Version name	 2009
		LIST listShortID;					//CAD  Short  Version name	 09
	end;
   
  
     STRING g_ACADPath;
     STRING g_ACADSearchPath; 
     STRING g_szRoamableRootFolder;     
     BOOL   g_bLANUCHAPP;
                              
     STRING g_szCurVcredist;    //当前系统和CAD对应的 vcredist 
     STRING g_szSelOutVersion; 	//用户选择的外部版本,例如 AutoCAD 2007,作为检索标示
     STRING g_szInVersion;		//全局内部版本代号    例如 R17.0
     STRING g_szCurVersion;      	//全局当前版本代号    例如 ACAD-201:804
     STRING g_szCustomID;			//全局小版本代号	  例如 2009
     STRING g_szShortID;			//全局短版本号		  例如 09
     CADVERSIONINFO g_CADVerInfo;        	//CAD Base Version info 	  
    
//-------------------------------------------   
 
//
//                                                                           
//  FUNCTION:   CADVerCheckDialog                                            
//  EVENT:		Check Mem CAD Verion Info In order to privide User to Select                                                                         
//  Author:                                                                            
///
#define RES_DIALOG_ID     		13333   // ID of dialog itself
#define RES_VERSIONLIST_ID  	1303    // ID of VersionList
#define RES_PBUT_NEXT         	1   	// ID of Next button 
#define RES_PBUT_CANCEL      	9   	// ID of Cancel button 
#define RES_PBUT_BACK        	12   	// ID of Back button 

prototype CADVerCheckDialog(STRING, STRING);

function CADVerCheckDialog(szTitle, szMsg) 
    STRING  szDlg, szDialogName, szDLLName, szDialog;
    STRING szTempOutVer,szTempInVer,szTempCurVer,szTempCustom;
    STRING  szTemp,szTemp2;
    number  nId, nSdDialog, hInstance, hwndParent, nResult;
    HWND    hwndDlg;
    LIST   	listVerID,listSupportVerID;
    BOOL  	bDone; 
    INT     iCount,i;
begin 
    // Specify a name to identify the custom dialog in this installation. 
    szDlg     = "NewDialog";
    nSdDialog =  RES_DIALOG_ID;
    g_szSelOutVersion="";
    
    // record data produced by this dialog
    if( MODE = SILENTMODE ) then
        return nId;
    endif; 
      
    // ensure general initialization is complete
    if( !bSdInit ) then
        SdInit();
    endif;  
    
    szDialogName = "NewDialog";
    hInstance  = 0;
    szDLLName  = "";
    szDialog   = ""; 
    hwndParent = 0; 
    nResult  = DefineDialog (szDialogName, hInstance, szDLLName, nSdDialog, szDialog, 
                             hwndParent, HWND_INSTALL, 
                             DLG_MSG_STANDARD|DLG_CENTERED);    
   
    listVerID = ListCreate (STRINGLIST);
    listSupportVerID = ListCreate(STRINGLIST); 
    
    if ( nResult = DLG_ERR) then
       bDone = TRUE;
       return -1;
    endif; 
    
    //Initialize CAD Install Version
    iCount = ListCount(g_CADVerInfo.listOutVerID);
    if( iCount<=0 ) then
    	bDone =TRUE;
    	return -1;
    endif;
    
    // Initialize CAD Install Verion in the for loop.
    for i = 0 to (iCount-1)
    	 ListSetIndex(g_CADVerInfo.listOutVerID,i);
    	 ListSetIndex(g_CADVerInfo.listInVerID,i);
    	 ListSetIndex(g_CADVerInfo.listCurVerID,i);
    	 ListSetIndex(g_CADVerInfo.listCustomID,i);
    	 
    	 ListCurrentString (g_CADVerInfo.listOutVerID,szTempOutVer);
    	 ListCurrentString (g_CADVerInfo.listInVerID,szTempInVer);
    	 ListCurrentString (g_CADVerInfo.listCurVerID,szTempCurVer);
    	 ListCurrentString (g_CADVerInfo.listCustomID,szTempCustom);
    	
    	//检查安装盘版本
    	szTemp = SRCDIR^SRC_BIN_FOLDER^DES_BIN_FOLDER+szTempCustom;
    	if (ExistsDir (szTemp) = EXISTS) then
    			ListAddString(listSupportVerID,szTempOutVer,AFTER);    	     
    		if(IsInstallCADVersion(szTempOutVer,szTempInVer,szTempCurVer)) then
    	 			ListAddString(listVerID,szTempOutVer,AFTER);
    	    endif;
    	endif;  
    endfor;
    
    //Get CAD Install Check Count if <=0 return
    iCount = ListCount(listVerID);
    if(iCount<=0) then
        iCount = ListCount(listSupportVerID);
        szTemp = "\n";
        if(iCount>0) then 
          for i = 0 to (iCount-1)
            ListSetIndex(listSupportVerID,i);
            ListCurrentString (listSupportVerID,szTemp2);
            szTemp = szTemp + "\n"+szTemp2;
       	  endfor;
       	  MessageBox ("当前软件支持安装"+szTemp+"版本,\n请选择安装一个版本后,再执行软件安装操作!", SEVERE);  
       	else //严重问题发生
          MessageBox ("软件安装信息缺失,请尽快联系软件提供商!", SEVERE);  
        endif;
       //MessageBox ("请检查系统是否已经安装AutoCAD 2007 以上版本,\n然后再执行软件安装操作!", SEVERE); 
       bDone = TRUE;
       return -1;
     else 
     
     endif;
    	    	
    // Initialize the indicator used to control the while loop. 
    bDone = FALSE;

    // Loop until done. 
    while (!bDone)
                  // Display the dialog and return the next dialog event. 
        nId = WaitOnDialog( szDlg );
        // Respond to the event. .
        
        switch(nId) 
        
            case DLG_INIT: 
  			 	nResult = CtrlSetList (szDialogName, RES_VERSIONLIST_ID,listVerID);
  			     
            case RES_PBUT_NEXT:     // The user clicked the Next button.
                bDone = TRUE; 
                
            case RES_PBUT_BACK:    	// The user clicked the Back button.
                bDone = TRUE; 
                
            case RES_PBUT_CANCEL:   // The user clicked the Cancel button. 
                Do (EXIT);

            case DLG_CLOSE:   
                SdCloseDlg( hwndDlg, nId, bDone );    
                            
    	endswitch; 
    endwhile; 
    
    if(bDone) then 
        nResult =  CtrlGetCurSel (szDialogName, RES_VERSIONLIST_ID, szTempCurVer);
  		if(nResult=0) then 
  			g_szSelOutVersion = szTempCurVer;		    	
  		endif;
    endif;
   

    // Cleanup Dialog
    EndDialog( szDlg );
    ReleaseDialog( szDlg );
    SdUnInit();  

    // record data produced by this dialog
    if( MODE = RECORDMODE ) then   
    endif;

    return nId;
end; 


//
//                                                                           
//  FUNCTION:   OnFirstUIBefore                                            
//                                                                           
//  EVENT:      FirstUIBefore event is sent when installation is run for the first
//              time on given machine. In the handler installation usually displays
//              UI allowing end user to specify installation parameters. After this
//              function returns, FeatureTransferData is called to perform file

//              transfer.
//                                                                           
///
function OnFirstUIBefore()
    number  nResult,nSetupType;
    STRING  szTitle,szMsg,szDir,szPicName;
begin
	   	         
    SHELL_OBJECT_FOLDER = @PRODUCT_NAME;
    szDir = INSTALLDIR;
    
    //检查早期的2009版本以前的安装包信息   
    //UninstallOldVersion("{9D23756A-FF9F-4AB9-85E5-4C1D22D7D53E}");

         
Dlg_Start:
Dlg_SdWelcome:   
	//设置对话框左边的图形: 
	SdInit(); 
 	szPicName = SUPPORTDIR^"LeftView.BMP";
 	DialogSetInfo(DLG_INFO_ALTIMAGE,szPicName,TRUE);
 	
    szTitle = "";
    szMsg   = "";
    nResult = SdWelcome( szTitle, szMsg );
    if (nResult = BACK) goto Dlg_Start;  
Dlg_License2:
	//设置对话框左边的图形: 
	SdInit(); 
 	szPicName = SUPPORTDIR^"LeftView.BMP";
 	DialogSetInfo(DLG_INFO_ALTIMAGE,szPicName,TRUE); 
 	 
   // Display the SdLicense2 dialog. 
   szTitle = "";
   szMsg   = "";
   if (SdLicense2 (szTitle, "", "", LICENSE_PATH, FALSE) = BACK) goto Dlg_SdWelcome; 
   
Dlg_CADVerCheckDialog: 
	szTitle = "";
	szMsg = "";
	nResult = CADVerCheckDialog( szTitle, szMsg );
	if (nResult = BACK) goto Dlg_License2;
	if(nResult = -1)then
	     abort;
	endif;
	
Dlg_SdAskDestPath:  
	//设置对话框上面的图形: 
	SdInit();
 	szPicName = SUPPORTDIR^"LeftView.BMP";
 	DialogSetInfo(DLG_INFO_ALTIMAGE,szPicName,TRUE);
 	
    szTitle = "";
    szMsg   = "";
    nResult = SdAskDestPath( szTitle, szMsg, szDir, 0 );   
    if (nResult = BACK) goto Dlg_License2;
    
    //检测路径是否合法
    if (Is(VALID_PATH,szDir) == FALSE) then     
    	MessageBox("请检查路径是否合法!",INFORMATION);
    	goto Dlg_SdAskDestPath;    
    endif;  
    
    if (SYSINFO.bIsWow64) then    
    	szMsg = GetUpperDir(szDir);     
    	if (szMsg == PROGRAMFILES64 || szDir == PROGRAMFILES64) then
    		MessageBox("非64位软件不能安装到此路径,请重新选择.",INFORMATION);
    		goto Dlg_SdAskDestPath;
    	endif; 
    endif;              
    
    INSTALLDIR = szDir;
    
    Enable(STATUSEX);       
    
    //初始化安装版本安装环境,路径、版本信息等
    if(!InitSelectVerionInstallPara(g_szSelOutVersion)) then
      abort; 
    endif;
    return 0;
end; 


//---------------------------------------------------------------------------                                                                        
//     
//   GetUpperDir(STRING)
//    获取当前目录的上一级目录  
//    如 srcDir : C:\Program Files\TestDir
//    返回 C:\Program Files\
//---------------------------------------------------------------------------
function string GetUpperDir(srcDir)
    NUMBER upperstrlen; 
    string returnDir,tempDir;
begin 
    returnDir = "";
    tempDir = srcDir;   
    while (StrFind(tempDir,"\\")>-1)
        StrSub(tempDir,tempDir,StrFind(tempDir,"\\")+1,StrLength(tempDir)-StrFind(tempDir,"\\"));
    endwhile;   
    upperstrlen = StrLength(tempDir);
    StrSub(returnDir,srcDir,0,StrLength(srcDir)-upperstrlen-1);  
    returnDir = returnDir + "\\";
    return returnDir;
end;


//
//
//  FUNCTION:   InitCADVerInfo()
//
//  EVENT:      初始化CAD的基础版本信息数据
//  Author:    
//
function BOOL InitCADVerInfo()
begin
	 g_CADVerInfo.listOutVerID = ListCreate (STRINGLIST); 		//CAD Outside Verion Name    AutoCAD 2007
	 g_CADVerInfo.listInVerID  = ListCreate (STRINGLIST);		//CAD Inside Verion Name     R17.0
	 g_CADVerInfo.listCurVerID = ListCreate (STRINGLIST);        //CAD Curtent Verion Name 	 ACAD-201:804
	 g_CADVerInfo.listCustomID = ListCreate (STRINGLIST);        //CAD  Custom Version name	 2009
	 g_CADVerInfo.listShortID = ListCreate (STRINGLIST);        //CAD  Short Version name	 09
                
     if (SYSINFO.bIsWow64) then   
/*     	//!AutoCAD 2009x64 
	    ListAddString (g_CADVerInfo.listOutVerID, "AutoCAD 2009", AFTER);
	    ListAddString (g_CADVerInfo.listInVerID	, "R17.2", AFTER);
	    ListAddString (g_CADVerInfo.listCurVerID, "ACAD-7001:804", AFTER);
	    ListAddString (g_CADVerInfo.listCustomID, "2009-x64", AFTER);
	    ListAddString (g_CADVerInfo.listShortID, "09", AFTER);   
	    
	    //!AutoCAD 2010x64 
	    ListAddString (g_CADVerInfo.listOutVerID, "AutoCAD 2010", AFTER);
	    ListAddString (g_CADVerInfo.listInVerID	, "R18.0", AFTER);
	    ListAddString (g_CADVerInfo.listCurVerID, "ACAD-8001:804", AFTER);
	    ListAddString (g_CADVerInfo.listCustomID, "2010-x64", AFTER);
	    ListAddString (g_CADVerInfo.listShortID, "10", AFTER);    
	    
	     //!AutoCAD 2011x64 
	    ListAddString (g_CADVerInfo.listOutVerID, "AutoCAD 2011", AFTER);
	    ListAddString (g_CADVerInfo.listInVerID	, "R18.1", AFTER);
	    ListAddString (g_CADVerInfo.listCurVerID, "ACAD-9001:804", AFTER);
	    ListAddString (g_CADVerInfo.listCustomID, "2011-x64", AFTER);
	    ListAddString (g_CADVerInfo.listShortID, "11", AFTER);    
	    
	    //!AutoCAD 2012x64 
	    ListAddString (g_CADVerInfo.listOutVerID, "AutoCAD 2012", AFTER);
	    ListAddString (g_CADVerInfo.listInVerID	, "R18.2", AFTER);
	    ListAddString (g_CADVerInfo.listCurVerID, "ACAD-A001:804", AFTER);
	    ListAddString (g_CADVerInfo.listCustomID,  "2012-x64", AFTER);
	    ListAddString (g_CADVerInfo.listShortID, "12", AFTER);    
	    
	    //!AutoCAD 2013x64 
	    ListAddString (g_CADVerInfo.listOutVerID, "AutoCAD 2013", AFTER);
	    ListAddString (g_CADVerInfo.listInVerID	, "R19.0", AFTER);
	    ListAddString (g_CADVerInfo.listCurVerID, "ACAD-B001:804", AFTER);
	    ListAddString (g_CADVerInfo.listCustomID,  "2013-x64", AFTER);
	    ListAddString (g_CADVerInfo.listShortID, "13", AFTER);
	    
	    //!AutoCAD 2014x64 
	    ListAddString (g_CADVerInfo.listOutVerID, "AutoCAD 2014", AFTER);
	    ListAddString (g_CADVerInfo.listInVerID	, "R19.1", AFTER);
	    ListAddString (g_CADVerInfo.listCurVerID, "ACAD-D001:804", AFTER);
	    ListAddString (g_CADVerInfo.listCustomID,  "2014-x64", AFTER);
	    ListAddString (g_CADVerInfo.listShortID, "14", AFTER);                           */                 
	    
	    //!AutoCAD MAP 3D 2016x64 
	    ListAddString (g_CADVerInfo.listOutVerID, "AutoCAD Map 3D 2016", AFTER);
	    ListAddString (g_CADVerInfo.listInVerID	, "R20.1", AFTER);
	    ListAddString (g_CADVerInfo.listCurVerID, "ACAD-F002:409", AFTER);
	    ListAddString (g_CADVerInfo.listCustomID, "2016-x64", AFTER);
	    ListAddString (g_CADVerInfo.listShortID, "16", AFTER);   
     
/*     else
	     //!AutoCAD 2007 
	     ListAddString (g_CADVerInfo.listOutVerID, "AutoCAD 2007", AFTER);
	     ListAddString (g_CADVerInfo.listInVerID	, "R17.0", AFTER);
	     ListAddString (g_CADVerInfo.listCurVerID, "ACAD-5001:804", AFTER);
	     ListAddString (g_CADVerInfo.listCustomID, "2007", AFTER);
	     ListAddString (g_CADVerInfo.listShortID, "07", AFTER);
	     
	      //!AutoCAD 2008 
	     ListAddString (g_CADVerInfo.listOutVerID, "AutoCAD 2008", AFTER);
	     ListAddString (g_CADVerInfo.listInVerID	, "R17.1", AFTER);
	     ListAddString (g_CADVerInfo.listCurVerID, "ACAD-6001:804", AFTER);
	     ListAddString (g_CADVerInfo.listCustomID, "2008", AFTER);
	     ListAddString (g_CADVerInfo.listShortID, "08", AFTER);
	     
	      //!AutoCAD 2009 
	    ListAddString (g_CADVerInfo.listOutVerID, "AutoCAD 2009", AFTER);
	    ListAddString (g_CADVerInfo.listInVerID	, "R17.2", AFTER);
	    ListAddString (g_CADVerInfo.listCurVerID, "ACAD-7001:804", AFTER);
	    ListAddString (g_CADVerInfo.listCustomID, "2009", AFTER);
	    ListAddString (g_CADVerInfo.listShortID, "09", AFTER);   
	                              	    
	      //!AutoCAD 2010 
	    ListAddString (g_CADVerInfo.listOutVerID, "AutoCAD 2010", AFTER);
	    ListAddString (g_CADVerInfo.listInVerID	, "R18.0", AFTER);
	    ListAddString (g_CADVerInfo.listCurVerID, "ACAD-8001:804", AFTER);
	    ListAddString (g_CADVerInfo.listCustomID, "2010", AFTER);
	    ListAddString (g_CADVerInfo.listShortID, "10", AFTER);
	                                               	     
	      //!AutoCAD 2011 
	    ListAddString (g_CADVerInfo.listOutVerID, "AutoCAD 2011", AFTER);
	    ListAddString (g_CADVerInfo.listInVerID	, "R18.1", AFTER);
	    ListAddString (g_CADVerInfo.listCurVerID, "ACAD-9001:804", AFTER);
	    ListAddString (g_CADVerInfo.listCustomID, "2011", AFTER);
	    ListAddString (g_CADVerInfo.listShortID, "11", AFTER);   
	                            	                               	     
	     //!AutoCAD 2012 
	    ListAddString (g_CADVerInfo.listOutVerID, "AutoCAD 2012", AFTER);
	    ListAddString (g_CADVerInfo.listInVerID	, "R18.2", AFTER);
	    ListAddString (g_CADVerInfo.listCurVerID, "ACAD-A001:804", AFTER);
	    ListAddString (g_CADVerInfo.listCustomID,  "2012", AFTER);
	    ListAddString (g_CADVerInfo.listShortID, "12", AFTER);     
	                             	                                	    
	     //!AutoCAD 2013 
	    ListAddString (g_CADVerInfo.listOutVerID, "AutoCAD 2013", AFTER);
	    ListAddString (g_CADVerInfo.listInVerID	, "R19.0", AFTER);
	    ListAddString (g_CADVerInfo.listCurVerID, "ACAD-B001:804", AFTER);
	    ListAddString (g_CADVerInfo.listCustomID,  "2013", AFTER);
	    ListAddString (g_CADVerInfo.listShortID, "13", AFTER); 
	                             	                                	                    
	     //!AutoCAD 2014 
	    ListAddString (g_CADVerInfo.listOutVerID, "AutoCAD 2014", AFTER);
	    ListAddString (g_CADVerInfo.listInVerID	, "R19.1", AFTER);
	    ListAddString (g_CADVerInfo.listCurVerID, "ACAD-D001:804", AFTER);
	    ListAddString (g_CADVerInfo.listCustomID,  "2014", AFTER);
	    ListAddString (g_CADVerInfo.listShortID, "14", AFTER);          */
	endif;   
	              
end;
//
//
//  FUNCTION:   InitCADVerInfo
//
//  EVENT:      是否已经包含CAD指定版本注册信息
//  Author:    
//
function BOOL IsInstallCADVersion( szOutVer, szInVer, szCurVer)
STRING szKey,szNumName,szNumValue;   //szKey表示键,szNumName表示字符,svNumValue表示数值
number nvType,nvSize;
begin   
    if (SYSINFO.bIsWow64) then
    	REGDB_OPTIONS = REGDB_OPTIONS | REGDB_OPTION_WOW64_64KEY;
    endif;
	 
	if(RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE) <0) then 
		   return FALSE;
	endif;
	
	nvType = REGDB_STRING;
	szKey	= "SOFTWARE\\Autodesk\\AutoCAD\\"+szInVer+"\\"+szCurVer;   
    szNumName ="AcadLocation"; 
	
	if (RegDBKeyExist (szKey) < 0) then   
        	return FALSE;	    
	else 
		if (RegDBGetKeyValueEx (szKey, szNumName, nvType, szNumValue, nvSize) < 0) then
		 	return FALSE; 
		endif;
	endif;  
	
	if (SYSINFO.bIsWow64) then
    	REGDB_OPTIONS = REGDB_OPTIONS & ~REGDB_OPTION_WOW64_64KEY;
    endif;
		
	return TRUE; 
end; 

//
//
//  FUNCTION:   CreateUninstShortCut()
// 
//  EVENT:      创建删除快捷方式
//  Author:    
//
 function BOOL CreateUninstShortCut()
 string szmsg1,szmsg2,szfilename;
 INT nresult;
 begin 
 	//创建删除快捷方式    /UNINSTALL
	szfilename = UNINSTALL_STRING +" /removeonly";
	nresult = StrFind(szfilename,".exe");
	if nresult >=0 then
		StrSub(szmsg1,szfilename,0,nresult + 4);
		StrSub(szmsg2,szfilename,nresult + 4,200);
		LongPathToQuote(szmsg1, FALSE );
		LongPathToQuote(szmsg2, FALSE );
		szfilename = "\"" + szmsg1 + "\"" +szmsg2;
	endif;
	
	if(AddFolderIcon(FOLDER_PROGRAMS^PRODOUCT_NAME,"卸载"+PRODOUCT_NAME,szfilename,WINDIR,"",0,"",REPLACE)!=0) then
		return FALSE;
	endif;
	
	return TRUE;
 end;  
//
//
//  FUNCTION:   LaunchAppAcad()
// 
//  EVENT:      启动应用程序
//  Author:    
// 
function BOOL LaunchAppAcad()
string  AppTarget,szDocFile;
begin
	AppTarget=TARGETDIR^LANUCH_FOLDER;
	if(FindFile(AppTarget, LANUCH_APPNAME, szDocFile)=0) then
		if (LaunchApp (AppTarget^LANUCH_APPNAME, "") < 0) then
			//MessageBox ("Unable to launch "+serviceTarget+".", SEVERE);
		endif;
	endif;
end; 
//
//
//  FUNCTION:   GetCADVerInfo(szOutVer, szInVer, szCurVer,szCustomID,szShortID)
// 【IN】szOutVer 【out】 szInVer 【out】szCurVer
//  EVENT:      得到CAD版本信息配置数据
//  Author:   
//
function BOOL GetCADVerInfo(szOutVer, szInVer, szCurVer,szCustomID,szShortID)
STRING szTempOutVer,szTempInVer,szTempCurVer,szTempCustomID,szTempShortID;
INT iCount,i;
BOOL bRet;
begin
	szInVer 	= "";
	szCurVer	=""; 
	bRet 		= FALSE;
	 
	iCount = ListCount(g_CADVerInfo.listOutVerID);
	if(iCount<=0) then
		return FALSE; 
	endif;  
	
	for i=0 to (iCount-1)
		 ListSetIndex(g_CADVerInfo.listOutVerID,i);
    	 ListSetIndex(g_CADVerInfo.listInVerID,i);
    	 ListSetIndex(g_CADVerInfo.listCurVerID,i);
    	 ListSetIndex(g_CADVerInfo.listCustomID,i);
    	 ListSetIndex(g_CADVerInfo.listShortID,i);
    	 
    	 ListCurrentString (g_CADVerInfo.listOutVerID,szTempOutVer);
    	 ListCurrentString (g_CADVerInfo.listInVerID,szTempInVer);
    	 ListCurrentString (g_CADVerInfo.listCurVerID,szTempCurVer);
    	 ListCurrentString (g_CADVerInfo.listCustomID,szTempCustomID);
    	 ListCurrentString (g_CADVerInfo.listShortID,szTempShortID);
    		 
    	if( StrCompare (szOutVer, szTempOutVer) = 0) then
    		 szInVer = szTempInVer;
    		 szCurVer= szTempCurVer;
    		 szCustomID = szTempCustomID;
    		 szShortID =  szTempShortID;
    		 return TRUE; 
    	endif;
	endfor;
	
	return FALSE;
	
end;

// 初始化vcredist到 g_szCurVcredist
function BOOL InitVcredist(szOutVer)
begin
/*	 if(szOutVer == "AutoCAD 2007" || szOutVer == "AutoCAD 2008") then
	 	g_szCurVcredist = VCREDIST_x86_2005; 
	 endif;
	 if(szOutVer == "AutoCAD 2009") then
	 	if(!SYSINFO.bIsWow64) then 
	 	    g_szCurVcredist = 	VCREDIST_x86_2005;
	 	else
	 		g_szCurVcredist = 	VCREDIST_x64_2005;
	 	endif;     
	 endif;
	 if(szOutVer == "AutoCAD 2010" || szOutVer == "AutoCAD 2011") then
	 	if(!SYSINFO.bIsWow64) then 
	 		g_szCurVcredist = 	VCREDIST_x86_2008;
	 	else
	 	    g_szCurVcredist = 	VCREDIST_x64_2008;
	 	endif;     
	 endif;
	 if(szOutVer == "AutoCAD 2012") then
	 	if(!SYSINFO.bIsWow64) then 
	 		g_szCurVcredist = 	VCREDIST_x86_2010;
	 	else
	 	    g_szCurVcredist = 	VCREDIST_x64_2010;
	 	endif;     
	 endif;                         */
	 if(szOutVer == "AutoCAD Map 3D 2016") then
	 	if(!SYSINFO.bIsWow64) then 
	 		g_szCurVcredist = 	VCREDIST_x86_2016;
	 	else
	 	    g_szCurVcredist = 	VCREDIST_x64_2016;
	 	endif;     
	 endif; 
	 
	 if (g_szCurVcredist == "") then
	 	return FALSE;
	 else
	 	return TRUE;
	 endif;
	 
end;
//
//
//  FUNCTION:   InitSelectVerionInstallPara(STRING)
//  【IN】szOutVer
//  EVENT:      初始化用户选择CAD版本安装变量
//  Author:    
//
function BOOL InitSelectVerionInstallPara(szOutVer)
begin  
  
  	//Convert OutVersion to InVersion,Current Verion
	if(!GetCADVerInfo(szOutVer,g_szInVersion,g_szCurVersion,g_szCustomID,g_szShortID)) then 
		return FALSE;
	endif;
	
	//get search path
	if(!SearchCADPath(g_szInVersion,g_szCurVersion,g_ACADPath, g_ACADSearchPath)) then 
		return FALSE;
	endif;
	
	//get Roamable path
	if(!SearchRoamableRootFolder(g_szInVersion,g_szCurVersion,g_szRoamableRootFolder)) then 
		return FALSE;
	endif;           
	
	//初始化vcredist
	if(!InitVcredist(szOutVer)) then 
		return FALSE;
	endif; 
  
   return TRUE;
end;
				
//
//
//  FUNCTION:   SearchCADPath
// 【IN】szInVersion,【IN】szCurVersion,【out】szACADPath,【out】szACADSearchPath
//  EVENT:      查找CAD路径
//
//
function BOOL SearchCADPath(szInVersion,szCurVersion,szACADPath,szACADSearchPath)
string szKey,szNumName,svNumValue;   //szKey表示键,szNumName表示字符,svNumValue表示数值
int nns; 
number nvType ,nvSize;
begin     
		if (SYSINFO.bIsWow64) then
    		REGDB_OPTIONS = REGDB_OPTIONS | REGDB_OPTION_WOW64_64KEY;
    	endif;
    
		if (RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE)<0) then
			return FALSE; 
		endif;
			 
		nvType = REGDB_STRING;  
		szKey = "Software\\Autodesk\\AutoCAD\\"+szInVersion+"\\"+szCurVersion;
		szNumName ="AcadLocation"; 
			
		if (RegDBKeyExist (szKey) < 0) then   
        	return FALSE;	    
		else 
			if (RegDBGetKeyValueEx (szKey, szNumName, nvType, svNumValue,nvSize) < 0) then
				return FALSE;
			endif;
		endif;  
		
		if (SYSINFO.bIsWow64) then
    		REGDB_OPTIONS = REGDB_OPTIONS & ~REGDB_OPTION_WOW64_64KEY;
    	endif;
		
		szACADPath		 = svNumValue; 
		szACADSearchPath = svNumValue;
		return TRUE;   	
end;           

function RecursionModifyFileData( objNode, szOldStr,szNewStr )
	STRING szValue;             
	NUMBER nCount,i,nRet;   
	OBJECT ObjList,subNode; 
begin                                   
	if (IsObject(objNode)) then   
		//修改自身属性
		set ObjList = objNode.Attributes;
		nCount = ObjList.length();   
		for i = 0 to nCount step 1
         	set subNode = ObjList(i);
			if (IsObject(subNode)) then 
				szValue = subNode.Text;
				nRet = StrReplace(szValue, szOldStr, szNewStr, 0);
				if (nRet > ISERR_SUCCESS) then
					subNode.Text = szValue;   
				endif;                      
			endif;
		endfor;
	
		//修改子项
		if (objNode.hasChildNodes()) then
			set ObjList = objNode.childNodes;
			nCount = ObjList.length();   
			for i = 0 to nCount step 1
	         	set subNode = ObjList(i);
				RecursionModifyFileData(subNode, szOldStr, szNewStr); 
			endfor;
		endif; 
	endif;
end; 


function ModifyFileData(szFileName,szOldStr,szNewStr)  
	STRING szFilePath;          
	NUMBER nRet; 
	OBJECT objXml,objNode; 
begin                                  
	szFilePath = szFileName;  
		 
	nRet = Is(FILE_EXISTS, szFilePath);
	if (nRet = TRUE) then   
		set objXml = CreateObject("MSXML.DOMDocument");//创建一个DOM对象    
		if (IsObject(objXml)) then  
			objXml.async = FALSE; 
            objXml.Load(szFilePath);     

            set objNode = objXml.documentElement; 
            RecursionModifyFileData(objNode, szOldStr, szNewStr);                                 

			objXml.save(szFilePath); //保存  
    	endif;
	endif;
end; 


//
//
//  FUNCTION:   SearchRoamableRootFolder(STRING, STRING,BYREF STRING)
//  【IN】szInVer,【IN】szCurVer,【out】szRoamableRootFolder
//  EVENT:      得到CAD版本的根路径
//  Author:    
//
function BOOL SearchRoamableRootFolder(szInVer, szCurVer,szRoamableRootFolder)
STRING szKey,szNumName,szNumValue;   //szKey表示键,szNumName表示字符,svNumValue表示数值
number nvType ,nvSize;
begin   
	if (SYSINFO.bIsWow64) then
    	REGDB_OPTIONS = REGDB_OPTIONS | REGDB_OPTION_WOW64_64KEY;
    endif;

	RegDBSetDefaultRoot(HKEY_CURRENT_USER);
	szKey = "Software\\Autodesk\\AutoCAD\\"+szInVer+"\\"+szCurVer;
	szNumName ="RoamableRootFolder";
	if(RegDBGetKeyValueEx (szKey, szNumName, nvType, szNumValue, nvSize) < 0) then
		return FALSE;
	endif;   
	
	if (SYSINFO.bIsWow64) then
    	REGDB_OPTIONS = REGDB_OPTIONS & ~REGDB_OPTION_WOW64_64KEY;
    endif;
	  
	szRoamableRootFolder =   szNumValue;
	return TRUE;
end;            


//
//
//  FUNCTION:   SetupFolders()
//
//  EVENT:      在桌面和程序组创建快捷方式
//
///
function BOOL SetupFolders()

NUMBER nResult;     
STRING szFolderDir,svResult,szProgramFolder,szProgram,szCommandLine,szWorkingDir,szIconPath,szShortCutKey; 
INT nIcon,nFlag;
begin    

Disable(LOGGING);
Enable(LOGGING);

szProgramFolder = FOLDER_PROGRAMS^SHELL_OBJECT_FOLDER;//建立程序组或快捷方式的位置

szProgram = INSTALLDIR^"\\dist\\LiveUpdate.exe"; //可执行文件名

//g_szParam = "/p HHWY10KV3 /nologo";

LongPathToQuote (szProgram, TRUE);//合并路径

szCommandLine = szProgram; //生成命令行

szWorkingDir = INSTALLDIR^"\\dist";//工作路径

szIconPath = INSTALLDIR^"\\Support\\setup.ico";

nIcon = 0;

szShortCutKey = "";

nFlag = REPLACE;

AddFolderIcon (szProgramFolder, PRODOUCT_NAME, szCommandLine, szWorkingDir, szIconPath, nIcon, szShortCutKey, nFlag);

szProgramFolder = FOLDER_DESKTOP;

LongPathToQuote(szCommandLine, TRUE);

AddFolderIcon (szProgramFolder, PRODOUCT_NAME, szCommandLine, szWorkingDir, szIconPath, nIcon, szShortCutKey, nFlag);
  
 
return TRUE;
end;

///
//
//  FUNCTION:   WriteReg()
//
//  EVENT:      向注册表中写入定制好的CAD模板信息。   
//
///
function BOOL WriteReg()
string szKey,szNumName,svNumValue,szMenuName;   //szKey表示键,szNumName表示字符,svNumValue表示数值
number nvType ,nvSize;  
begin    
		if (SYSINFO.bIsWow64) then
    		REGDB_OPTIONS = REGDB_OPTIONS | REGDB_OPTION_WOW64_64KEY;
    	endif;
       
		if RegDBSetDefaultRoot(HKEY_CURRENT_USER) <0 then 
			MessageBox("安装失败[设置注册表根键失败]!",INFORMATION); 
			return FALSE;
		endif;
		
		szKey ="Software\\Autodesk\\AutoCAD\\"+g_szInVersion+"\\"+g_szCurVersion+"\\Profiles\\"+PROFILES_NAME+"\\General";
		
		szNumName ="ACAD";
		svNumValue=g_szRoamableRootFolder+";"+g_szRoamableRootFolder+"\support;"+g_ACADSearchPath+"\\;"+g_ACADSearchPath+"\\support;"+g_ACADSearchPath+"\\fonts;"+g_ACADSearchPath+"\\help;"+g_ACADSearchPath+"\\support\\color;";
		svNumValue=svNumValue+INSTALLDIR+"\Bin\\Arx;"+INSTALLDIR+"\Font;"+INSTALLDIR+"\Menu;";
		nvType = REGDB_STRING;
		if (RegDBSetKeyValueEx (szKey, szNumName, nvType, svNumValue,nvSize) < 0)	then
			MessageBox("安装失败[设置注册表失败]!",SEVERE);
			return FALSE;
		endif; 
		
		szKey ="Software\\Autodesk\\AutoCAD\\"+g_szInVersion+"\\"+g_szCurVersion+"\\Profiles\\"+PROFILES_NAME+"\\Variables";
		    
		// 设置信任路径    
		szNumName ="TRUSTEDPATHS";
		svNumValue=INSTALLDIR+"\Bin\\Arx;";
		nvType = REGDB_STRING;
		if (RegDBSetKeyValueEx (szKey, szNumName, nvType, svNumValue,nvSize) < 0)	then
			MessageBox("安装失败[设置注册表失败]!",SEVERE);
			return FALSE;
		endif;
		
		szKey ="Software\\Autodesk\\AutoCAD\\"+g_szInVersion+"\\"+g_szCurVersion+"\\Profiles\\"+PROFILES_NAME+"\\General Configuration";
		
		szNumName ="MenuFile";
		//特殊处理
		
		if(g_szInVersion=="R17.0" || g_szInVersion=="R17.1")then 
			szMenuName = "menu_"+g_szShortID+"_jk_t";
		else
		    szMenuName = "menu_"+g_szShortID+"_jk_r";
		endif;	
		svNumValue=INSTALLDIR+"\Menu\\"+szMenuName;
		
		nvType = REGDB_STRING;
		if (RegDBSetKeyValueEx (szKey, szNumName, nvType, svNumValue,nvSize) < 0) then
			MessageBox("安装失败[设置注册表失败]!",SEVERE);
			return FALSE;
		endif;
		
		if (RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE) < 0) then 
			MessageBox("安装失败[设置注册表根键失败]!",INFORMATION); 
			return FALSE;
		endif;
		
		szKey ="SOFTWARE\\XX客户端\\1.00";
		szNumName ="InstallDir";
		svNumValue=INSTALLDIR;
		nvType = REGDB_STRING;
		if (RegDBSetKeyValueEx (szKey, szNumName, nvType, svNumValue,nvSize) < 0) then
			MessageBox("安装失败[设置注册表失败]!",SEVERE);
			return FALSE;
		endif; 
			
		if RegDBSetDefaultRoot(HKEY_CLASSES_ROOT) <0 then 
			MessageBox("安装失败[设置注册表根键失败]!",INFORMATION); 
			return FALSE;
		endif;  
		
		szKey ="\\hhwypwsj";
		szNumName ="";
		svNumValue="hhwy";
		nvType = REGDB_STRING;
		if (RegDBSetKeyValueEx (szKey, szNumName, nvType, svNumValue,nvSize) < 0) then
			MessageBox("安装失败[设置注册表失败]!",SEVERE);
			return FALSE;
		endif;
		
		szKey ="\\hhwypwsj";
		szNumName ="URL Protocol";
		svNumValue=":"+INSTALLDIR+"\Support\\HHShellRun\\HHShellRun.exe";
		nvType      = REGDB_STRING;
		if (RegDBSetKeyValueEx (szKey, szNumName, nvType, svNumValue,nvSize) < 0) then
			MessageBox("安装失败[设置注册表失败]!",SEVERE);
			return FALSE;
		endif;
		
		szKey ="\\hhwypwsj\\DefaultIcon";
		szNumName ="";
		svNumValue=INSTALLDIR+"\Support\\HHShellRun\\HHShellRun.exe";
		nvType      = REGDB_STRING;
		if (RegDBSetKeyValueEx (szKey, szNumName, nvType, svNumValue,nvSize) < 0) then
			MessageBox("安装失败[设置注册表失败]!",SEVERE);
			return FALSE;
		endif;
		
		szKey ="\\hhwypwsj\\shell\\open\\command";
		szNumName ="";
		svNumValue=INSTALLDIR+"\Support\\HHShellRun\\HHShellRun.exe %1";
		nvType      = REGDB_STRING;
		if (RegDBSetKeyValueEx (szKey, szNumName, nvType, svNumValue,nvSize) < 0) then
			MessageBox("安装失败[设置注册表失败]!",SEVERE);
			return FALSE;
		endif;  
		
		if (SYSINFO.bIsWow64) then
    		REGDB_OPTIONS = REGDB_OPTIONS & ~REGDB_OPTION_WOW64_64KEY;
    	endif;
		
	return TRUE;						
end;  

///
//
//  FUNCTION:   InstallDog()
//
//  EVENT:      安装加密狗驱动和服务   
//
///
function BOOL InstallDogDirver()
STRING szDogPath,szModel,svResult;
number nvResult;
begin  
// 安装加密狗驱动和服务
if (!MAINTENANCE) then    
	Delay(1);
	szDogPath =  INSTALLDIR^"\\Support\\Drivers\\Drivers\\InstWiz3.exe"; 
	//INSTALLDIR^"\\Support\\Drivers\\Drivers\\InstWiz3.exe";    锁打包 
	//INSTALLDIR^"\\Support\\Drivers\\hdd32NC.exe";   锁打包
     
    szModel = "WINXPSP2";
	//检测当前的操作系统
	GetSystemInfo(WINMINOR, nvResult,svResult);
	
	//Vista
	if(svResult =="6.0" ) then
		SetCompatModel(szDogPath,szModel); 
	endif;
	//Win7
	if(svResult =="6.1" ) then
		SetCompatModel(szDogPath,szModel);  
	endif; 
	// Win8/8.1   
	if(svResult == "6.2") then
		SetCompatModel(szDogPath,szModel);  
	endif;

    if(LaunchAppAndWait (szDogPath ,"",LAAW_OPTION_WAIT)<0)then
	    MessageBox("安装加密锁驱动出错!请手动安装。",SEVERE); 
    endif;                                              

endif;

end;

//
//
//  FUNCTION:   CopyVersionFiles()
//  【RETURN】 
//  EVENT:      拷贝目录数据
//  Author:   
//

function BOOL CopyVersionFiles()
STRING szSrcDir,szDesDir,szBinName;
begin
	//版本名称目录
	szBinName = DES_BIN_FOLDER+g_szCustomID; 
	szSrcDir = SRCDIR^SRC_BIN_FOLDER^szBinName;
	szDesDir = INSTALLDIR^DES_BIN_FOLDER;
	if (XCopyFile  ( szSrcDir^ "*.*", szDesDir ^ "*.*",INCLUDE_SUBDIR) != 0) then 
		return FALSE;
	endif;
	
    	//dist目录
    	szSrcDir = SRCDIR^SRC_DIST_FOLDER^"dist_x86";
    	szDesDir = INSTALLDIR^DES_DIST_FOLDER;
    	if (SYSINFO.bIsWow64) then   
    		szSrcDir = SRCDIR^SRC_DIST_FOLDER^"dist_x64";
    	endif;
      
	if (XCopyFile  ( szSrcDir^ "*.*", szDesDir ^ "*.*",INCLUDE_SUBDIR) != 0) then 
    		return FALSE;
    	endif;
    
	return TRUE;
end; 


//
//
//  FUNCTION:   RegisterDll()
//  【RETURN】 
//  EVENT:      手工注册必要的dll--采用静默式注
//  Author:    
//
function BOOL RegisterDll()
string szRegPath;
begin
 	 szRegPath =TARGETDIR^REGISTER_DLLDIR;
     if (LongPathToShortPath (szRegPath) == 0) then      	
     	LaunchAppAndWait (szRegPath ,"",LAAW_OPTION_HIDDEN|LAAW_OPTION_WAIT); 
	endif;	  
	return TRUE;
end; 


//
//
//  FUNCTION:   SetCompatModel(STRING,STRING)
// 【IN】szAppPath路径,szModel 【RETURN】  BOOL 
//  EVENT:      设置程序为兼容模式
//  Author:   
//
 function BOOL SetCompatModel(szAppPath,szModel)
 STRING szKey;
 number nvType,nvSize;
 begin     
    	
		if RegDBSetDefaultRoot(HKEY_CURRENT_USER) <0 then 
			return FALSE;
		endif;
		
		szKey ="Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers";
		nvType = REGDB_STRING;
		if (RegDBSetKeyValueEx (szKey,szAppPath, nvType, szModel,nvSize) < 0)	then
			MessageBox("安装失败[设置注册表失败]!",SEVERE);
			return FALSE;
		endif;  
		
		if (SYSINFO.bIsWow64) then
    		REGDB_OPTIONS = REGDB_OPTIONS & ~REGDB_OPTION_WOW64_64KEY;
    	endif;
 
 end;                  
//
//
//  FUNCTION:   UninstallFiles()
//  【RETURN】   BOOL
//  EVENT:      注册必要的dll
//  Author:    
//
function BOOL UninstallFiles()
begin
   
   //删除安装文件信息  
   DeleteProgramFolder(PRODOUCT_NAME);
   DeleteFolderIcon (FOLDER_DESKTOP,PRODOUCT_NAME);
   //DeleteProgramFolder ( TARGETDIR ); 动态链接时,无版本文件测试发现删除不干净 
   DeleteDir(TARGETDIR^DES_BIN_FOLDER,ALLCONTENTS);
   DeleteDir(TARGETDIR^DES_BIN_FOLDER,ONLYDIR);
  
   DeleteDir(TARGETDIR^DES_PRJ_FOLDER,ALLCONTENTS);
   DeleteDir(TARGETDIR^DES_PRJ_FOLDER,ONLYDIR);  
   
   DeleteDir(TARGETDIR^DES_MENU_FOLDER,ALLCONTENTS);
   DeleteDir(TARGETDIR^DES_MENU_FOLDER,ONLYDIR);
       
   
   //删除安装文件信息 
	DeleteDir(ProgramFilesFolder+"//InstallShield Installation Information//{"+PRODUCT_GUID +"}",ALLCONTENTS);  
	DeleteDir(ProgramFilesFolder+"//InstallShield Installation Information//{"+PRODUCT_GUID +"}",ONLYDIR); 
end;

//
//
//  FUNCTION:   WindowsUnstallInfo( szGUID)
//  【RETURN】  BOOL
//  EVENT:      检查是否已经安装过某个软件信息,
//  Author:    
//
function BOOL WindowsUnstallInfo( szGUID)
STRING  UNINSTALL_REG;
STRING  szNumName,szUnInstallString;
NUMBER  nType,nSize;
begin

	if (SYSINFO.bIsWow64) then
    	REGDB_OPTIONS = REGDB_OPTIONS | REGDB_OPTION_WOW64_64KEY;
    endif;                 
    
	RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE);
	UNINSTALL_REG = "\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"+szGUID;
	nType = REGDB_STRING;
	
	RegDBGetKeyValueEx(UNINSTALL_REG,szNumName,nType,szUnInstallString,nSize); //获取卸载脚本
    if(RegDBKeyExist(UNINSTALL_REG)>0) then
    	return TRUE;
    endif;
           
	if (SYSINFO.bIsWow64) then
    	REGDB_OPTIONS = REGDB_OPTIONS & ~REGDB_OPTION_WOW64_64KEY;
    endif;
               
	return FALSE;
	
end; 

//
//
//  FUNCTION:   InstallSoftSilent( szAppDir, szAppName)
//  【RETURN】  BOOL 
//  EVENT:      检查是否已经安装过某个软件信息,
//  Author:    
//
 function BOOL InstallSoftSilent( szAppDir, szAppName)
 STRING szResult,szTemp;
 INT	nResult; 
 begin 
 	 //先查找文件,如果查找不到,需要进行提示
 	 if (FindFile(szAppDir,szAppName,szResult) < 0) then
 	  	 return FALSE;
 	 else
        Delay(1); 
         szTemp =szAppDir^szAppName;
         
         //需要转换为短路径
         if (LongPathToShortPath (szTemp) == 0) then
            nResult=LaunchAppAndWait(szTemp," /qd ",LAAW_OPTION_WAIT|LAAW_OPTION_HIDDEN);
         	 return TRUE;
          endif;
          
          return FALSE;
   	 endif;
 end;
 

 //
//
//  FUNCTION:   UninstallOldVersion(STRING); 
//  【RETURN】 
//  EVENT:      检查删除就版本信息
//  Author:    
//
function BOOL UninstallOldVersion(szOldGuid)
STRING szUninstallString; 
BOOL bFind;
INT  nResult;
begin
    while(CheckOldVersion(szOldGuid,szUninstallString))
	    if(AskYesNo("检测到已存在此软件,是否卸载后安装新版本?",NO)=YES)then
	    	//SdShowMsg("正在卸载程序,请稍等 ...",TRUE); 
	        Delay(1);
	        nResult = LaunchAppAndWait("",szUninstallString,LAAW_OPTION_WAIT);                  
	        //刷新注册表
	        nResult = LaunchAppAndWait("","cmd /c gp /force /wait:0 ",LAAW_OPTION_WAIT|LAAW_OPTION_HIDDEN);
	    else
	        abort;
	    endif;
    endwhile;
end; 

//
//
//  FUNCTION:   CheckOldVersion(szGUID,szUnInstallString)
//  【RETURN】 
//  EVENT:      检查旧版本安装信息
//  Author:    
//
function BOOL CheckOldVersion(szGUID,szUnInstallString)
STRING  UNINSTALL_REG;
STRING  szNumName;
NUMBER  nType,nSize;
begin

	if (SYSINFO.bIsWow64) then
    	REGDB_OPTIONS = REGDB_OPTIONS | REGDB_OPTION_WOW64_64KEY;
    endif;
     
	RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE);
	UNINSTALL_REG = "\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\InstallShield_"+szGUID; 
	nType = REGDB_STRING;
	szNumName = "UninstallString";
	RegDBGetKeyValueEx(UNINSTALL_REG,szNumName,nType,szUnInstallString,nSize); //获取卸载脚本
    if(RegDBKeyExist(UNINSTALL_REG)>0) then
    	return TRUE;
    endif;
    
	if (SYSINFO.bIsWow64) then
    	REGDB_OPTIONS = REGDB_OPTIONS & ~REGDB_OPTION_WOW64_64KEY;
    endif;
           
	return FALSE;
end;         
//
//
//  FUNCTION:   OnBegin
//
//  EVENT:      Begin event is always sent as the first event during installation.
//
//
function OnBegin()
STRING szMsg;
begin       
    InitCADVerInfo(); 
end;
///
//
//  FUNCTION:   OnEnd
//
//  EVENT:      End event is the last event. It is not sent if the installation
//              has been aborted. In this case Abort event is sent
//
///
function OnEnd()  
STRING szDogPath;
begin 
	 
	 if(g_bLANUCHAPP=TRUE)then 
	 	LaunchAppAcad();
	 endif;
    
end; 

//
//
//  FUNCTION:   OnInstallFilesActionAfter
//
//  EVENT:      InstallFilesActionAfter event is sent just after the 
//              standard MSI action InstallFiles is executed.
//
///
function OnInstallFilesActionAfter()
string szPicName;   
begin   
	SetupFolders();  
	SdInit(); 
 	szPicName = SUPPORTDIR^"LeftView.BMP";
 	DialogSetInfo(DLG_INFO_ALTIMAGE,szPicName,TRUE); 	
end;  
//---------------------------------------------------------------------------
// OnMoved
//
// The OnMoved event is called just before the InstallShield action 
// 'GeneratedMSIScript' is executed.
//---------------------------------------------------------------------------
function OnMoved()
string  szINI,szPathValue;
begin  
	if (!MAINTENANCE) then
		
		//拷贝安装版本文
	    if(!CopyVersionFiles())then
	    	 MessageBox ("复制数据文件信息出错!", SEVERE); 
	    	abort;
	    endif;
	    
	    //修改启动文件Ini信息
	    szINI = INSTALLDIR^LANUCH_INI;
	    szPathValue = "SOFTWARE\\Autodesk\\AutoCAD\\"+g_szInVersion+"\\"+g_szCurVersion;
	    if(WriteProfString (szINI, "ExeInfo", "RegPath",szPathValue)!=0) then
	     	MessageBox ("安装启动版本信息出错!", SEVERE);
	     	abort;
	    endif;
	   
	      //修改版本信息
	     if(WriteProfString (szINI, "ExeInfo", "Version",g_szCustomID)!=0) then
	     	MessageBox ("安装版本信息出错!", SEVERE);
	     	abort;
	    endif;   
	    
    endif; 
end;


//---------------------------------------------------------------------------
// OnMaintUIAfter
//
// The OnMaintUIAfter event called by the framework after the file transfer
// of the setup when the setup is running in maintenance mode. By default
// this event displays UI that informs the end user that the maintenance setup
// has been completed successfully.
//---------------------------------------------------------------------------
function OnMaintUIAfter()
    STRING szTitle, szMsg1, szMsg2, szOpt1, szOpt2,szMsg;
    NUMBER bOpt1, bOpt2;
begin
 
	Disable(STATUSEX);
    
    if( REMOVEALLMODE ) then
        szTitle = SdLoadString(IFX_SDFINISH_REMOVE_TITLE);
        szMsg1 = SdLoadString(IFX_SDFINISH_REMOVE_MSG1);
    else
        szTitle = SdLoadString(IFX_SDFINISH_MAINT_TITLE);    
        szMsg1  = SdLoadString(IFX_SDFINISH_MAINT_MSG1);
    endif;

	bOpt1   = FALSE;
    bOpt2   = FALSE;    

    if ( BATCH_INSTALL ) then
    	SdFinishReboot ( szTitle , szMsg1 , SYS_BOOTMACHINE , szMsg2 , 0 );
    else    
       	SdFinish ( szTitle , szMsg1 , szMsg2 , szOpt1 , szOpt2 , bOpt1 , bOpt2 );
    endif;
    
    UninstallFiles();  
end;


//---------------------------------------------------------------------------
// OnFirstUIAfter
//
// The OnFirstUIAfter event called by the framework 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.
//---------------------------------------------------------------------------
function OnFirstUIAfter()
    STRING szTitle, szMsg1, szMsg2, szOpt1, szOpt2,szOption1,szOption2,szDocFile;
    NUMBER bOpt1, bOpt2;
begin
	
	//注册表
	if(!WriteReg()) then
		abort;
	endif; 
	
	//注册dll
	RegisterDll(); 
	
	//卸载快捷方式
	CreateUninstShortCut(); 
	
	//安装vcredist_x86_2008 版本9.0.30729 
	if(!WindowsUnstallInfo(VC_REDIST_11)) then
		InstallSoftSilent(INSTALLDIR^VC_REDIST_DIR,g_szCurVcredist);
	endif;     
	
	//装狗驱动
	InstallDogDirver();         
	       
	if (SYSINFO.bIsWow64) then    	       
		LaunchAppAndWait ("msiexec.exe", "/i \""+INSTALLDIR^"Support\\Drivers\\AceRedist.msi\" /qb", LAAW_OPTION_WAIT);
	endif;
	
	Disable(STATUSEX);
	ShowObjWizardPages(NEXT);
	bOpt1 = TRUE;
	bOpt2 = TRUE;
	szMsg1 = SdLoadString(IFX_SDFINISH_MSG1);
	szTitle="";
	szMsg1="";
	szMsg2="";
	szOption1="立即启动应用程序";
	szOption2="";
	SdFinishEx(szTitle, szMsg1, szMsg2, szOption1, szOption2, bOpt1, bOpt2);
	g_bLANUCHAPP = bOpt1;

end;
//---------------------------------------------------------------------------
// OnMaintUIBefore
//
// The OnMaintUIBefore event is called by the framework when the setup is
// running in maintenance mode. By default this event displays UI that
// allows the end user to add or remove features, repair currently
// installed features or uninstall the application.
//---------------------------------------------------------------------------
function OnMaintUIBefore()
	NUMBER nResult, nType;
	STRING szTitle, szMsg, svDir, svResult, szCaption,szInfo;
	BOOL bRunningCad;
begin

 szInfo ="即将卸载"+PRODOUCT_NAME+",请确定已备份数据\n           是否继续执行卸载操作?"; 	
 if MessageBox(szInfo,MB_YESNO) = IDNO then     
    abort;
 endif; 

bRunningCad = TRUE;
while(bRunningCad)
	bRunningCad = ProcessRunning("acad");
	if(bRunningCad)then
	   szInfo="请确定关闭所有的AutoCAD应用程序后,\n            再执行卸载操作";
	   if MessageBox(szInfo,MB_OKCANCEL) = IDCANCEL then     
    		abort;
 	  	endif; 
	endif;
endwhile; 
							
	
Dlg_Start:
      nType = REMOVEALL;
Dlg_SdFeatureTree:
	if (nType = MODIFY) then
		szTitle = "";
		szMsg = "";
		nResult = SdFeatureTree(szTitle, szMsg, INSTALLDIR, "", 2);
		if (nResult = BACK) goto Dlg_Start;
	endif;

	switch(nType)
        case REMOVEALL: 
        
            ComponentRemoveAll();

            // Added in IS 2009 - Set appropriate StatusEx static text.
            SetStatusExStaticText( SdLoadString( IDS_IFX_STATUSEX_STATICTEXT_MAINTUI_REMOVEALL ) );

        case REPAIR:
        
            ComponentReinstall();

            // Added in IS 2009 - Set appropriate StatusEx static text.
            SetStatusExStaticText( SdLoadString( IDS_IFX_STATUSEX_STATICTEXT_MAINTUI_REPAIR ) );


        case MODIFY:

            // Added in IS 2009 - Set appropriate StatusEx static text.
            SetStatusExStaticText( SdLoadString( IDS_IFX_STATUSEX_STATICTEXT_MAINTUI_MODIFY ) );

    endswitch;
    
	// setup default status 
	SetStatusWindow(0, "");
	Enable(STATUSEX);
	StatusUpdate(ON, 100);
end;
/
// Function prototypes.
/

prototype POINTER ArrayToPointer(BYREF VARIANT);
prototype BOOL    ProcessRunning(STRING);

// Kernel functions.

prototype NUMBER Kernel32.OpenProcess(NUMBER, BOOL, NUMBER);
prototype NUMBER Kernel32.TerminateProcess(NUMBER, NUMBER);

// Process information functions.

prototype NUMBER PSAPI.EnumProcesses(POINTER, NUMBER, BYREF NUMBER);
prototype NUMBER PSAPI.EnumProcessModules(NUMBER, BYREF NUMBER, NUMBER,
        BYREF NUMBER);
prototype NUMBER PSAPI.GetModuleFileNameExA(NUMBER, NUMBER, BYREF STRING,
        NUMBER);



/
// Structures.
/

// Structure to mirror the C/C++ SAFEARRAY data structure.

typedef _SAFEARRAY
begin
    SHORT   cDims;
    SHORT   fFeatures;
    LONG    cbElements;
    LONG    cLocks;
    POINTER pvData;
    // rgsaBound omitted
end;

// Structure to mirror the C/C++ VARIANT data structure.

typedef _VARIANT
begin
    SHORT  vt;
    SHORT  wReserver1;
    SHORT  wReserved2;
    SHORT  wReserved3;
    NUMBER nData;
end;


        
/
// Constants.
/

#define PSAPI_FILE        "psapi.dll"  // Windows NT process DLL
#define PROCESSID_LENGTH  4            // 4 bytes (DWORD) for a process ID

// Process information constants.

#define PROCESS_QUERY_INFORMATION  0x400
#define PROCESS_ALL_ACCESS         0x1f0fff
#define PROCESS_VM_READ            0x10



//
//
// Function:    ArrayToPointer
//
// Description: Converts an InstallShield array into a C array.
//
//              When an array is created in InstallScript, a VARIANT variable
//              is created which holds an OLEAutomation SAFEARRAY. To pass
//              such an array to a DLL function expecting a C-style array,
//              this function explicitly typecasts the pointer to the array
//              to a _VARIANT pointer so that the _SAFEARRAY pointer can be
//              extracted. The pointer to the actual data is then extracted
//              from the _SAFEARRAY pointer.
//
// Parameters:  structArray - Array variable.
//
// Returns:     POINTER - Pointer to array.
//
//

function POINTER ArrayToPointer(structArray)
    _SAFEARRAY POINTER pstructArray;    // _SAFEARRAY array pointer
    _VARIANT   POINTER pstructVariant;  // _VARIANT array pointer
begin
    // Typecast the pointer to the array to a _VARIANT pointer.
    
    pstructVariant = &structArray;
    
    // Extract the _SAFEARRAY pointer from the _VARIANT.
    
    pstructArray = pstructVariant->nData;
    
    // Return the pointer to the actual data from the _SAFEARRAY.
    
    return pstructArray->pvData;
end;



//
//
// Function:    _Process_Running
//
// Description: Determines if the specified process is running in memory.
//
// Parameters:  szAppName - Name of the application to check.
//
// Returns:     TRUE  - The process is running.
//              FALSE - The process is not running.
//
//

function BOOL ProcessRunning(szAppName)
    BOOL    bvRunning;          // Process is running
    NUMBER  nvProcessIDs(512);  // Array of process IDs
    NUMBER  nvBytesReturned;    // Number of bytes returned in process ID array
    NUMBER  nvProcesses;        // Number of processes running
    NUMBER  nvIndex;            // Loop index
    NUMBER  nvProcessHandle;    // Handle to a process
    NUMBER  nvModuleHandle;     // Handle to a process module
    NUMBER  nvBytesRequired;    // Number of bytes required to store values
    POINTER pvProcessIDs;       // Pointer to process ID array
    STRING  svModuleName;       // Module name
    STRING  svFileName;         // Module filename 
begin
    // The psapi.dll reads the Windows NT performance database. The DLL
    // is part of the Win32 SDK.
    
    if UseDLL(WINSYSDIR ^ PSAPI_FILE) < 0 then
        // Could not load psapi.dll.
        
        MessageBox("ERROR: Could not load [" + WINSYSDIR ^ PSAPI_FILE +
                "].", SEVERE);
        
        return FALSE;
    endif;
    
    // Get the PIDs of all currently running processes.
    
    pvProcessIDs = ArrayToPointer(nvProcessIDs);

    EnumProcesses(pvProcessIDs, 512, nvBytesReturned);

    // Determine the number of process IDs retrieved. Each process ID
    // is PROCESSID_LENGTH bytes.
    
    nvProcesses = nvBytesReturned / PROCESSID_LENGTH;
    
    // Get the executable associated with each process, and check if
    // its filename matches the one passed to the function.
    
    for nvIndex = 1 to nvProcesses
        // Get a handle to the process.
        
        nvProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION |
                PROCESS_VM_READ, 0, nvProcessIDs(nvIndex));
                
        if nvProcessHandle != 0 then
            // Get a handle to the first module in the process, which
            // should be the executable.
            
            if EnumProcessModules(nvProcessHandle, nvModuleHandle,        
                    PROCESSID_LENGTH, nvBytesRequired) != 0 then
                // Get the path of the module.
                
                if GetModuleFileNameExA(nvProcessHandle, nvModuleHandle,
                        svModuleName, SizeOf(svModuleName)) != 0 then
                    // Extract the filename (without an extension) from
                    // the path.
                    
                    ParsePath(svFileName, svModuleName, FILENAME_ONLY);
                    
                    if StrCompare(svFileName, szAppName) = 0 then
                        // The process module matches the application 
                        // name passed to the function.
                        
                        bvRunning = TRUE;
                        
                        goto ProcessRunningEnd;
                    endif;
                endif;
            endif;
        endif;
    endfor;
            
    ProcessRunningEnd:
        
    if UnUseDLL(PSAPI_FILE) < 0 then
        MessageBox("ERROR: Could not unload [" + WINSYSDIR ^ PSAPI_FILE +
                "].", SEVERE);
                
        return FALSE;
    endif;
        
    return bvRunning;
end;

InstallShield :@http://blog.51cto.com/liucw/1220134

InstallShield Limited Edition for Visual Studio : @https://www.cnblogs.com/zhuxiaohui/p/5139740.html

InstallShield(最全) :@http://blog.csdn.net/duanbeibei/article/details/50333603

ctrl + F7:检查

F7:编译

把Product Configuration 1\Release 1\DiskImages\下的DISK1压缩,运行里面的setup.exe就可进行安装

转载于:https://my.oschina.net/u/2930533/blog/1593778

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值