在已部署Tomcat+MySql+Jdk后,如何打包部署应用

前言

前一篇介绍了如何使用InstallShield打包自动部署JavaWeb的运行环境,如果有不了解的,请参考:
使用InstallShield打包Tomcat+MySql+Jdk的Web运行环境详解
本文主要介绍如何使用InstallShield打包自动部署应用。具体应用是多种多样的,但是打包的思路基本一样的。拷贝文件,系统注册等操作,InstallShield都会替你做了,我们只需要在InstallScript里对应的部首阶段中,调用自己的安装和卸载批处理即可。

安装批处理

为了打包简单,我设计了一个批处理,在InstallShield的脚本里调用即可。具体批处理【real_update_DVCSWeb.bat】内容如下:

@ echo off  
::switch to work dir
cd /d %~dp0
echo %cd%

echo install tomcat service
call "%cd%"\install_tomcat.bat

echo stop tomcat service
sc stop dvcs_tomcat

echo kill tomcat6
taskkill /f /t /im tomcat6.exe

echo backup mysql data [wait for a few minutes]
"%MYSQL_HOME%"\bin\mysqldump -uroot -p123456 dvcs > "%cd%\dvcs_data_bak_%DATE:~0,4%%DATE:~5,2%%DATE:~8,2%.sql"

echo update war packet
rd /s/q "%CATALINA_HOME%\webapps\dvcs"
rd /s/q "%CATALINA_HOME%\work\Catalina\localhost\dvcs"
copy /y  "%cd%\DVCSWeb\dvcs.war" "%CATALINA_HOME%\webapps"

echo update [system.properties]
copy /y  "%cd%\DVCSWeb\system.properties" "%DVCS_HOME%\conf"
echo update [mail.properties]
copy /y  "%cd%\DVCSWeb\mail.properties" "%DVCS_HOME%\conf"

echo start tomcat service
sc start dvcs_tomcat


批处理中调用的其它批处理,读者可以参考前面的文章,可以找到线索,这里不再细说,批处理里的注释也说得很清楚。
同样,为了生成安装日志,再创建一个批处理【update_DVCSWeb.bat】封装起来,供InstallScript调用,具体内容如下:

@ echo off  
::切换到工作目录
cd /d %~dp0
echo %cd%

::调用更新批处理
call real_update_DVCSWeb.bat > update_DVCSWeb.log

卸载批处理

我的应用在卸载时,主要停止Tomcat即可,后面删除文件和目录由InstallShield替我做了,具体卸载批处理【unstall_DVCSWeb.bat】内容如下:

@ echo off  
::切换到工作目录
cd /d %~dp0

::echo 停止Tomcat
::call %DVCS_HOME%\stop_tomcat.bat

echo 停止Tomcat服务...
sc stop dvcs_tomcat

使用InstallShield打包应用

我创建了同样的InstallShield工程类型【InstallScript MSI Project】,具体脚本内容如下:

//===========================================================================
//
//  File Name:    Setup.rul
//
//  Description:  Blank setup main script file
//
//  Comments:     Blank setup is an empty setup project. If you want to
//				  create a new project via. step-by step instructions use the
//				  Project Assistant.
//
//===========================================================================

// Included header files ----------------------------------------------------
#include "ifx.h"              

// Microsoft Visual C++ 2012 Redistribute Package
#define VS_2012_REDIST_X64_KEY "SOFTWARE\\Classes\\Installer\\Dependencies\\{ca67548a-5ebe-413a-b50c-4b9ceb6d66c6}"

BOOL bRetainUseData, g_isVs2012X64Installed;
// Note: In order to have your InstallScript function executed as a custom
// action by the Windows Installer, it must be prototyped as an 
// entry-point function.

// The keyword export identifies MyFunction() as an entry-point function.
// The argument it accepts must be a handle to the Installer database.
    
/* export prototype MyFunction(HWND); */ 
export prototype  IsVS2012X64Installed();  

// 判断VS2012分发布是否已安装
function IsVS2012X64Installed()    
begin
    RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE);
    if(RegDBKeyExist(VS_2012_REDIST_X64_KEY) == 1) then
    	//MessageBox ("VS2012 has installed", INFORMATION); 
    	g_isVs2012X64Installed = TRUE;
    else                                                                    
    	//MessageBox ("VS2012 not installed", INFORMATION);  
    	g_isVs2012X64Installed = FALSE;
    endif;
end;

//---------------------------------------------------------------------------
// OnFirstUIBefore
//
// The OnFirstUIBefore event is called by the framework when the setup is
// running in first install mode. By default this event displays UI allowing
// the end user to specify installation parameters.   
//---------------------------------------------------------------------------
function OnFirstUIBefore()
    NUMBER nResult, nSetupType, nvSize, nUser;
    STRING szTitle, szMsg, szQuestion, svName, svCompany, szFile;
    STRING szLicenseFile;
	BOOL bCustom, bIgnore1, bIgnore2;
begin
    //SetTitle("Installation "+IFX_PRODUCT_NAME,0,BACKGROUNDCAPTION);
    // TO DO: if you want to enable background, window title, and caption bar title                                                                   
    // SetTitle( @PRODUCT_NAME, 24, WHITE );                                        
    // SetTitle( @PRODUCT_NAME, 0, BACKGROUNDCAPTION ); 	                  
    // Enable( FULLWINDOWMODE );						   
    // Enable( BACKGROUND );							  
    // SetColor(BACKGROUND,RGB (0, 128, 128));					   

    // Added in InstallShield 15 - Show an appropriate error message if
    // -uninst is specified and the product is not installed.
    if( REMOVEONLY ) then
        Disable( DIALOGCACHE );
		szMsg = SdLoadString( IDS_IFX_ERROR_PRODUCT_NOT_INSTALLED_UNINST );
   		SdSubstituteProductInfo( szMsg );
		MessageBox( szMsg, SEVERE );
		abort;
    endif;
    
	nSetupType = TYPICAL;	

Dlg_SdWelcome:
    szTitle = "";
    szMsg   = "";
    nResult = SdWelcome(szTitle, szMsg);
    if (nResult = BACK) goto Dlg_SdWelcome;
	
	szTitle   = "";
	svName    = "";
    svCompany = "";

Dlg_SdRegisterUser:
    szMsg = "";
    szTitle = "";
    nResult = SdRegisterUser( szTitle, szMsg, svName, svCompany );
    if (nResult = BACK) goto Dlg_SdWelcome;

Dlg_SetupType:  
/*
    szTitle = "";
    szMsg   = "";
    nResult = SetupType2(szTitle, szMsg, "", nSetupType, 0);
    if (nResult = BACK) then
        goto Dlg_SdRegisterUser;
    else
	    nSetupType = nResult;
        if (nSetupType != CUSTOM) then
	        nvSize = 0;
	        FeatureCompareSizeRequired(MEDIA, INSTALLDIR, nvSize);
	        if (nvSize != 0) then      
            	MessageBox(szSdStr_NotEnoughSpace, WARNING);
	            goto Dlg_SetupType;
            endif;
			bCustom = FALSE;
			goto Dlg_SQL;
		else
			bCustom = TRUE;
        endif;
    endif;  */  

Dlg_SdAskDestPath:    	
    nResult = SdAskDestPath(szTitle, szMsg, INSTALLDIR, 0);
    if (nResult = BACK) goto Dlg_SdRegisterUser;

Dlg_SdFeatureTree: 
    szTitle    = "";
    szMsg      = "";
    if (nSetupType = CUSTOM) then
		nResult = SdFeatureTree(szTitle, szMsg, INSTALLDIR, "", 2);
		if (nResult = BACK) goto Dlg_SdAskDestPath;  
    endif;

Dlg_SQL:
    nResult = OnSQLLogin( nResult );
    if( nResult = BACK ) then
    	if (!bCustom) then
    		goto Dlg_SetupType;    
    	else
    		goto Dlg_SdFeatureTree;
    	endif;
    endif;

Dlg_ValueAddedServices:
    nResult = OnFirstUIBeforeValueAddedServices( nResult );
    if (nResult = BACK) goto Dlg_SQL;

Dlg_SdStartCopy:
    szTitle = "";
    szMsg   = "";
    nResult = SdStartCopy2( szTitle, szMsg );			
	
	if (nResult = BACK) then
    	goto Dlg_ValueAddedServices;
    endif;

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

    // setup default status
    Enable(STATUSEX);
 
    return 0;
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,szCmd,szDir;
begin 
    //SetTitle("Installation "+IFX_PRODUCT_NAME,0,BACKGROUNDCAPTION);
    //加入终止进程函数
     
	// TO DO: if you want to enable background, window title, and caption bar title   								
	// SetTitle( @PRODUCT_NAME, 24, WHITE );					
	// SetTitle( @PRODUCT_NAME, 0, BACKGROUNDCAPTION );  			
	// SetColor(BACKGROUND,RGB (0, 128, 128));					
	// Enable( FULLWINDOWMODE );						
	// Enable( BACKGROUND );							

Dlg_Start: 
	bRetainUseData=TRUE;
    nType = REMOVEALL; 
    nResult = MessageBox( SdLoadString( IFX_MAINTUI_MSG ), MB_YESNO );
	if (nResult != IDYES ) then
        abort;
    endif; 
    nResult = MessageBox( "Do you  want to reserve the config data?(Y:Reserve, N:Dispose)", MB_YESNOCANCEL );
	if (nResult == IDNO ) then  
		bRetainUseData=FALSE;
    endif; 
    if (nResult == IDCANCEL ) then  
		abort;
    endif;   
         
    // 停止Tomcat    
    szCmd = TARGETDIR ^ "\\DVCS Server\\unstall_DVCSWeb.BAT"; 
    LaunchAppAndWait(szCmd,"",LAAW_OPTION_WAIT|LAAW_OPTION_SHOW_HOURGLASS|LAAW_OPTION_HIDDEN);  
     
    // 退出DVCS Server进程    
    szCmd = TARGETDIR ^ "\\DVCS Server\\1.BAT"; 
    LaunchAppAndWait(szCmd,"",LAAW_OPTION_WAIT|LAAW_OPTION_SHOW_HOURGLASS|LAAW_OPTION_HIDDEN);  
    
	switch(nType)
        case REMOVEALL:   
        	// 删除DVCS服务
        	LaunchAppAndWait("sc", "delete dvcs_server", LAAW_OPTION_WAIT); 
        
            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;
       
    // 卸载VS2012分发包
    if(g_isVs2012X64Installed) then 
	    szCmd = TARGETDIR ^ "\\DVCS Server\\vcredist_x64.exe"; 
	    LaunchAppAndWait(szCmd,"",LAAW_OPTION_WAIT|LAAW_OPTION_SHOW_HOURGLASS|LAAW_OPTION_HIDDEN);
    endif;
    
	// setup default status 
	SetStatusWindow(0, "");
	Enable(STATUSEX);
	StatusUpdate(ON, 100);
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;
    NUMBER bOpt1, bOpt2;
begin
	Disable(STATUSEX);
    
    if( REMOVEALLMODE ) then
        szTitle = SdLoadString(IFX_SDFINISH_REMOVE_TITLE);
        szMsg1 = SdLoadString(IFX_SDFINISH_REMOVE_MSG1);
        
        if(!bRetainUseData) then
        	DeleteProgramFolder(TARGETDIR+"DVCS Server");
        	DeleteProgramFolder(FOLDER_PROGRAMS+"DVCS Server"); 
        endif;        
    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;                                                              
end;
//---------------------------------------------------------------------------
// OnInstallFilesActionAfter
//
// The InstallFilesActionAfter event is called just after the standard MSI
// action 'InstallFiles' is executed.
//---------------------------------------------------------------------------
function OnInstallFilesActionAfter() 
STRING  szDir;
STRING	szCmd; 
NUMBER ret;
begin         
	if( REMOVEALLMODE ) then
		
	else 
		// 退出DVCS Server进程
		szCmd = TARGETDIR ^ "\\DVCS Server\\1.BAT"; 
	    LaunchAppAndWait(szCmd,"",LAAW_OPTION_WAIT|LAAW_OPTION_SHOW_HOURGLASS|LAAW_OPTION_HIDDEN);
	    // 安装VS2012分发包
	    if(!g_isVs2012X64Installed) then 
		    szCmd = TARGETDIR ^ "\\DVCS Server\\vcredist_x64.exe"; 
		    LaunchAppAndWait(szCmd,"",LAAW_OPTION_WAIT|LAAW_OPTION_SHOW_HOURGLASS|LAAW_OPTION_HIDDEN);
	    endif;
	     
	    // 启动DVCS服务
		szDir = " create dvcs_server binPath= \""+INSTALLDIR+"DVCS Server\\dvcs_daemon.exe\" type= own start= auto ";
		if( LaunchAppAndWait("sc",szDir, LAAW_OPTION_WAIT)>=0) then
			LaunchAppAndWait("sc","start dvcs_server", LAAW_OPTION_WAIT);  
		endif;   
		
		// 更新DVCS Web  
		szCmd = TARGETDIR ^ "\\DVCS Server\\update_DVCSWeb.BAT"; 
	    LaunchAppAndWait(szCmd,"",LAAW_OPTION_WAIT|LAAW_OPTION_SHOW_HOURGLASS|LAAW_OPTION_HIDDEN);
		
	endif;
end;
//---------------------------------------------------------------------------
//  OnResumeUIBefore
//
//  The OnResumeUIBefore event is called when end user runs installation that
//  is performing a resumed install. Usually this happens by specifying
//  a property like REINSTALL or ADDLOCAL at the command line when the 
//  product is already installed. After this function returns, 
//  ComponentTransferData is called to perform file transfer.
//---------------------------------------------------------------------------
function OnResumeUIBefore()
	int    nResult;
	string szTitle, szMsg ,szCmd;
begin
    // 由于从V3.7.27后不能覆盖升级(文件不能更新,具体原因不清楚 20181213 pst)
    // 需要先卸载旧版本,不支持覆盖安装
    MessageBox("The installation has detected the DVCS Server has been installed. " +
    		     "Please uninstall it first.", INFORMATION);
    abort; 
    
Dlg_SdWelcome:
	szTitle = SdLoadString(ISWI_RESUMEUI_TITLE);
	szMsg = SdLoadString(ISWI_RESUMEUI_MSG);
    nResult = SdWelcome(szTitle, szMsg);

    // Added in IS 2009 - Set appropriate StatusEx static text.
    szMsg = SdLoadString( IDS_IFX_STATUSEX_STATICTEXT_UPDATEUI );
	SdSubstituteProductInfo( szMsg );
    SetStatusExStaticText( szMsg );

	Enable(STATUSEX);   
	
    // 停止Tomcat    
    szCmd = TARGETDIR ^ "\\DVCS Server\\unstall_DVCSWeb.BAT"; 
    LaunchAppAndWait(szCmd,"",LAAW_OPTION_WAIT|LAAW_OPTION_SHOW_HOURGLASS|LAAW_OPTION_HIDDEN);  
     
    // 退出DVCS Server进程 
	szCmd = TARGETDIR ^ "\\DVCS Server\\1.BAT"; 
    LaunchAppAndWait(szCmd,"",LAAW_OPTION_WAIT|LAAW_OPTION_SHOW_HOURGLASS|LAAW_OPTION_HIDDEN);             
	
	DeleteProgramFolder(TARGETDIR+"DVCS Server\\Web");
    DeleteProgramFolder(FOLDER_PROGRAMS+"DVCS Server\\Web");
end;
//---------------------------------------------------------------------------
// OnBegin
//
// The OnBegin event is called directly by the framework after the setup
// initializes.
//---------------------------------------------------------------------------
function OnBegin()
begin
	// TO DO: you may change default non-UI setting, for example
	//
	// You may also perform your custom initialization steps, check requirements, etc.
	// 检查VS2012分发包是否已经安装
	IsVS2012X64Installed();
end;

结束语

通过前面文件和这篇文章的介绍,对如何打包自动部署Web应用的思路和具体办法进行了比较详细的介绍,希望对大家有所帮助。
这些自动化打包部署的方法大概花了两周时间,慢慢摸索出来的。之前的开发工程师写了一个很长的手工安装文档,按照这个文档一步一步安装的话,估计要半天时间。并且我们的客户基本没有计算机经验,让他们如何打开控制台执行命令都不清楚。
其实做软件这个行业,要积极发现问题,并耐心解决,不能怕麻烦。如果工程师怕麻烦,最终就把麻烦丢给了客户,造成客户的丢失。

你可能感兴趣的:(开发问题)