打包:InstallShield

打包:InstallShield,由windows提供, 安裝包開發的製做工具 。html

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

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

(1) Application Information:公司名稱,軟件名稱,版本號,公司網址(必填),更新是否自動通知用戶,圖標windows

(2)Installation Requirement:操做系統和所需的軟件等api

(3) Installation Architecture: 用戶能夠自由選擇安裝某些功能。(可參考下面第三個網址)app

若是爲Yes,在此處設置好之後, 把界面切到 Installation Designer ----> Organization ----> Features 從新修改一遍名稱。async

(4) Application Files : 安裝路徑,默認路徑爲C:\Program Files (x86)\公司名稱\項目名稱,現改成C:\Program Files (x86)\項目名稱ide

(5) Application Shortcuts :快捷方式工具

左側: More Options下Create an uninstallation shortcut:卸載快捷方式。oop

右側勾選按鈕分別爲: 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就可進行安裝

相關文章
相關標籤/搜索