获取Msi文件的属性内容InstallUtility

void MsiGetPropertyByOpenPackage()
{
	MSIHANDLE msiHandle = NULL;
	UINT uiOpenState;
	TCHAR* szMsiFileName= _T("C:\\Program Files (x86)\\远为软件\\virnos client\\SWar.msi");
	uiOpenState = MsiOpenPackage(szMsiFileName, &msiHandle);
	if (ERROR_SUCCESS != uiOpenState)
	{
		// error
		return;
	}

	TCHAR* szValueBuf = NULL;
	DWORD cchValueBuf = 0;
	UINT uiState =MsiGetProperty(msiHandle, TEXT("ProductName"), TEXT(""), &cchValueBuf);
	if (ERROR_MORE_DATA == uiState)
	{

		++cchValueBuf;
		szValueBuf = new TCHAR(cchValueBuf);
		if (szValueBuf)
		{
			uiState = MsiGetProperty(msiHandle, TEXT("ProductName"), szValueBuf, &cchValueBuf);
		}
	}
	MsiCloseHandle(msiHandle);
}

 

调用MsiOpenPackage函数来获取MSIHANDLE值,然后就可以获取属性值,MsiOpenPackage使用的时候会打开msi文件,会看到程序运行时的界面,再调用MsiCloseHandle(hInstall)函数就关闭msi文件,也会看到msi程序运行界面消失。用该方法的时候就会看到有msi瞬间闪现安装界面,体验感觉不好

因此使用MsiOpenDatabase打开msi文件,然后再获取,后面相继使用MsiDatabaseOpenView,MsiViewExecute,MsiViewFetch,MsiRecordGetString等方法,

使用MsiCloseHandle关闭打开的msi句柄。

BOOL  GetMsiPropertyProductVersion(CString strMsiName, CString &strVer )
{
	USES_CONVERSION;
	MSIHANDLE hMsiHandle = NULL;
	UINT uiStatus = MsiOpenDatabase(strMsiName, MSIDBOPEN_READONLY, &hMsiHandle);
	if (ERROR_SUCCESS != uiStatus)
	{
		return FALSE;
	}
	MSIHANDLE hView = NULL;
	MsiDatabaseOpenView(hMsiHandle, _T("SELECT * FROM Property WHERE Property = 'ProductVersion'"), &hView);
	MSIHANDLE hRecord = NULL;
	MsiViewExecute(hView, hRecord);
	if (MsiViewFetch(hView, &hRecord) == ERROR_SUCCESS)
	{
		TCHAR szName[MAX_PATH]={0};
		TCHAR szValue[MAX_PATH]={0};
		DWORD  dwStringLen = MAX_PATH;
		MsiRecordGetString(hRecord, 1, szName, &dwStringLen);
		dwStringLen = MAX_PATH;
		MsiRecordGetString(hRecord, 2, szValue, &dwStringLen );
		printf("%s\t:%s\r\n", T2A(szName), T2A(szValue));
		strVer = szValue;
		MsiCloseHandle(hView);
		MsiCloseHandle(hMsiHandle);
		return TRUE;
	}
	MsiCloseHandle(hView);
	MsiCloseHandle(hMsiHandle);
	return FALSE;
}

UINT  GetMsiAllProperty(CString strMsiName )
{
	USES_CONVERSION;
	MSIHANDLE hMsiHandle = NULL;
	UINT uiStatus = MsiOpenDatabase(strMsiName, MSIDBOPEN_READONLY, &hMsiHandle);
	if (ERROR_SUCCESS != uiStatus)
	{
		return uiStatus;
	}


	MSIHANDLE hView = NULL;
	MsiDatabaseOpenView(hMsiHandle, _T("SELECT * FROM Property"), &hView);
	MSIHANDLE hRecord = NULL;
	MsiViewExecute(hView, hRecord);
	while(MsiViewFetch(hView, &hRecord) == ERROR_SUCCESS)
	{
		TCHAR szValueBuf[MAX_PATH]={0};
		TCHAR Source[MAX_PATH]={0};
		DWORD  dwStringLen = MAX_PATH;
		MsiRecordGetString(hRecord, 1, szValueBuf, &dwStringLen);
		dwStringLen = MAX_PATH;
		MsiRecordGetString(hRecord, 2, Source, &dwStringLen );
		printf("%s\t:%s\r\n", T2A(szValueBuf), T2A(Source));
	}
	MsiCloseHandle(hView);
	MsiCloseHandle(hMsiHandle);
	return 1;
}













例如实际的配置文档内容

创建DLL文件build.bat内容

call vs6.bat
@echo off
nmake -nologo -f makefile-InstallUtility clean
nmake -nologo -f makefile-InstallUtility
del ufutils.dll
rename InstallUtility.dll ufutils.dll
rem copy ufutils.dll ..\Lib\Resource\ufutils.dll
echo buildding completed!
pause

vs6.bat 文件内容 

"c:\Program Files\Microsoft Visual Studio\VC98\Bin\VCVARS32.BAT" 


InstallUtility.def  内容

; InsatllUtility.def : Declares the module parameters for the DLL.


LIBRARY      "InstallUtility"
DESCRIPTION  'InstallUtility Windows Dynamic Link Library'


EXPORTS
    ; Explicit exports can go here
RollbackBackupFiles@1
ExcuteDBEnginSys@2
CompareFilesDate             @3
        ExcuteApp             @4
    ExcuteRegServer       @5
RemoveAllFiles        @6
CreateBinaryFile      @7
        SetRegPolicyScopeValue @8
        ExcuteSqlLiteSys       @9
        UninstallExcuteEnginSys @10

InstallUtility.cpp 文件内容



// ++
//
// UFIDA Ltd. inc. 
//
// Copyright (C) Microsoft UFIDA, 2006
//
// File: 
//		InstallUtility.cpp
//
// Date: 
//		Apr.29.2006
//
// Note:
//		U8安装程序辅助扩展工具,提供程序反安装
//	原始文件还原的功能
//
// ++
#pragma warning (disable:4786 4530)
#include <windows.h>
#include <stdlib.h>
#include <tchar.h>
#include <Msi.h>
#include <Msiquery.h>
#include <set>
#include <string>
#include <fstream>
#include "Shlwapi.h"
#include "RpcDce.h"
#include <time.h>
#include <stdio.h>
#include "rpcdce.h"
#pragma comment(lib, "Msi.lib")
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "Advapi32.lib")
#pragma comment(lib, "rpcrt4.lib")
#define PROPERTYNAME_DEPENDLIST _T("dependlist")
#define PROPERTYNAME_PATCHREGROOT _T("patchregroot")
#define PROPERTYNAME_CURBACKDIR _T("currbak")
#define PROPERTYNAME_ABC _T("[#file.2D0F7A40_6082_42CA_B2B5_546AA2DB9CB0]")
#define RELEASE(p) if (p) {\
						delete [] (p); \
						(p) = NULL; \
					}

#define INSTALLMESSAGE_FATALEXIT	0x00000000L
#define MAX_BUFFER 512
#import "com\\Comadmin.dll" no_namespace
using namespace std;
//#import "com\\Comadmin.dll" no_namespace
//
// Global Variant Define
//
TCHAR*		g_lpszBackupFilesPath = NULL;	// 保存备份原始文件的目录
BOOL		g_fNeedReBoot		  = FALSE;	// 是否需要重新启动操作系统
MSIHANDLE	g_hInstall			  = NULL;

long		eMessageType		  = INSTALLMESSAGE_INFO;

TCHAR*		g_spid = NULL;	// 问题号
TCHAR*		g_dbEnginPath = NULL;	// 数据库引擎
TCHAR*		g_sqllitepathinfoPath = NULL;	// 导入SQLLITE文件信息
TCHAR*		g_exerunPath = NULL;	// 获取EXE 运行路径,卸载完后的。

set<string>  g_setupfilesets; //声明集合
void Log2Msi(LPCTSTR lpszMsg, ...)
{
	TCHAR szBuffer[2048] = {0};
	va_list list;
	va_start(list, lpszMsg);
	wvsprintf(szBuffer, lpszMsg, list);
	va_end(list);

	OutputDebugString(szBuffer);


	PMSIHANDLE hRec = ::MsiCreateRecord(2);
	::MsiRecordSetString(hRec, 0, szBuffer);
	
	::MsiProcessMessage(g_hInstall, (tagMSIMESSAGE)eMessageType, hRec);
	
	::MsiCloseHandle(hRec);
}


//
// 
//
//
LPTSTR getProperty(MSIHANDLE hInstall, LPCTSTR lpszPropertyName)
{
	TCHAR*	szCAData	= NULL;
	DWORD	cchCAData	= 0;
	UINT	uiState		= ERROR_SUCCESS;

	//
	// 尝试获取属性的长度,然后分配内存
	//
	uiState = ::MsiGetProperty(hInstall, lpszPropertyName, _T(""), &cchCAData);
	if (uiState == ERROR_MORE_DATA)
	{
		//
		// 分配内存
		//
		szCAData = new TCHAR[++cchCAData];
		
		//
		// 得到属性值
		//
		uiState = ::MsiGetProperty(hInstall, lpszPropertyName, szCAData, &cchCAData);
		if (uiState != ERROR_SUCCESS)
		{
			//
			// 失败释放内存,返回失败
			//
			RELEASE(szCAData)
		}
	}
	
	return szCAData;
}



//
// getBackupFilesPath
//
//	从安装包中获取备份文件目录
//
BOOL getBackupFilesPath(MSIHANDLE hInstall)
{
	TCHAR*	szCAData	= NULL;
	DWORD	cchCAData	= 0;
	UINT	uiState		= ERROR_SUCCESS;

	g_lpszBackupFilesPath = getProperty(hInstall, PROPERTYNAME_CURBACKDIR);
	
	return (g_lpszBackupFilesPath != NULL);
}


//
// RegisterDllOcx
//
//	注册COM组件
//
BOOL RegisterDllOcx(LPCTSTR lpszFile)
{
	BOOL	fRet	= FALSE;
	HRESULT (STDAPICALLTYPE * lpDllEntryPoint)(void);

	HINSTANCE hInst = LoadLibraryEx(lpszFile, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
	
	if (hInst != NULL)
	{
		(FARPROC&)lpDllEntryPoint = GetProcAddress(hInst, _T("DllRegisterServer"));
		if (lpDllEntryPoint != NULL)
		{	
			if (FAILED((*lpDllEntryPoint)()))
				Log2Msi(_T("CCA- RegisterDllOcx!DllRegisterServer failed, LastError:0x%08X file:%s"),GetLastError(), lpszFile);	
			else
				fRet = TRUE;
		}
		else
			Log2Msi(_T("CCA- RegisterDllOcx!Could't find dll entry,DllRegisterServer file:%s"),lpszFile);
	}
	else
		Log2Msi(_T("CCA- RegisterDllOcx!Could't load file:%s"),lpszFile);

	FreeLibrary(hInst);
	return fRet;
}

bool IsVista(void)
{
    OSVERSIONINFOEX osvi = {0};
    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
    ::GetVersionEx((LPOSVERSIONINFO)&osvi);
	//return false;
    return osvi.dwMajorVersion >= 6;
}
DWORD RunCommand(LPCTSTR lpApplicationName, LPTSTR lpCommandLine,WORD nCmdShow,DWORD dwInterval)
{	
	TCHAR commandLine[1024] = {0};
	wsprintf(commandLine, _T("\"%s\" %s"), lpApplicationName, lpCommandLine);
	Log2Msi(_T("CCA- GetProcessReturn(%s ) !"), commandLine );
	
	STARTUPINFO si = {0};
	si.cb = sizeof(si);
	si.dwFlags |= STARTF_USESHOWWINDOW;
	//si.wShowWindow = SW_HIDE;
	si.wShowWindow=nCmdShow;
	PROCESS_INFORMATION pi;
	DWORD dwExitCode = -1;
	DWORD dwResult=-1;
	BOOL flag = ::CreateProcess(NULL, 
		commandLine,
		NULL,NULL,FALSE,0,NULL,NULL,&si, &pi);
	if (flag) 
	{
		::CloseHandle(pi.hThread);
		
		dwResult=::WaitForSingleObject(pi.hProcess, dwInterval);
		
		::GetExitCodeProcess(pi.hProcess, &dwExitCode);
		::CloseHandle(pi.hProcess);
	}
	else
	{
		dwExitCode = GetLastError();		
	}
	Log2Msi(_T("CCA- GetProcessReturn(%s exitcode: %d Result:%d) !"), commandLine, dwExitCode,dwResult );
	return dwExitCode;
}
/*
废弃,不再使用,可以外挂一个支持提升权限的程序,使用此程序作为中介,再提升其他程序
DWORD RunShellExecuteEx(LPCTSTR lpApplicationName, LPTSTR lpCommandLine,WORD nCmdShow,DWORD dwInterval)
{
	//Log2Msi(_T("CCA- RunShellExecute(%s %s ) !"), lpApplicationName,lpCommandLine);
	TCHAR commandLine[1024] = {0};
	wsprintf(commandLine, _T("\"%s\" %s"), lpApplicationName, lpCommandLine);
	Log2Msi(_T("CCA- RunShellExecute(%s ) !"), commandLine );
	DWORD dwExitCode = -1;
	
    SHELLEXECUTEINFO ShExecInfo = {0};
    ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
    ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;    
	ShExecInfo.hwnd = GetForegroundWindow();
    ShExecInfo.lpVerb =_T("runas");
    ShExecInfo.lpFile = lpApplicationName;        
    ShExecInfo.lpParameters = lpCommandLine;    
    ShExecInfo.lpDirectory = NULL;
    ShExecInfo.nShow = nCmdShow;
    ShExecInfo.hInstApp = NULL;    
    BOOL flag = ShellExecuteEx(&ShExecInfo);

	if( flag )
    {
        ::WaitForSingleObject(ShExecInfo.hProcess,INFINITE);
        ::GetExitCodeProcess(ShExecInfo.hProcess, &dwExitCode);
        ::CloseHandle(ShExecInfo.hProcess);
    }
    else
    {
        dwExitCode = ::GetLastError();
    }
	
	Log2Msi(_T("CCA- RunShellExecute(%s %s exitcode: %d) !"), lpApplicationName,lpCommandLine, dwExitCode );
	return dwExitCode;
}
*/
DWORD RunShellExecute(LPCTSTR lpApplicationName, LPTSTR lpCommandLine,WORD nCmdShow,DWORD dwInterval)
{
	//Log2Msi(_T("CCA- RunShellExecute(%s %s ) !"), lpApplicationName,lpCommandLine);
	TCHAR commandLine[1024] = {0};
	wsprintf(commandLine, _T("\"%s\" %s"), lpApplicationName, lpCommandLine);
	Log2Msi(_T("CCA- RunShellExecute(%s ) !"), commandLine );
	DWORD dwExitCode = -1;
	/*
    SHELLEXECUTEINFO ShExecInfo = {0};
    ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
    ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;    
	ShExecInfo.hwnd = GetForegroundWindow();
    ShExecInfo.lpVerb =_T("runas");
    ShExecInfo.lpFile = lpApplicationName;        
    ShExecInfo.lpParameters = lpCommandLine;    
    ShExecInfo.lpDirectory = NULL;
    ShExecInfo.nShow = nCmdShow;
    ShExecInfo.hInstApp = NULL;    
    BOOL flag = ShellExecuteEx(&ShExecInfo);
	*/
	
	HANDLE hPToken;
	HANDLE hUserTokenDup;
	PROCESS_INFORMATION pi;	
	STARTUPINFO si;
	LUID luid;
	TOKEN_PRIVILEGES tp;
	DWORD dwSessionId;
	
	
	//获取当前token值 GetCurrentProcess()
	//TOKEN_DUPLICATE
	BOOL bResult=::OpenProcessToken(::GetCurrentProcess(),
		TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY
		| TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_ADJUST_SESSIONID
		| TOKEN_READ | TOKEN_WRITE,
		&hPToken);

	if (!bResult)
	{		
		Log2Msi(_T("CCA- OpenProcessToken(%s %s exitcode: %d) !"), lpApplicationName,lpCommandLine, ::GetLastError() );
	}

	if ( !LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &luid ) )
	{
		dwExitCode = ::GetLastError();
		Log2Msi(_T("CCA- LookupPrivilegeValue(%s %s exitcode: %d) !"), lpApplicationName,lpCommandLine, dwExitCode );
		
	}
	else{
		tp.PrivilegeCount =1;
		tp.Privileges[0].Luid =luid;
		tp.Privileges[0].Attributes =SE_PRIVILEGE_ENABLED;
	}
	
	
// MAXIMUM_ALLOWED SecurityAnonymous
	if (bResult)
	{
		bResult=DuplicateTokenEx(hPToken,MAXIMUM_ALLOWED ,
			0, // token attributes
			SecurityIdentification,//SecurityAnonymous
			TokenPrimary
			,&hUserTokenDup);
	}
	
	if (!bResult)
	{		
		Log2Msi(_T("CCA- DuplicateTokenEx(%s %s exitcode: %d) !"), lpApplicationName,lpCommandLine, ::GetLastError() );
	}
	
	
	//Adjust Token privilege
	SetTokenInformation(hUserTokenDup,
        TokenSessionId,(void*)&dwSessionId,sizeof(DWORD));
	
	if (!AdjustTokenPrivileges(hUserTokenDup,FALSE,&tp,sizeof(TOKEN_PRIVILEGES),
		(PTOKEN_PRIVILEGES)NULL,NULL))
	{		
		dwExitCode = ::GetLastError();
		Log2Msi(_T("CCA- AdjustTokenPrivileges(%s %s exitcode: %d) !"), lpApplicationName,lpCommandLine, dwExitCode );
	}
	

	if (bResult)
	{
		// 使用CreateProcessAsUser来采用当前进程的token值来模拟运行.		
		// Initialize the STARTUPINFO structure.
	
		ZeroMemory(&si, sizeof(STARTUPINFO));
		ZeroMemory(&pi, sizeof(pi));
		si.cb= sizeof(STARTUPINFO);			
		si.dwFlags|=STARTF_USESHOWWINDOW;
		si.wShowWindow=nCmdShow;
		bResult =CreateProcessAsUser(
			hUserTokenDup,                     // client's access token
			NULL,    // file to execute
			commandLine,                 // command line
			NULL,            // pointer to process SECURITY_ATTRIBUTES
			NULL,               // pointer to thread SECURITY_ATTRIBUTES
			FALSE,              // handles are not inheritable
			0,     // creation flags
			NULL,               // pointer to new environment block
			NULL,               // name of current directory
			&si,               // pointer to STARTUPINFO structure
			&pi                // receives information about new process
			);
	
	}	
    if( bResult )
    { 		
	
		::WaitForSingleObject(pi.hProcess ,dwInterval);		
        ::GetExitCodeProcess(pi.hProcess , &dwExitCode);
		if (pi.hThread != INVALID_HANDLE_VALUE)
			CloseHandle(pi.hThread); 
        ::CloseHandle(pi.hProcess );
		 
		if (hPToken != INVALID_HANDLE_VALUE)
			CloseHandle(hPToken);  
		if (hUserTokenDup != INVALID_HANDLE_VALUE)
			CloseHandle(hUserTokenDup); 
		
    }
    else
    {
        dwExitCode = ::GetLastError();
		Log2Msi(_T("CCA- CreateProcessAsUser(%s %s exitcode: %d) !"), lpApplicationName,lpCommandLine, dwExitCode );
    }
	
	//RunShellExecuteEx(_T("C:\\Users\\u8plat\\AppData\\Local\\Temp\\ufmsi\\reg.exe"),commandLine,nCmdShow,dwInterval);
	Log2Msi(_T("CCA- RunShellExecute(%s %s exitcode: %d) !"), lpApplicationName,lpCommandLine, dwExitCode );
    return dwExitCode;
}


DWORD GetProcessReturn(LPCTSTR lpApplicationName, LPTSTR lpCommandLine,WORD nCmdShow,DWORD dwInterval =INFINITE)
{
	if (IsVista())
		return RunShellExecute(lpApplicationName,lpCommandLine,nCmdShow,dwInterval);
	else
		return RunCommand(lpApplicationName,lpCommandLine,nCmdShow,dwInterval);	 
	
}
//得到BinaryFile的绝对路径 nCreateFile=0 不创建文件 =1 创建文件
void BinaryFileTempPath(MSIHANDLE hInstall,LPCTSTR lpszBinaryFielName,LPTSTR szTempFile,WORD nCreateFile=0)
{	
    Log2Msi("GetBinaryFile Relative Path %s",szTempFile);
	Log2Msi("GetBinaryFile Relative Path %s",lpszBinaryFielName);
	UINT uRes = 0;
    TCHAR szTempPath[MAX_PATH];
	TCHAR szTempFile1[MAX_PATH];
    //TCHAR szTempFile[MAX_PATH];     
    ZeroMemory(szTempPath, sizeof(szTempPath));
    // get path to the temp directory
    DWORD dwRes = GetTempPath(MAX_PATH, szTempPath);
    ZeroMemory(szTempFile, sizeof(szTempFile));
	ZeroMemory(szTempFile1, sizeof(szTempFile1));
    /*
    if (dwRes) 
        uRes = GetTempFileName(szTempPath, _T("uf"), 0, szTempFile);
    if (!dwRes || !uRes)
    {        
		
        Log2Msi(_T("GetTempFileName failed"));		
		return ;
    }
	wsprintf (szTempFile,  _T("%s.exe"), szTempFile);
	*/
    //add .exe extension to the name of the temp file
	
	
	if(szTempPath[lstrlen(szTempPath)-1] == '\\') 
		wsprintf(szTempPath,  _T("%sufmsi"),szTempPath);
	else
		wsprintf(szTempPath,  _T("%s\\ufmsi"),szTempPath);
	
	if (PathFileExists(szTempPath) == FALSE)
	{
		if (!CreateDirectory(szTempPath, NULL) ) 
		{ 		
			Log2Msi(_T("CreateDirectory failed"));
		}		
	}	
	Log2Msi("%s",szTempPath);
	Log2Msi("%s.exe",lpszBinaryFielName);	
	wsprintf (szTempFile,  _T("%s\\%s.exe"),szTempPath, lpszBinaryFielName);
	//添加兼容性注册表。
	HKEY  hKey = NULL;
	char* szVal=_T("WINSRV03SP1");
    DWORD   dwSize = _tcslen(szVal) * sizeof(TCHAR);
    LPCTSTR  lpKey = _T("Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers");
    DWORD dwAccess = KEY_ALL_ACCESS;
    //RegCreateKeyEx(hRootKey, lpszRegPath, 0, NULL, REG_OPTION_NON_VOLATILE, dwAccess, NULL, &hKey, NULL)
	GetLongPathName(szTempFile,szTempFile1,MAX_PATH);
	
	
    if (::RegCreateKeyEx(HKEY_CURRENT_USER,lpKey,NULL,NULL,REG_OPTION_NON_VOLATILE, dwAccess,NULL, &hKey,NULL)== ERROR_SUCCESS )
    {
	    Log2Msi("GetLongPathName:%s",szTempFile1);
		
        if (::RegSetValueEx(hKey,szTempFile1,NULL,REG_SZ,(CONST BYTE*)szVal,dwSize) == ERROR_SUCCESS )
		{
		  Log2Msi(_T("Set Register Success HKEY_CURRENT_USER\\Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers"));
		}
		
        //if (::RegSetValueEx(hKey,szTempFile,NULL,REG_SZ,(CONST BYTE*)szVal,dwSize) == ERROR_SUCCESS )
		//{
		//  Log2Msi(_T("Set Register Success Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers"));
		//}
		
		RegCloseKey(hKey);
		hKey = NULL;
    }
	
	
	if (::RegCreateKeyEx(HKEY_LOCAL_MACHINE,lpKey,NULL,NULL,REG_OPTION_NON_VOLATILE, dwAccess,NULL, &hKey,NULL)== ERROR_SUCCESS )
    {
	    Log2Msi("GetLongPathName:%s",szTempFile1);
		
        if (::RegSetValueEx(hKey,szTempFile1,NULL,REG_SZ,(CONST BYTE*)szVal,dwSize) == ERROR_SUCCESS )
		{
		  Log2Msi(_T("Set Register Success HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers"));
		}
		/*
		if (::RegSetValueEx(hKey,szTempFile,NULL,REG_SZ,(CONST BYTE*)szVal,dwSize) == ERROR_SUCCESS )
		{
		  Log2Msi(_T("Set Register Success Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers"));
		}
		*/
		RegCloseKey(hKey);
		hKey = NULL;
    }
	Log2Msi(szTempFile);
    // create the actual temp file and get its handle. We'll use the handle to write data to 
    // this file.
    
    // Get handle to msi database	
    if(nCreateFile==0)
	{
	     Log2Msi(_T("nCreateFile==0 不创建文件"));
	     return;
	}
	if(PathFileExists(szTempFile) != FALSE)
	{
	   DeleteFile(szTempFile);
	   Log2Msi(_T("删除老的文件,让新的文件可以覆盖:%s"),szTempFile);
	}
    PMSIHANDLE hDB;
    hDB  = MsiGetActiveDatabase(hInstall);
    if (NULL == hDB)
    {
		Log2Msi(_T("MsiGetActiveDatabase failed"));
		//return szTempFile;
		return ;
    }
    // prepare query to retrieve the WDS setup binary from the MSI package.
    PMSIHANDLE hView;
    
	TCHAR cmdText[512] = {0};
	//wsprintf(cmdText, _T("SELECT `Data` FROM `Binary` WHERE `Name` = 'gacutil' "), lpszBinaryFielName);//WHERE `Name` = 'gacutil'
    wsprintf(cmdText, _T("SELECT `Data` FROM `Binary` WHERE `Name` = '%s' "), lpszBinaryFielName);//WHERE `Name` = 'gacutil'
	
	
    if (ERROR_SUCCESS != MsiDatabaseOpenView(hDB, 
        cmdText, 
        &hView)
        ||
        ERROR_SUCCESS != MsiViewExecute(hView, 0))	
    {  		
		// add code for logging the failure if needed
		Log2Msi(_T("MsiDatabaseOpenView:%s failed"),cmdText);
		//return szTempFile;
		return ;
    }
    // Fetch data from query result
    PMSIHANDLE hRec;
    uRes = MsiViewFetch(hView, &hRec);
    if (uRes != ERROR_SUCCESS)
    {        
		// add code for logging the failure if needed
		Log2Msi(_T("MsiViewFetch failed:%s error:%d"),cmdText,uRes);
		//return szTempFile;
		return ;
    } 

    // extract binary data from windows desktop search setup record
	HANDLE hFile = 0; 
    hFile = CreateFile(szTempFile, GENERIC_WRITE, 0, NULL,
        CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if (INVALID_HANDLE_VALUE == hFile)
    {
        // add code for logging the failure if needed
		Log2Msi(_T("CreateFile:%s failed"),szTempFile);
		//return szTempFile;
		return ;
    }
    char szBuff[MAX_BUFFER*2];
    DWORD dwBuffSize;
    DWORD dwBytesWritten;
    do {
        // Extract binary data to buffer
        dwBuffSize = MAX_BUFFER*2;
        uRes = MsiRecordReadStream(hRec, 1, szBuff, &dwBuffSize);
        if (ERROR_SUCCESS != uRes)
        {
            // add code for logging the failure if needed
			Log2Msi(_T("MsiRecordReadStream failed"));
            break;
        }
        if(dwBuffSize)
        {
            // write the chunk of the binary data to disk
            if ( !WriteFile(hFile, szBuff, dwBuffSize, &dwBytesWritten, NULL) )
            {
                // add code for logging the failure if needed
				Log2Msi(_T("WriteFile failed"));
                break;
            }
        }
    } 
    while (dwBuffSize > 0);
    CloseHandle(hFile);	
	::MsiViewClose(hView);
	::MsiCloseHandle(hRec);    	
	::MsiCloseHandle(hDB);
	
	Log2Msi(_T("szTempFile:%s"),szTempFile);
    
	return ;
}

void rollbackSingleFile(LPCTSTR src)
{
	TCHAR*	pBuffer		= NULL;
	DWORD	cchData		= 0;
	UINT	uiState		= ERROR_SUCCESS;
	
	const TCHAR* szStep = _T("#");
	TCHAR	pszLine[MAX_PATH] = {0};
	TCHAR*	pszShortName= NULL;
	TCHAR*	pszFileKey	= NULL;
	TCHAR*  pszFlag		= NULL;
	TCHAR	pszFullFileKey[MAX_PATH+1] = {0};
	//TCHAR	pszFullFileKey[MAX_PATH+1] = {0};

	lstrcpy(pszLine, src);
	pszShortName	= _tcstok(pszLine, szStep);
	pszFileKey		= _tcstok(NULL, szStep);
	pszFlag			= _tcstok(NULL, szStep);

	if (pszShortName == NULL || pszFileKey == NULL)
	{
		Log2Msi(_T("CCA- Invalid Parameters!"));
		return;
	}

	Log2Msi(_T("CCA- Rollback Single File Begin"));

	for (LPTSTR pszFetoh=pszFileKey; pszFetoh != NULL && *pszFetoh != _T('\0'); pszFetoh++)
	{
		if ((*pszFetoh) == _T('-'))
			(*pszFetoh) = _T('_');
	}

	wsprintf(pszFullFileKey, _T("[#%s]"), pszFileKey);
	PMSIHANDLE hRec = ::MsiCreateRecord(1);
	::MsiRecordSetString(hRec, 0, pszFullFileKey);

	uiState = ::MsiFormatRecord(g_hInstall, hRec, _T(""), &cchData);
	if (uiState == ERROR_MORE_DATA)
	{
		pBuffer = new TCHAR[++cchData];
		
		uiState = ::MsiFormatRecord(g_hInstall, hRec, pBuffer, &cchData);
		if (uiState == ERROR_SUCCESS)
		{
			//
			// 构造源文件全路径
			//
			TCHAR szSourceFilePath[MAX_PATH+1] = {0};
			wsprintf(szSourceFilePath, _T("%s%s"), g_lpszBackupFilesPath, src);

			
			//
			// 还原文件
			// 
			if (!MoveFileEx(szSourceFilePath, pBuffer, MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING))
			{
				Log2Msi(_T("CCA- MoveFileEx(%s,%s) failed! 0x%08X"), szSourceFilePath, pBuffer, GetLastError());

				//
				// 移动文件失败,可能的原因是文件正在使用,要求重新启动操作系统
				// 以便在重起后,移动文件
				TCHAR dir[_MAX_DIR];				
				_tsplitpath(pBuffer,NULL,dir,NULL,NULL);
				if (PathFileExists(dir) == FALSE && CreateDirectory(dir, NULL))
				{
					if (!MoveFileEx(szSourceFilePath, pBuffer, MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING))
					{
						Log2Msi(_T("CCA- MoveFileEx(%s,%s) failed! 0x%08X"), szSourceFilePath, pBuffer, GetLastError());
						g_fNeedReBoot = TRUE;					
						MoveFileEx(szSourceFilePath, pBuffer, MOVEFILE_DELAY_UNTIL_REBOOT | MOVEFILE_REPLACE_EXISTING);
					}
				}
				else
				{
					g_fNeedReBoot = TRUE;					
					MoveFileEx(szSourceFilePath, pBuffer, MOVEFILE_DELAY_UNTIL_REBOOT | MOVEFILE_REPLACE_EXISTING);
				}
				
				
			}
			else
				Log2Msi(_T("CCA- MoveFileEx(%s,%s) successed!"), szSourceFilePath, pBuffer);
	
			if (pszFlag != NULL)
			{
				if ((pszFlag[0] == _T('R') || pszFlag[0] == _T('r')) && (pszFlag[1] == _T('G') || pszFlag[1] == _T('g')))
				{
					//
					// 注册COM组件,失败写入日志, 直接调用DllRegisterServer将COM信息写入注册表
					//
					if(RegisterDllOcx(pBuffer))
						Log2Msi(_T("CCA- RegisterDllOcx(%s) successed!"), szSourceFilePath);
				
				}
				if ((pszFlag[0] == _T('G') || pszFlag[0] == _T('g')) && (pszFlag[1] == _T('C') || pszFlag[1] == _T('c')))
				{
					//
					// 注册到GAC中,失败写入日志,直接调用gacutil将dll信息写入GAC中
					//
					TCHAR	strCommandLine[MAX_PATH+1]		= {0};
					//wsprintf(strCommandLine,_T("-i %s -f"),pBuffer);
					wsprintf(strCommandLine,_T("-ir \"%s\" OPAQUE \"UFIDA U8 CUSTOM\" \"UFIDA U8 INSTALL\" -f"),pBuffer);
					
			
					
					TCHAR strTmpFile[MAX_PATH];
					BinaryFileTempPath(g_hInstall,_T("gacutil"),strTmpFile,1);					
					if (GetProcessReturn(
						strTmpFile,strCommandLine, SW_HIDE)==0)
						{
							DeleteFile(strTmpFile);							
							Log2Msi(_T("CCA- GetProcessReturn(gacutil.exe,%s) successed!"), strCommandLine );
						}
					
					
				}
			}

		}
	}
	RELEASE(pBuffer)	
	MsiCloseHandle(hRec);

	Log2Msi(_T("CCA- Rollback Single File End"));
}


//
//
// 
//
BOOL rollbackFiles(LPCTSTR lpszPath)
{
	TCHAR	szFullPath[MAX_PATH+1]		= {0};
	TCHAR	szSourceFile[MAX_PATH+1]	= {0};		// 源文件路经
	TCHAR	szDestFile[MAX_PATH+1]		= {0};		// 目标文件路经
	UINT	nFlag						= 0;		// 处理类型

	WIN32_FIND_DATA FindFileData;
	HANDLE	hFind = NULL;

	lstrcpy(szFullPath, lpszPath);
	lstrcat(szFullPath, _T("*.*"));

	Log2Msi(_T("CCA- ReadBackFiles Begin!"));

	hFind = FindFirstFile(szFullPath, &FindFileData);

	if (hFind != INVALID_HANDLE_VALUE)
	{
		while (1)
		{
			Log2Msi(_T("CCA- Process file:%s!"), FindFileData.cFileName);
			if (!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
			{
				rollbackSingleFile(FindFileData.cFileName);
			}
			
			if (!FindNextFile(hFind, &FindFileData))
				break;
		}
	}
	Log2Msi(_T("CCA- ReadBackFiles End!"));
	return TRUE;
}

//
// RollbackBackupFiles
//
//		尝试着还原安装前已经备份的原始文件
// 
UINT __stdcall RollbackBackupFiles(MSIHANDLE hInstall)
{
	//
	// 假设不需要重新启动操作系统
	//
	g_fNeedReBoot	= FALSE;
	g_hInstall		= hInstall;

	Log2Msi(_T("CCA- RollbackBackupFiles Begin!"));

	if (getBackupFilesPath(hInstall))
		rollbackFiles(g_lpszBackupFilesPath);

	//
	// clean up
	//
	RELEASE(g_lpszBackupFilesPath);

	
	//
	// 通知安装包反安装完成后,因为一些文件无法覆盖,
	// 需要重新启动操作系统
	//
	if (g_fNeedReBoot)
	{
		::MsiSetProperty(hInstall, _T("REBOOT"), _T("Force"));
	}

	Log2Msi(_T("CCA- RollbackBackupFiles End!"));

	return ERROR_SUCCESS;
}

UINT __stdcall SetRegPolicyScopeValue(MSIHANDLE hInstall)
{
    g_hInstall=hInstall;
    Log2Msi(_T("SetRegPolicyScopeValue Start!"));
    HKEY	hKey = NULL;
	DWORD   dwVal = 1;
	DWORD	dwSize = sizeof(dwVal);
	TCHAR lpKey[] = _T("SOFTWARE\\Policies\\Microsoft\\windows\\safer\\codeidentifiers");
	DWORD dwAccess = KEY_ALL_ACCESS;
	
	//HKLM	SOFTWARE\\Policies\\Microsoft\\windows\\safer\\codeidentifiers	integer	PolicyScope	00000001
	//RegCreateKeyEx(hRootKey, lpszRegPath, 0, NULL, REG_OPTION_NON_VOLATILE, dwAccess, NULL, &hKey, NULL)

	if ( ::RegCreateKeyEx( HKEY_LOCAL_MACHINE,lpKey,NULL,NULL,REG_OPTION_NON_VOLATILE, dwAccess,NULL, &hKey,NULL)	!= ERROR_SUCCESS )
	{
		Log2Msi(_T("SetRegPolicyScopeValue CreateKey Failed!"));
		return FALSE;
	}
	
	if ( ::RegSetValueEx( hKey,_T("PolicyScope"),NULL,REG_DWORD,(LPBYTE)&dwVal,dwSize) != ERROR_SUCCESS )
	{
		RegCloseKey(hKey);
		hKey = NULL;
		Log2Msi(_T("SetRegPolicyScopeValue SetValue Failed!"));
		return FALSE;
	}
	
	if (hKey)
	{
		RegCloseKey(hKey);
		hKey = NULL;
	}
	Log2Msi(_T("SetRegPolicyScopeValue Suc!"));
	
	Log2Msi(_T("net stop msiserver start !"));
	TCHAR	strCommandLine[MAX_PATH+1]		= {0};	
    wsprintf(strCommandLine,_T(" stop msiserver"));
    GetProcessReturn(_T("net.exe"),strCommandLine, SW_SHOW,60000);
	Log2Msi(_T("net stop msiserver end  !"));
	
	Log2Msi(_T("net start msiserver start !"));
	TCHAR	strCommandLinestart[MAX_PATH+1]		= {0};	
    wsprintf(strCommandLinestart,_T(" start msiserver"));
    GetProcessReturn(_T("net.exe"),strCommandLinestart, SW_SHOW,60000);
	Log2Msi(_T(" net start msiserver end  !"));
	
	return TRUE;
}
//
// DependChecked
//
// 补丁依赖性检查
//
UINT __stdcall DependChecked(MSIHANDLE hInstall)
{
	TCHAR*	szCAData	= NULL;
	TCHAR*	szRegPath	= NULL;
	TCHAR*	szCurr		= NULL;
	BOOL	fChecked	= FALSE;
	TCHAR	szBuffer[1024]	= {0};
	UINT	uiRet		= ERROR_SUCCESS;

//	Log2Msi(_T("CCA- DependChecked Start!"));

	//uiRet = ERROR_INSTALL_USEREXIT;
	return uiRet;

	szCAData = getProperty(hInstall, PROPERTYNAME_DEPENDLIST);
	szRegPath = getProperty(hInstall, PROPERTYNAME_PATCHREGROOT);
	
	if ((szCAData != NULL || szRegPath != NULL) && lstrlen(szCAData) > 0)
	{
		szCurr = szCAData;
		for (LPTSTR p=szCAData; *p != _T('\0'); p++)
		{
			if (*p == _T(','))
			{
				*p = _T('\0');
				wsprintf(szBuffer, _T("%s\\%%s"), szRegPath, szCurr);

				Log2Msi(_T("CCA- DependCheck %s"), szBuffer);
				
				if (lstrlen(szBuffer) > 0)
				{
					HKEY hKey;
					if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szBuffer, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
					{
						fChecked = TRUE;
						break;
					}
					RegCloseKey(hKey);
				}
				
				szCurr = p+1;
			}
		}
	}

	if (fChecked)
	{
		eMessageType = INSTALLMESSAGE_FATALEXIT;
		Log2Msi(_T("[ProductName] 无法安装,因为相关补丁[dependlist]不存在"));
		eMessageType = INSTALLMESSAGE_INFO;
		uiRet = ERROR_INSTALL_USEREXIT;
	}
	
	//::MsiSetProperty(hInstall, _T("DependChecked"), (fChecked ? _T("1") : _T("0")));

	Log2Msi(_T("CCA- DependChecked End!"));
	return uiRet;
}


//得到补丁的问题号
BOOL getSPIDValue(MSIHANDLE hInstall)
{
	g_spid = getProperty(hInstall, _T("SPID") );	
	return (g_spid != NULL);	
/*
	TCHAR*	szCAData	= NULL;
	DWORD	cchCAData	= 0;
	UINT	uiState		= ERROR_SUCCESS;

	//
	// 尝试获取属性的长度,然后分配内存
	//
	uiState = ::MsiGetProperty(hInstall, _T("SPID"), _T(""), &cchCAData);

	if (uiState == ERROR_MORE_DATA)
	{
		//
		// 分配内存
		//
		g_spid = new TCHAR[++cchCAData];
		
		//
		// 得到属性值
		//
		uiState = ::MsiGetProperty(hInstall, _T("SPID"), g_spid, &cchCAData);
		if (uiState != ERROR_SUCCESS)
		{
			//
			// 失败释放内存,返回失败
			//
			RELEASE(g_spid)			
			return FALSE;
		}

		return TRUE;
	}
	else
	{
		return FALSE;
	}
	*/

}

//得到DBEnginSys的路径
BOOL DBEnginSysPath(MSIHANDLE hInstall)
{
	/*
	TCHAR*	szCAData	= NULL;
	DWORD	cchCAData	= 0;
	DWORD	cchData	= 0;
	UINT	uiState		= ERROR_SUCCESS;
	TCHAR*	pBuffer		= NULL;
	*/	

	TCHAR*	pBuffer		= NULL;
	pBuffer= getProperty(hInstall, _T("TARGETDIR") );
	
	if (pBuffer != NULL)
	{
		g_dbEnginPath = new TCHAR[MAX_PATH];
		
		if(pBuffer[lstrlen(pBuffer)-1] == '\\') //删除结尾的'\'
			wsprintf(g_dbEnginPath, _T("%s%s"), pBuffer,"Admin\\UFDBTMP\\DBEnginSys.exe");
		else
			wsprintf(g_dbEnginPath, _T("%s%s"), pBuffer,"\\Admin\\UFDBTMP\\DBEnginSys.exe");		
	}
    RELEASE(pBuffer);
	return (g_dbEnginPath != NULL);

	//
	// 尝试获取属性的长度,然后分配内存
	//
   /*
	uiState = ::MsiGetProperty(hInstall, _T("DBEnginSysPath"), _T(""), &cchCAData);

	if (uiState == ERROR_MORE_DATA)
	{
		//
		// 分配内存
		//
		pBuffer = new TCHAR[++cchCAData];		
		//
		// 得到属性值
		//
		uiState = ::MsiGetProperty(hInstall, _T("DBEnginSysPath"), pBuffer, &cchCAData);
		if (uiState != ERROR_SUCCESS)
		{
			//
			// 失败释放内存,返回失败
			//
			
			//TCHAR szError[1024] = {0};
			//wsprintf(szError, _T("%d %s"), uiState, pBuffer);
			//OutputDebugString(szError);
			
			RELEASE(pBuffer);			
			return FALSE;
		}		
		//OutputDebugString(pBuffer);
	}	
	 
	PMSIHANDLE hRec = ::MsiCreateRecord(1);
	::MsiRecordSetString(hRec, 0, pBuffer);	

	uiState = ::MsiFormatRecord(hInstall, hRec, _T(""), &cchData);	
	
	if (uiState == ERROR_MORE_DATA)
	{		
		
		g_dbEnginPath = new TCHAR[++cchData];		
		uiState = ::MsiFormatRecord(hInstall, hRec, g_dbEnginPath, &cchData);		
		if (uiState != ERROR_SUCCESS)
		{
			RELEASE(pBuffer)
			RELEASE(g_dbEnginPath);			
			return FALSE;
		}		
		//OutputDebugString(g_dbEnginPath); 
	}	
	RELEASE(pBuffer)
	MsiCloseHandle(hRec);
	return TRUE;
	*/
	
}


//得到DSetPatchInfoToSqlLite的路径
BOOL DSetPatchInfoToSqlLitePath(MSIHANDLE hInstall)
{

	TCHAR*	pBuffer		= NULL;
	pBuffer= getProperty(hInstall, _T("TARGETDIR") );
	
	if (pBuffer != NULL)
	{
		g_sqllitepathinfoPath = new TCHAR[MAX_PATH];
		
		if(pBuffer[lstrlen(pBuffer)-1] == '\\') //删除结尾的'\'
			wsprintf(g_sqllitepathinfoPath, _T("%s%s"), pBuffer,"3rdPrograms\\UFFileInformation\\SetPatchInfoToSqlLite.exe");
		else
			wsprintf(g_sqllitepathinfoPath, _T("%s%s"), pBuffer,"\\3rdPrograms\\UFFileInformation\\SetPatchInfoToSqlLite.exe");		
	}
    RELEASE(pBuffer);
	return (g_sqllitepathinfoPath != NULL);
}

//得到DSetPatchInfoToSqlLite的路径
BOOL DSetPatchInfoToSqlLitePathUninstall(MSIHANDLE hInstall)
{

	TCHAR*	pBuffer		= NULL;
	pBuffer= getProperty(hInstall, _T("TARGETDIR") );
	
	if (pBuffer != NULL)
	{
		g_exerunPath = new TCHAR[MAX_PATH];
		
		if(pBuffer[lstrlen(pBuffer)-1] == '\\') //删除结尾的'\'
			wsprintf(g_exerunPath, _T("%s%s"), pBuffer,"3rdPrograms\\UFFileInformation\\SetPatchInfoToSqlLiteUninstall.exe");
		else
			wsprintf(g_exerunPath, _T("%s%s"), pBuffer,"\\3rdPrograms\\UFFileInformation\\SetPatchInfoToSqlLiteUninstall.exe");		
	}
    RELEASE(pBuffer);
	return (g_exerunPath != NULL);
}

/*
//临时增加的方法,执行U8Login.msi的卸载操作
UINT __stdcall ExcuteU8LoginMSI(MSIHANDLE hInstall)
{    
	Log2Msi(_T("CCA- ExcuteU8LoginMSI") );
	CoInitialize(NULL);
    BOOL bRet = FALSE;	
    try
    {
        _bstr_t bAppName = _bstr_t(_T("U8Login"));
        ICOMAdminCatalogPtr spCatalog("COMAdmin.COMAdminCatalog");
        ICatalogCollectionPtr spApplications;
        spApplications = spCatalog->GetCollection (L"Applications");
        spApplications->Populate ();
        
        LONG count = 0;
        spApplications->get_Count(&count);
        for(INT i=0;i<count;i++)
        {
            HRESULT hr;
            ICatalogObject* pObject = NULL;
            hr = spApplications->get_Item(i,(IDispatch**)&pObject);
            if(hr==S_OK)
            {
                VARIANT vName;
                pObject->get_Name(&vName);
                _bstr_t bName = _bstr_t(vName.bstrVal);
                if(bName==bAppName)
                {
                    spApplications->Remove(i);
                }
                pObject->Release();
            }
        }
        
        HRESULT hr = spApplications->SaveChanges();
        
        bRet = SUCCEEDED(hr);
    }
    catch(_com_error& err)
    {
	    Log2Msi(_T("ComPlus U8login error: %s!"),err.Description());
		
    }
    catch(...)
    {
		Log2Msi(_T("ComPlus U8login error, LastError:0x%08X "),GetLastError());	

    }	
    CoUninitialize();    
	return ERROR_SUCCESS;	
}
*/	

//
//执行数据库引擎,
UINT __stdcall ExcuteDBEnginSys(MSIHANDLE hInstall)
{
	//
	g_hInstall=hInstall;		
	DWORD flag		  = -1;

	TCHAR*	pDBServer		= NULL;
	pDBServer= getProperty(hInstall, _T("FDBC") );
	//如果不是数据库服务器不需要执行脚本
	
	if (pDBServer == NULL || lstrlen(pDBServer)== 0)
	{
		RELEASE(pDBServer); 	
		return ERROR_SUCCESS;

	}
	
	
	RELEASE(pDBServer); 
	if (getSPIDValue(hInstall)  &&  DBEnginSysPath(hInstall))
	{
		TCHAR	strCommandLine[MAX_PATH+1]		= {0};
		wsprintf(strCommandLine,_T("-q -n:%s"),g_spid);
		OutputDebugString(strCommandLine);
		OutputDebugString(g_dbEnginPath); 
		flag		  =GetProcessReturn(g_dbEnginPath,strCommandLine,SW_SHOW);
		if (flag==0)
		{
			::MsiSetProperty(hInstall, _T("EXCUTEDBENGINSYS"), _T("1"));
			OutputDebugString("EXCUTEDBENGINSYS:1");
		}
		else
		{
		::MsiSetProperty(hInstall, _T("EXCUTEDBENGINSYS"), _T("0"));
		OutputDebugString("EXCUTEDBENGINSYS:0");
		}
	}
	
	RELEASE(g_spid); 
	RELEASE(g_dbEnginPath);
	return ERROR_SUCCESS;
}


void _stdcall CreateGUID(LPTSTR str)
{
	GUID guid;
	unsigned char* p;
	::CoInitialize(NULL);
	
	::CoCreateGuid(&guid);
	::UuidToString(&guid, &p);
	_stprintf(str, _T("{%s%}"), (char*)p);
	_strupr(str);
	::RpcStringFree(&p);
	
	::CoUninitialize();
}

//添加卸载后注册表 GUID
BOOL SetSmartClientGUIDRegister(MSIHANDLE hInstall)
{
    g_hInstall=hInstall;
	OutputDebugString("SetSmartClientGUIDRegister Start!");
    Log2Msi(_T("SetSmartClientGUIDRegister Start!"));
    HKEY	hKey = NULL;
	//char* szVal=_T("WINSRV03SP1");
	TCHAR buff [256] = {0};
	CreateGUID(buff);
	//char* szVal = getProperty(hInstall, _T("ProductCode") );
	char* szVal=buff;
    DWORD   dwSize = _tcslen(szVal) * sizeof(TCHAR);
	TCHAR lpKey[] = _T("SOFTWARE\\Ufsoft\\WF\\V8.700\\Install\\SmartGuid");
	DWORD dwAccess = KEY_ALL_ACCESS;
	
    //[HKEY_LOCAL_MACHINE\SOFTWARE\Ufsoft\WF\V8.700\Install\SmartGuid]
    //"smartclient"="150661EA-AF70-4038-8E5C-F2C80BFE1D6B"


	if ( ::RegCreateKeyEx( HKEY_LOCAL_MACHINE,lpKey,NULL,NULL,REG_OPTION_NON_VOLATILE, dwAccess,NULL, &hKey,NULL)	!= ERROR_SUCCESS )
	{
	    OutputDebugString("SetSmartClientGUIDRegister CreateKey Failed!");
		Log2Msi(_T("SetSmartClientGUIDRegister CreateKey Failed!"));
		return FALSE;
	}
	
	if ( ::RegSetValueEx( hKey,_T("smartclient"),NULL,REG_SZ,(CONST BYTE*)szVal,dwSize) != ERROR_SUCCESS )
	{
		RegCloseKey(hKey);
		hKey = NULL;
		OutputDebugString("SetSmartClientGUIDRegister SetValue Failed!");
		Log2Msi(_T("SetSmartClientGUIDRegister SetValue Failed!"));
		return FALSE;
	}
	
	if (hKey)
	{
		RegCloseKey(hKey);
		hKey = NULL;
	}
	Log2Msi(_T("SetSmartClientGUIDRegister Suc!"));

	return TRUE;
}
//安装前执行文件信息导入数据库引擎, SetPatchInfoToSqlLite.exe
UINT __stdcall ExcuteSqlLiteSys(MSIHANDLE hInstall)
{
	g_hInstall=hInstall;		
	DWORD flag		  = -1;
    OutputDebugString("ExcuteSqlLiteSys");
	if ( getSPIDValue(hInstall)  &&  DSetPatchInfoToSqlLitePath(hInstall))
	{
		TCHAR	strCommandLine[MAX_PATH+1]		= {0};
		wsprintf(strCommandLine,_T("-install %s"),g_spid);
		OutputDebugString(strCommandLine);
		OutputDebugString(g_sqllitepathinfoPath); 
		flag		  =GetProcessReturn(g_sqllitepathinfoPath,strCommandLine,SW_SHOW);
		if (flag==0)
		{
			::MsiSetProperty(hInstall, _T("EXCUTESQLLITESYS"), _T("1"));
			OutputDebugString("EXCUTESQLLITESYS:1");
                        //设置注册表。
	                 DWORD dwExitCode = -1; 
	                 try
                         { 
	                   SetSmartClientGUIDRegister(hInstall);
	                 }
	                 catch(...)
                         {
		           dwExitCode=::GetLastError();
		           Log2Msi(_T("SetSmartClientGUIDRegister  error, LastError:0x%08X "),dwExitCode);	
                         }
		}
		else
		{
		::MsiSetProperty(hInstall, _T("EXCUTESQLLITESYS"), _T("0"));
		OutputDebugString("EXCUTESQLLITESYS:0");
		}
	}
	
	RELEASE(g_spid); 
	RELEASE(g_sqllitepathinfoPath);

	return ERROR_SUCCESS;
}



//安装后执行EXE SetPatchInfoToSqlLite.exe
UINT __stdcall UninstallExcuteEnginSys(MSIHANDLE hInstall)
{
	//设置注册表。
	DWORD dwExitCode = -1; 
	try
    { 
	  SetSmartClientGUIDRegister(hInstall);
	}
	catch(...)
    {
		dwExitCode=::GetLastError();
		Log2Msi(_T("Remove  SetSmartClientGUIDRegister  error, LastError:0x%08X "),dwExitCode);	
    }
	g_hInstall=hInstall;		
	DWORD flag		  = -1;
        OutputDebugString("UninstallExcuteEnginSys");
	if (getSPIDValue(hInstall) &&  DSetPatchInfoToSqlLitePathUninstall(hInstall))
	{
		TCHAR	strCommandLine[MAX_PATH+1]		= {0};
		wsprintf(strCommandLine,_T("-uninstall %s"),g_spid);
		OutputDebugString(strCommandLine);
		OutputDebugString(g_exerunPath); 
		flag		  =GetProcessReturn(g_exerunPath,strCommandLine,SW_SHOW);
		if (flag==0)
		{
			::MsiSetProperty(hInstall, _T("EXCUTEEXESYS"), _T("1"));
			OutputDebugString("EXCUTEEXESYS:1");
		}
		else
		{
		    ::MsiSetProperty(hInstall, _T("EXCUTEEXESYS"), _T("0"));
		    OutputDebugString("EXCUTEEXESYS:0");
		}
	}
	
	RELEASE(g_spid); 
	RELEASE(g_exerunPath);
	return ERROR_SUCCESS;
}




LONG GetFileDateTime(LPCTSTR fileName,tm& filetm)
{
		WIN32_FILE_ATTRIBUTE_DATA fileData;
		BOOL result = ::GetFileAttributesEx(fileName, GetFileExInfoStandard, &fileData);
		if (result == FALSE)
		{
			//OutputDebugString(_T("GetFileAttributesEx call false"));	
			return ::GetLastError();
		}

		FILETIME filetime = fileData.ftLastWriteTime;
		SYSTEMTIME systime;
		FILETIME localtime;
		::FileTimeToLocalFileTime(&filetime, &localtime);
		::FileTimeToSystemTime(&localtime, &systime);
		filetm.tm_year = systime.wYear- 1900;
		filetm.tm_mon = systime.wMonth - 1;
		filetm.tm_mday = systime.wDay;
		filetm.tm_hour = systime.wHour;
		filetm.tm_min = systime.wMinute;
		filetm.tm_sec = systime.wSecond;
		filetm.tm_isdst=-1;
	//	wsprintf(buf, _T("%4d%02d%02d%02d%02d%02d"),systime.wYear, systime.wMonth, systime.wDay
	//		,systime.wHour, systime.wMinute, systime.wSecond);
				
		return 0;
}
//
// CompareFileDateTime
//
//	比较安装盘文件和系统已经存在文件的新旧,srcFileName指安装包的文件,desFileName指本机已经存在的文件
// 
LONG CompareFileDateTime(LPCTSTR srcFileName, LPCTSTR desFileName,LPCTSTR remove)
{
	LPTSTR srcTime = _tcsrchr(srcFileName, _T('.'));
	srcTime++;
	//TCHAR desTime[15]={0};
	struct   tm   destm;
	//if (desFileName==NULL ||lstrlen(desFileName)==0)  return -1;
	//如果文件名查找不到,采用默认策略,不处理,目前出现的问题是放到GAC的文件,在本地没有副本
	Log2Msi(_T("desFileName %s!"),desFileName);
	//if (desFileName==NULL ||lstrlen(desFileName)==0)  return -1;
	if (desFileName==NULL ||lstrlen(desFileName)==0)  return 1;
	LONG hr = ::GetFileDateTime(desFileName, destm);	
     //如果 remove=ALL 删除文件。	
	if (remove != NULL && lstrlen(remove)!= 0 && _tcscmp(remove,_T("ALL"))==0)
	{		
		if (hr != 0) //卸载安装包的时候,虽然本机文件出错,但安装包的文件一定不能安装
		{
			return -1;		
		}
	}
	else
	{
		if (hr != 0) //如果本机文件出错,要求安装包的文件一定要安装
			return 1;
	}
	struct   tm   srctm;
	time_t   srctimet,destimet; 
  
	_stscanf(srcTime," %4d%02d%02d%02d%02d%02d",&srctm.tm_year,&srctm.tm_mon,&srctm.tm_mday,&srctm.tm_hour,&srctm.tm_min,&srctm.tm_sec);  

	srctm.tm_year=srctm.tm_year-1900;
	srctm.tm_mon=srctm.tm_mon-1;
	srctm.tm_isdst =-1;	
	srctimet=mktime(&srctm);  
	destimet=mktime(&destm);	
	//srcTime[12] = _T('\0');
	//desTime[12] = _T('\0');
	//result=srctimet(MSI包中的文件的日期)-destimet(本地计算机上已经存在的文件的日期)
	double result   =difftime(srctimet,destimet);    
	
	if ( result > -61.0 && result < 61.0) 
	{
		return 0;
	}
	else
	{
		return (LONG)result;
	}
	//return _tcscmp(srcTime, desTime);
}


//
// GetSetupFileSets
//得到需要安装的文件集合
//	
// 
void GetSetupFileSets(MSIHANDLE hInstall)
{

	TCHAR* setupfilepath=NULL;
	TCHAR* spid=NULL;
	TCHAR*	pBuffer		= NULL;
	pBuffer= getProperty(hInstall, _T("TARGETDIR") );
	
	if (pBuffer != NULL)
	{
		setupfilepath = new TCHAR[MAX_PATH];
		spid = getProperty(hInstall, _T("SPID") );
		if (spid != NULL)
		{

		if(pBuffer[lstrlen(pBuffer)-1] == '\\') //删除结尾的'\'
			wsprintf(setupfilepath, _T("%s%s%s%s"), pBuffer,_T("Installer\\"),spid,_T(".config"));
		else
			wsprintf(setupfilepath, _T("%s%s%s%s"), pBuffer,_T("\\Installer\\"),spid,_T(".config"));
		}
		OutputDebugString(_T("setupfilepath%s"));
		OutputDebugString(setupfilepath); 
	}
    RELEASE(pBuffer);
	RELEASE(spid);
	char SetupFile[255];
    ifstream fin(setupfilepath);
	if (fin)
	{
		while(fin.getline(SetupFile, 255))
		{
			g_setupfilesets.insert(_strlwr(SetupFile)); 
		}
	}
	RELEASE(setupfilepath);
	
}

//对于那些需要保留老状态的情况,需要区分安装和卸载两种情况
void RetainComponentState(MSIHANDLE hInstall,LPCTSTR lpszComponentName,LPCTSTR remove,LPCTSTR srcfilePath)
{
	if (remove != NULL && lstrlen(remove)!= 0 && _tcscmp(remove,_T("ALL"))==0)					
	{
		::MsiSetComponentState(hInstall,lpszComponentName,INSTALLSTATE_ABSENT);
		Log2Msi(_T("remove=ALL,uninstalled.%s"),srcfilePath);					
	}
    else
	{
		Log2Msi(_T("retain old state:%s"),srcfilePath);
	}				
}

//
// CompareFileDate
//
//	解决安装盘文件和系统已经存在文件的新旧问题,如果系统已经存在文件的修改日期较新,则不覆盖
// 
UINT __stdcall CompareFilesDate(MSIHANDLE hInstall)
{
    g_hInstall=hInstall;
	//Log2Msi(_T("CCA- CompareFilesDate Begin!"));

	
	UINT	uiState		= ERROR_SUCCESS;
	PMSIHANDLE hRecordprop=NULL;     
	TCHAR*	remove		= NULL;
	TCHAR*	comparedate		= NULL;//是否需要比较文件日期.="N",不进行日期对比 缺省情况下进行日期对比
	TCHAR*	depend		= NULL;//是否是依赖安装=1 依赖安装 =0 完全安装 缺省情况下完全安装
	TCHAR*	caremove		= NULL;
    
	PMSIHANDLE hDB=NULL;
	PMSIHANDLE	hViewprop=NULL;
	
	comparedate= getProperty(hInstall, _T("CACOMPAREDATE") );
	depend= getProperty(hInstall, _T("CADEPEND") );
	caremove= getProperty(hInstall, _T("CAREMOVE") );
	Log2Msi(_T("property CACOMPAREDATE:%s CADEPEND:%s"),comparedate,depend);
	//不需要日期对比,且不是依赖安装,直接退出函数.提高效率
	if (comparedate != NULL && lstrlen(comparedate)!= 0 && _tcscmp(comparedate,_T("N"))==0)
	{		
		if  (depend == NULL || lstrlen(depend)== 0 ||_tcscmp(depend,_T("0"))==0)
		 {
			 return ERROR_SUCCESS;
		 }
	}
	
	remove= getProperty(hInstall, _T("REMOVE") );
	//依赖安装
	if  (depend != NULL &&  _tcscmp(depend,_T("1"))==0)
	{
		GetSetupFileSets(hInstall);//获得需要安装的文件集合
	}
	
    hDB = ::MsiGetActiveDatabase(hInstall);     
    ::MsiDatabaseOpenView(hDB,
        _T("SELECT * FROM `File`"), &hViewprop);
    ::MsiViewExecute(hViewprop, 0);     
    while (::MsiViewFetch(hViewprop, &hRecordprop) != ERROR_NO_MORE_ITEMS)
	{
        
		DWORD	cchData	= 0;
		DWORD	ccData	= 0;		
		TCHAR		srcfilePath[MAX_PATH]={0};
		ccData=sizeof(srcfilePath) ;
		::MsiRecordGetString(hRecordprop, 1, srcfilePath, &ccData);
		OutputDebugString(srcfilePath); 
		
		TCHAR		componentName[MAX_PATH]={0};
		ccData=sizeof(componentName) ;
		::MsiRecordGetString(hRecordprop, 2, componentName, &ccData);
		TCHAR	pszFullFileKey[MAX_PATH+3] = {0};	
		wsprintf(pszFullFileKey, _T("[#%s]"), srcfilePath);
		PMSIHANDLE hRec = ::MsiCreateRecord(1);
		::MsiRecordSetString(hRec, 0, pszFullFileKey);			
		uiState = ::MsiFormatRecord(hInstall, hRec, _T(""), &cchData);	
					
		if (uiState == ERROR_MORE_DATA)
		{			
			TCHAR*		desfilePath = new TCHAR[++cchData];						
			uiState = ::MsiFormatRecord(hInstall, hRec, desfilePath, &cchData);		
			if (uiState != ERROR_SUCCESS)
			{
				RELEASE(desfilePath);			
				return ERROR_SUCCESS;
			}
			Log2Msi(_T("desfilePath:%s"),desfilePath);	
            //安装依赖文件			
			if  (depend != NULL && _tcscmp(depend,_T("1"))==0)
			{			
				set<string>::iterator it = g_setupfilesets.find(_strlwr(desfilePath));
				if( g_setupfilesets.size()==0 ||it != g_setupfilesets.end()  ) //等于end就是没有找到
				{
					//::MsiGetComponentState(hInstall,componentName,&piInstalled,&piAction);			
					//Log2Msi(_T("Get Component %s State.%d %d"),srcfilePath,piInstalled,piAction);	
					//不比较日期 comparedate=N
					if (comparedate != NULL && lstrlen(comparedate)!= 0 && _tcscmp(comparedate,_T("N"))==0)
					{
						//Log2Msi(_T("not compare date.retain old state:%s"),srcfilePath);
						//保留老的状态。
						RetainComponentState(hInstall,componentName,remove,srcfilePath);
					}
					else
					{
						LONG flag=CompareFileDateTime(srcfilePath,desfilePath,remove);
						//=符号,强制覆盖,为了修改安装,不卸载文件使用
						if(flag<0)			
						{
							if (remove != NULL && lstrlen(remove)!= 0 && _tcscmp(remove,_T("ALL"))==0 
								&& caremove != NULL && lstrlen(caremove)!= 0 &&_tcscmp(caremove,_T("NO"))==0
								&& flag!=-1)
							{
							    //INSTALLSTATE_LOCAL ==The component is installed locally.
								::MsiSetComponentState(hInstall,componentName,INSTALLSTATE_LOCAL);
								//如果本地文件比安装盘文件新,则不允许安装盘卸载此文件
								Log2Msi(_T("flag<0,don't remove1.%s"),srcfilePath);
							}
							else
							{
							    //INSTALLSTATE_ABSENT==The component is not installed.
								::MsiSetComponentState(hInstall,componentName,INSTALLSTATE_ABSENT);
								Log2Msi(_T("flag<0,uninstalled1.%s"),srcfilePath);
							}
							//Log2Msi(_T("flag<0,uninstalled.%s"),srcfilePath);					
						}
						else if(flag==0)
						{
							//Log2Msi(_T("flag>=0.retain old state:%s"),srcfilePath);
							//如果remove=all 执行 INSTALLSTATE_ABSENT     不处理;安装不处理。
							RetainComponentState(hInstall,componentName,remove,srcfilePath);
						}
						else
						{
						     //保留老的状态。
							Log2Msi(_T("flag>0.retain old state:%s"),srcfilePath);
						}
					}								
				}
				else
				{
				    //此组件不安装  INSTALLSTATE_ABSENT==The component is not installed.
					::MsiSetComponentState(hInstall,componentName,INSTALLSTATE_ABSENT);
					Log2Msi(_T("this file doesn't exist in config file ,uninstalled.%s"),srcfilePath);						
				}
			}
			//不是依赖安装
			else
			{
				LONG flag=CompareFileDateTime(srcfilePath,desfilePath,remove);	
				//本地文件比较新
				if(flag<0)			
				{
				    //卸载
					if (remove != NULL && lstrlen(remove)!= 0 && _tcscmp(remove,_T("ALL"))==0 
						&& caremove != NULL && lstrlen(caremove)!= 0 &&_tcscmp(caremove,_T("ALL"))==0
						&& flag!=-1)
					{
					    //如果本地文件比安装盘文件新,替换安装到本地新的文件。
						::MsiSetComponentState(hInstall,componentName,INSTALLSTATE_LOCAL);
						//如果本地文件比安装盘文件新,则不允许安装盘卸载此文件
						Log2Msi(_T("flag<0,don't remove2.%s"),srcfilePath);
					}
					else
					{
					    //如果是安装,不安装此文件 保持本地文件新的。
						::MsiSetComponentState(hInstall,componentName,INSTALLSTATE_ABSENT);
						Log2Msi(_T("flag<0,uninstalled2.%s"),srcfilePath);
					}					
					//::MsiSetComponentState(hInstall,componentName,INSTALLSTATE_ABSENT);
					//Log2Msi(_T("flag<0,uninstalled.%s"),srcfilePath);					
				}
				else if (flag==0)
				{
					//Log2Msi(_T("flag>=0.retain old state:%s"),srcfilePath);	
					//如果remove=all 执行 INSTALLSTATE_ABSENT   保留老的状态 相反替换。
					RetainComponentState(hInstall,componentName,remove,srcfilePath);
				}
				else
				{
					Log2Msi(_T("flag>0.retain old state:%s"),srcfilePath);						
				}	
			}
			RELEASE(desfilePath)
		}   
		::MsiCloseHandle(hRec); 
	}  
    
    ::MsiViewClose(hViewprop);
	::MsiCloseHandle(hRecordprop);
	::MsiCloseHandle(hDB);
	RELEASE(remove); 
	RELEASE(comparedate); 
	RELEASE(depend); 
	RELEASE(caremove);
	//Log2Msi(_T("CCA- CompareFilesDate End!"));

	return ERROR_SUCCESS;
}

//得到File的绝对路径
void FilePath(MSIHANDLE hInstall,LPCTSTR lpszFileKey,LPTSTR szFilePath)
{
	TCHAR	pszFullFileKey[MAX_PATH+3] = {0};	
	UINT	uiState		= ERROR_SUCCESS;
	DWORD	cchData	= 0;
	wsprintf(pszFullFileKey, _T("[#%s]"), lpszFileKey);
	PMSIHANDLE hRec = ::MsiCreateRecord(1);
	::MsiRecordSetString(hRec, 0, pszFullFileKey);			
	uiState = ::MsiFormatRecord(hInstall, hRec, _T(""), &cchData);	
	if (uiState == ERROR_MORE_DATA)
	{			
					
		uiState = ::MsiFormatRecord(hInstall, hRec, szFilePath, &cchData);		
		if (uiState == ERROR_SUCCESS)
		{
			
			Log2Msi(_T("szFilePath:%s"),szFilePath);
		}
		
	}
}
//卸载COm+服务,即使文件丢失也可以
DWORD UninstallCOMPLUS(LPCTSTR lpApplicationName)
{
	DWORD dwExitCode = -1;	
	CoInitialize(NULL);
    BOOL bRet = FALSE;	
    try
    {
        _bstr_t bAppName = _bstr_t(lpApplicationName);
        ICOMAdminCatalogPtr spCatalog("COMAdmin.COMAdminCatalog");
        ICatalogCollectionPtr spApplications;
        spApplications = spCatalog->GetCollection (L"Applications");
        spApplications->Populate ();        
        LONG count = 0;
        spApplications->get_Count(&count);
        for(INT i=0;i<count;i++)
        {
            HRESULT hr;
            ICatalogObject* pObject = NULL;
            hr = spApplications->get_Item(i,(IDispatch**)&pObject);
            if(hr==S_OK)
            {
                VARIANT vName;
                pObject->get_Name(&vName);
                _bstr_t bName = _bstr_t(vName.bstrVal);
                if(bName==bAppName)
                {
                    spApplications->Remove(i);
                }
                pObject->Release();
            }
        }
        
        HRESULT hr = spApplications->SaveChanges();
        
        bRet = SUCCEEDED(hr);
    }
    catch(_com_error& err)
    {
		dwExitCode=err.WCode();
		//dwExitCode=_com_error::WCodeToHRESULT(err.WCode());
		Log2Msi(_T("Remove %s ComPlus  error: %s!"),err.Description());
		
    }
    catch(...)
    {
		dwExitCode=::GetLastError();
		Log2Msi(_T("Remove %s ComPlus  error, LastError:0x%08X "),lpApplicationName,dwExitCode);	

    }	
    CoUninitialize(); 
     
    return dwExitCode;
}
//安装结束,执行注册GAC等操作,通过属性传递相应的参数
/*
UINT __stdcall ExcuteApp(MSIHANDLE hInstall)
{
	TCHAR*	filepath		= NULL;
	TCHAR*	remove		= NULL;	
	
	g_hInstall=hInstall;
    Log2Msi(_T("CCA- ExcuteApp"));
	DWORD flag		  = -1;	
	
	filepath= getProperty(hInstall, _T("file_gacutil") );
	Log2Msi(_T("CCA- ExcuteApp%s"),filepath);
	const TCHAR* szStep = _T("#");
	TCHAR*	pszFileKey	= NULL;
	
	remove= getProperty(hInstall, _T("REMOVE") );
	//如果查找不到,不需要处理
	if (filepath != NULL && lstrlen(filepath)!= 0)
	{
		
		//TCHAR	pszFullFileKey[MAX_PATH+1] = {0};
		pszFileKey	= _tcstok(filepath, szStep);
		TCHAR strTmpFile[MAX_PATH];
		BinaryFileTempPath(hInstall,_T("gacutil"),strTmpFile);
		while (pszFileKey != NULL)
		{
			
			// 注册到GAC中,失败写入日志,直接调用gacutil将dll信息写入GAC中
			//
			TCHAR	strCommandLine[MAX_PATH+1]		= {0};
			TCHAR strFilePath[MAX_PATH];

			FilePath(hInstall,pszFileKey,strFilePath);
			if (remove != NULL && lstrlen(remove)!= 0 && _tcscmp(remove,_T("ALL"))==0)
			{
				TCHAR fname[MAX_PATH];
				
				_tsplitpath(strFilePath,NULL,NULL,fname,NULL);
				wsprintf(strCommandLine,_T("-ur \"%s\" OPAQUE \"UFIDA U8 CUSTOM\" \"UFIDA U8 INSTALL\" -f"),fname);
				GetProcessReturn(strTmpFile,strCommandLine, SW_HIDE,60000);
			}
			else
			{
				wsprintf(strCommandLine,_T("-ir \"%s\" OPAQUE \"UFIDA U8 CUSTOM\" \"UFIDA U8 INSTALL\" -f "),strFilePath);
				if (PathFileExists(strFilePath) != FALSE)
				{
					Log2Msi(_T("GetProcessReturn PathFileExists true"));
					GetProcessReturn(strTmpFile,strCommandLine, SW_HIDE,60000);
				}
			}			
			
			//Log2Msi(_T("CCA- GetProcessReturn(gacutil.exe,%s) successed!"), strCommandLine );
			pszFileKey		= _tcstok(NULL, szStep);
		}		
		//DeleteFile(strTmpFile);			
	}
	RELEASE(filepath);
	if (remove == NULL || lstrlen(remove)== 0 || _tcscmp(remove,_T("ALL"))!=0)
	{
		filepath= getProperty(hInstall, _T("file_regasm") );
		//如果查找不到,不需要处理
		
		if (filepath != NULL && lstrlen(filepath)!= 0)
		{		
			pszFileKey	= _tcstok(filepath, szStep);
			TCHAR strTmpFile[MAX_PATH];
			BinaryFileTempPath(hInstall,_T("RegAsm"),strTmpFile);			
			while (pszFileKey != NULL)
			{		
				
				TCHAR	strCommandLine[MAX_PATH+1]		= {0};
				TCHAR strFilePath[MAX_PATH];
				FilePath(hInstall,pszFileKey,strFilePath);				
				if (PathFileExists(strFilePath) != FALSE)
				{
					wsprintf(strCommandLine,_T("\"%s\"  /codebase /silent"),strFilePath);			
					GetProcessReturn(strTmpFile,strCommandLine, SW_HIDE,60000);
				}
				//if (GetProcessReturn(strTmpFile,strCommandLine, SW_HIDE)==0)
				//	Log2Msi(_T("CCA- GetProcessReturn(RegAsm.exe,%s) successed!"), strCommandLine );
				pszFileKey		= _tcstok(NULL, szStep);
			}
			//DeleteFile(strTmpFile);			
		}
		RELEASE(filepath);
		
		
		filepath= getProperty(hInstall, _T("file_regasm40") );
		//如果查找不到,不需要处理
		
		if (filepath != NULL && lstrlen(filepath)!= 0)
		{		
			pszFileKey	= _tcstok(filepath, szStep);
			TCHAR strTmpFile[MAX_PATH];
			BinaryFileTempPath(hInstall,_T("RegAsm40"),strTmpFile);			
			while (pszFileKey != NULL)
			{		
				
				TCHAR	strCommandLine[MAX_PATH+1]		= {0};
				TCHAR strFilePath[MAX_PATH];
				FilePath(hInstall,pszFileKey,strFilePath);				
				if (PathFileExists(strFilePath) != FALSE)
				{
					wsprintf(strCommandLine,_T("\"%s\"  /codebase /silent"),strFilePath);			
					GetProcessReturn(strTmpFile,strCommandLine, SW_HIDE,60000);
				}
				//if (GetProcessReturn(strTmpFile,strCommandLine, SW_HIDE)==0)
				//	Log2Msi(_T("CCA- GetProcessReturn(RegAsm.exe,%s) successed!"), strCommandLine );
				pszFileKey		= _tcstok(NULL, szStep);
			}
			//DeleteFile(strTmpFile);			
		}
		RELEASE(filepath);
		
	}
	filepath= getProperty(hInstall, _T("file_regsvcs") );
	//filepath= getProperty(hInstall, _T("CustomActionData") );
	Log2Msi(_T("CCA- ExcuteApp-regsvcs%s"),filepath);
	//如果查找不到,不需要处理	
	if (filepath != NULL && lstrlen(filepath)!= 0)
	{
		
		
		pszFileKey	= _tcstok(filepath, szStep);
		TCHAR strTmpFile[MAX_PATH];

		BinaryFileTempPath(hInstall,_T("RegSvcs"),strTmpFile);
		//wsprintf(strTmpFile,_T("C:\\U8SOFT\\RegSvcs.exe"));
		while (pszFileKey != NULL)
		{
			
			// 注册到complus中,失败写入日志,直接调用regsvcs将dll信息写入com+中
			//
			TCHAR	strCommandLine[MAX_PATH+1]		= {0};
			TCHAR strFilePath[MAX_PATH];
			FilePath(hInstall,pszFileKey,strFilePath);
			if (remove != NULL && lstrlen(remove)!= 0 && _tcscmp(remove,_T("ALL"))==0)
			{				
				TCHAR drive[_MAX_DRIVE];
				TCHAR dir[_MAX_DIR];
				TCHAR fname[_MAX_FNAME];
				TCHAR tlbfilePath[_MAX_PATH];
				_tsplitpath(strFilePath,drive, dir, fname, NULL);
				UninstallCOMPLUS(fname);
				_tmakepath(tlbfilePath,drive, dir, fname, _T("tlb") );
				DeleteFile(tlbfilePath);
			}
			else
			{			   
				if (PathFileExists(strFilePath) != FALSE)
				{
					wsprintf(strCommandLine,_T("/fc /quiet \"%s\" "),strFilePath);
					GetProcessReturn(strTmpFile,strCommandLine, SW_HIDE);
					
				}
			}
			
			pszFileKey		= _tcstok(NULL, szStep);
		}
		//DeleteFile(strTmpFile);			
	}
	RELEASE(filepath); 
	RELEASE(remove); 
	return ERROR_SUCCESS;

}
*/
UINT __stdcall ExcuteApp(MSIHANDLE hInstall)
{
	TCHAR*	filepath		= NULL;
	TCHAR*	ProcessEXE		= NULL;	
	TCHAR*	CustomActionData = NULL;
	TCHAR*	remove		= NULL;	
	TCHAR* strFilePath= NULL;
	
	const TCHAR* szStepSpace = _T("   ");
	const TCHAR* szStep = _T("|");
	TCHAR*	pszFileKey	= NULL;	
	g_hInstall=hInstall;
    Log2Msi(_T("CCA- ExcuteApp"));
	DWORD flag		  = -1;	

	filepath = new TCHAR[MAX_PATH*50];
	ProcessEXE = new TCHAR[MAX_PATH];
	remove= new TCHAR[MAX_PATH];
	
	CustomActionData=getProperty(hInstall, _T("CustomActionData") );
	Log2Msi(_T("CCA- ExcuteApp CustomActionData:%s"),CustomActionData);
	if (CustomActionData != NULL && lstrlen(CustomActionData)!= 0)
	{
	
		pszFileKey	= _tcstok(CustomActionData, szStepSpace);	
		//Log2Msi(_T("CCA- ExcuteApp pszFileKey:%s"),pszFileKey);
		while (pszFileKey != NULL)
		{			
			if (_tcsstr(pszFileKey,_T("/REMOVE="))!=NULL)
			{				
				_tcscpy(remove,pszFileKey+8);				
				Log2Msi(_T("CCA- ExcuteApp remove:%s"),remove);
			}
			if (_tcsstr(pszFileKey,_T("/EXE=")) != NULL) 
			{
				_tcscpy(ProcessEXE,pszFileKey+5);
				Log2Msi(_T("CCA- ExcuteApp ProcessEXE:%s"),ProcessEXE);
			}
			if (_tcsstr(pszFileKey,_T("/FILEPATH=")) != NULL) 
			{
				_tcscpy(filepath,pszFileKey+10);				
				Log2Msi(_T("CCA- ExcuteApp filepath:%s"),filepath);
			}
			pszFileKey		= _tcstok(NULL, szStepSpace);
			Log2Msi(_T("CCA- ExcuteApp pszFileKey:%s"),pszFileKey);
		}
	}
	//TCHAR strFilePath[MAX_PATH];
	
	//如果查找不到,不需要处理
	if (filepath != NULL && lstrlen(filepath)!= 0)
	{
	
		strFilePath	= _tcstok(filepath, szStep);
		TCHAR strTmpFile[MAX_PATH];
		Log2Msi(_T("GetRegisterExe: %s"),ProcessEXE);
		BinaryFileTempPath(hInstall,ProcessEXE,strTmpFile,0);
        Log2Msi(_T("GetRegisterExe: %s %s"),strTmpFile,ProcessEXE);			
		while (strFilePath != NULL)
		{
			
			// 注册到GAC中,失败写入日志,直接调用gacutil将dll信息写入GAC中
			//
			TCHAR	strCommandLine[MAX_PATH+1]		= {0};			

			if (ProcessEXE != NULL && lstrlen(ProcessEXE)!= 0 && _tcscmp(ProcessEXE,_T("gacutil"))==0)
			{
				if (remove != NULL && lstrlen(remove)!= 0 && _tcscmp(remove,_T("ALL"))==0)
				{
					TCHAR fname[MAX_PATH];				
					_tsplitpath(strFilePath,NULL,NULL,fname,NULL);
					wsprintf(strCommandLine,_T("-ur \"%s\" OPAQUE \"UFIDA U8 CUSTOM\" \"UFIDA U8 INSTALL\" -f"),fname);
					GetProcessReturn(strTmpFile,strCommandLine, SW_HIDE,60000);
				}
				else
				{
					wsprintf(strCommandLine,_T("-ir \"%s\" OPAQUE \"UFIDA U8 CUSTOM\" \"UFIDA U8 INSTALL\" -f "),strFilePath);
					if (PathFileExists(strFilePath) != FALSE)
					{
						Log2Msi(_T("GetProcessReturn PathFileExists true"));
						GetProcessReturn(strTmpFile,strCommandLine, SW_HIDE,60000);
					}
				}		
			}
			if (ProcessEXE != NULL && lstrlen(ProcessEXE)!= 0 && _tcscmp(ProcessEXE,_T("RegAsm"))==0)
			{
				if (remove == NULL || lstrlen(remove)== 0 || _tcscmp(remove,_T("ALL"))!=0)
				{
					if (PathFileExists(strFilePath) != FALSE)
					{
						wsprintf(strCommandLine,_T("\"%s\"  /codebase /silent"),strFilePath);	
					    Log2Msi(_T("Ready to Register: %s"),strCommandLine);						
						GetProcessReturn(strTmpFile,strCommandLine, SW_HIDE,60000);
						Log2Msi(_T("End to Register: %s %s"),strTmpFile,strCommandLine);	
					}
				}
			}
			//v4.0.30319版本呢的RegAsm.exe生成TLB注册信息
			if (ProcessEXE != NULL && lstrlen(ProcessEXE)!= 0 && _tcscmp(ProcessEXE,_T("RegAsm40"))==0)
			{
				if (remove == NULL || lstrlen(remove)== 0 || _tcscmp(remove,_T("ALL"))!=0)
				{
					if (PathFileExists(strFilePath) != FALSE)
					{
						wsprintf(strCommandLine,_T("\"%s\"  /codebase /silent"),strFilePath);	
					    Log2Msi(_T("Ready to Register: %s"),strCommandLine);						
						GetProcessReturn(strTmpFile,strCommandLine, SW_HIDE,60000);
						Log2Msi(_T("End to Register: %s %s"),strTmpFile,strCommandLine);	
					}
				}
			}
			if (ProcessEXE != NULL && lstrlen(ProcessEXE)!= 0 && _tcscmp(ProcessEXE,_T("RegSvcs"))==0)
			{
				if (remove != NULL && lstrlen(remove)!= 0 && _tcscmp(remove,_T("ALL"))==0)
				{				
					TCHAR drive[_MAX_DRIVE];
					TCHAR dir[_MAX_DIR];
					TCHAR fname[_MAX_FNAME];
					TCHAR tlbfilePath[_MAX_PATH];
					_tsplitpath(strFilePath,drive, dir, fname, NULL);
					UninstallCOMPLUS(fname);
					_tmakepath(tlbfilePath,drive, dir, fname, _T("tlb") );
					DeleteFile(tlbfilePath);
				}
				else
				{			   
					if (PathFileExists(strFilePath) != FALSE)
					{
						wsprintf(strCommandLine,_T("/fc /quiet \"%s\" "),strFilePath);
						GetProcessReturn(strTmpFile,strCommandLine, SW_HIDE);
						
					}
				}
			}			
			strFilePath		= _tcstok(NULL, szStep);
		}					
	}	
	RELEASE(filepath);	
	RELEASE(ProcessEXE);
	RELEASE(CustomActionData);
	RELEASE(remove); 
	RELEASE(strFilePath);
	
	return ERROR_SUCCESS;

}
//安装结束,对于COM组件(EXE),使用/RegServer或-RegServer注册,通过属性传递相应的参数
//或者对于一些注册不成功的COM,使用regsvr32注册
UINT __stdcall ExcuteRegServer(MSIHANDLE hInstall)
{
	g_hInstall=hInstall;
	DWORD flag		  = -1;	
	TCHAR*	filepath_regserver		= NULL;
	TCHAR*	filepath_regsvr32		= NULL;
	TCHAR*	CustomActionData	= NULL;
	TCHAR*	remove		= NULL;	
	const TCHAR* szStep = _T("|");
	//const TCHAR* szStepSpace = _T("\t");//\t
	const TCHAR* szStepSpace =  _T("   ");//
	TCHAR*	pszFileKey	= NULL;
	TCHAR* strFilePath		=NULL;
	filepath_regserver = new TCHAR[MAX_PATH*50];
	filepath_regsvr32 = new TCHAR[MAX_PATH*50];	
	remove= new TCHAR[MAX_PATH];

	CustomActionData=getProperty(hInstall, _T("CustomActionData") );
	Log2Msi(_T("CCA- ExcuteApp CustomActionData:%s"),CustomActionData);
	if (CustomActionData != NULL && lstrlen(CustomActionData)!= 0)
	{		
		pszFileKey	= _tcstok(CustomActionData, szStepSpace);	
		while (pszFileKey != NULL)
		{
			
			if (_tcsstr(pszFileKey,_T("/REMOVE="))!=NULL)
			{				
				_tcscpy(remove,pszFileKey+8);				
			}
			if (_tcsstr(pszFileKey,_T("/REGSERVER=")) != NULL) 
			{
				_tcscpy(filepath_regserver,pszFileKey+11);				
			}
			if (_tcsstr(pszFileKey,_T("/REGSVR=")) != NULL) 
			{
				_tcscpy(filepath_regsvr32,pszFileKey+8);				
			}
			pszFileKey		= _tcstok(NULL, szStepSpace);
		}
	}

	if (remove == NULL || lstrlen(remove)== 0 || _tcscmp(remove,_T("ALL"))!=0)
	{			
		//如果查找不到,不需要处理
		if (filepath_regserver != NULL && lstrlen(filepath_regserver)!= 0)
		{		
			strFilePath	= _tcstok(filepath_regserver, szStep);
			
			while (strFilePath != NULL)
			{				
				int retval;
				
				retval=PathFileExists(strFilePath);
				if (retval==1 )
				{					
					GetProcessReturn(strFilePath,_T("/RegServer"), SW_HIDE);
				}
				strFilePath		= _tcstok(NULL, szStep);
			}				
		}	
	}
	
	//如果查找不到,不需要处理	
	if (filepath_regsvr32 != NULL && lstrlen(filepath_regsvr32)!= 0)
	{
		strFilePath	= _tcstok(filepath_regsvr32, szStep);		
		while (strFilePath != NULL)
		{	
			
			TCHAR	strCommandLine[MAX_PATH+1]		= {0};			
			if (remove != NULL && lstrlen(remove)!= 0 && _tcscmp(remove,_T("ALL"))==0)
			{
				TCHAR fname[MAX_PATH];
				TCHAR ext[_MAX_EXT];
				TCHAR dllfilePath[_MAX_PATH];
				_tsplitpath(strFilePath,NULL,NULL,fname,ext);
				_tmakepath(dllfilePath,NULL,NULL, fname, ext);
				wsprintf(strCommandLine,_T("/u /s \"%s\" "),dllfilePath);
				GetProcessReturn(_T("RegSvr32.exe"),strCommandLine, SW_HIDE);
			}
			else
			{
				int retval;
				retval=PathFileExists(strFilePath);
				if (retval==1 )
				{
					wsprintf(strCommandLine,_T("/s \"%s\" "),strFilePath);
					GetProcessReturn(_T("RegSvr32.exe"),strCommandLine, SW_HIDE);
				}
			}			
			strFilePath		= _tcstok(NULL, szStep);
		}	
	}
	RELEASE(filepath_regserver); 
	RELEASE(filepath_regsvr32);
	RELEASE(strFilePath);
    RELEASE(pszFileKey);
	RELEASE(remove); 
	return ERROR_SUCCESS;
	
}
/*
UINT __stdcall ExcuteRegServer(MSIHANDLE hInstall)
{
	g_hInstall=hInstall;
	DWORD flag		  = -1;	
	TCHAR*	filepath		= NULL;
	TCHAR*	remove		= NULL;	
	const TCHAR* szStep = _T("#");
	TCHAR*	pszFileKey	= NULL;
	remove= getProperty(hInstall, _T("REMOVE") );
	if (remove == NULL || lstrlen(remove)== 0 || _tcscmp(remove,_T("ALL"))!=0)
	{
		filepath= getProperty(hInstall, _T("file_regserver") );		
		//如果查找不到,不需要处理
		if (filepath != NULL && lstrlen(filepath)!= 0)
		{		
			pszFileKey	= _tcstok(filepath, szStep);		
			while (pszFileKey != NULL)
			{			
				TCHAR strFilePath[MAX_PATH];
				FilePath(hInstall,pszFileKey,strFilePath);
				int retval;
				retval=PathFileExists(strFilePath);
				if (retval==1 )
				{
								
					GetProcessReturn(strFilePath,_T("/RegServer"), SW_HIDE);
				}
				pszFileKey		= _tcstok(NULL, szStep);
			}				
		}	
	}

	filepath= getProperty(hInstall, _T("file_regsvr32") );
	//如果查找不到,不需要处理	
	if (filepath != NULL && lstrlen(filepath)!= 0)
	{
		pszFileKey	= _tcstok(filepath, szStep);		
		while (pszFileKey != NULL)
		{	
			
			TCHAR	strCommandLine[MAX_PATH+1]		= {0};
			TCHAR strFilePath[MAX_PATH];
			FilePath(hInstall,pszFileKey,strFilePath);
			if (remove != NULL && lstrlen(remove)!= 0 && _tcscmp(remove,_T("ALL"))==0)
			{
				TCHAR fname[MAX_PATH];
				TCHAR ext[_MAX_EXT];
				TCHAR dllfilePath[_MAX_PATH];
				_tsplitpath(strFilePath,NULL,NULL,fname,ext);
				_tmakepath(dllfilePath,NULL,NULL, fname, ext);
				wsprintf(strCommandLine,_T("/u /s \"%s\" "),dllfilePath);
				GetProcessReturn(_T("RegSvr32.exe"),strCommandLine, SW_HIDE);
			}
			else
			{
				int retval;
				retval=PathFileExists(strFilePath);
				if (retval==1 )
				{
					wsprintf(strCommandLine,_T("/s \"%s\" "),strFilePath);
					GetProcessReturn(_T("RegSvr32.exe"),strCommandLine, SW_HIDE);
				}
			}			
			pszFileKey		= _tcstok(NULL, szStep);
		}	
	}
	RELEASE(filepath); 
    RELEASE(pszFileKey);
	RELEASE(remove); 
	return ERROR_SUCCESS;
	
}

*/
//
// 
//
//	解决安装盘清除文件速度慢的问题
// 
UINT __stdcall RemoveAllFiles(MSIHANDLE hInstall)
{
    g_hInstall=hInstall;		
	UINT	uiState		= ERROR_SUCCESS; 
	UINT	uiState1		= ERROR_SUCCESS;
	PMSIHANDLE hDB=NULL;
	PMSIHANDLE	hViewprop=NULL;
	PMSIHANDLE hRecordprop=NULL;     
	//TCHAR*	remove		= NULL;
	INSTALLSTATE piInstalled;
	INSTALLSTATE piAction;
	
	//remove= getProperty(hInstall, _T("REMOVE") );
	
    hDB = ::MsiGetActiveDatabase(hInstall);     
    ::MsiDatabaseOpenView(hDB,
        _T("SELECT * FROM `File`"), &hViewprop);
    ::MsiViewExecute(hViewprop, 0); 
    uiState1=::MsiViewFetch(hViewprop, &hRecordprop);
	Log2Msi(_T("MsiViewFetch uiState1:%d"),uiState1);	
    //while(uiState1!= ERROR_NO_MORE_ITEMS && uiState1== ERROR_SUCCESS ) 
	while(uiState1== ERROR_SUCCESS ) 
	{ 		
		DWORD	cchData	= 0;
		DWORD	ccData	= 0;			
		TCHAR		componentName[MAX_PATH]={0};
		ccData=sizeof(componentName) ;
		::MsiRecordGetString(hRecordprop, 2, componentName, &ccData);		
		uiState=::MsiGetComponentState(hInstall,componentName,&piInstalled,&piAction);	
		Log2Msi(_T("Get Component %s State.%d %d"),componentName,piInstalled,piAction);
		
		if (uiState == ERROR_SUCCESS && piInstalled ==INSTALLSTATE_LOCAL && piAction ==INSTALLSTATE_ABSENT)
		{ 
			TCHAR		srcfilePath[MAX_PATH]={0};
			ccData=sizeof(srcfilePath) ;

			::MsiRecordGetString(hRecordprop, 1, srcfilePath, &ccData);		
			TCHAR	pszFullFileKey[MAX_PATH+3] = {0};	
			wsprintf(pszFullFileKey, _T("[#%s]"), srcfilePath);
			PMSIHANDLE hRec = ::MsiCreateRecord(1);
			::MsiRecordSetString(hRec, 0, pszFullFileKey);			
			uiState = ::MsiFormatRecord(hInstall, hRec, _T(""), &cchData);	
						
			if (uiState == ERROR_MORE_DATA)
			{		
				
				WCHAR*		desfilePath = new WCHAR[++cchData];						
				uiState = ::MsiFormatRecordW(hInstall, hRec, desfilePath, &cchData);		
				if (uiState != ERROR_SUCCESS)
				{
					RELEASE(desfilePath);			
					return ERROR_SUCCESS;
				}
					
				if( DeleteFileW(desfilePath) == FALSE)
				{
					Log2Msi(_T("CCA- RemoveAllFiles(%s) failed! 0x%08X"), desfilePath, GetLastError());					
					MoveFileExW(desfilePath,NULL,MOVEFILE_DELAY_UNTIL_REBOOT);
				}				
				RELEASE(desfilePath)
			} 
			::MsiCloseHandle(hRec); 
		}
		uiState1=MsiViewFetch(hViewprop, &hRecordprop);
		Log2Msi(_T("MsiViewFetch state:%d"),uiState1);
	}      
    ::MsiViewClose(hViewprop);
	::MsiCloseHandle(hRecordprop);
	::MsiCloseHandle(hDB);
	
	return ERROR_SUCCESS;
}

//
//判断MSI包是否允许执行;从11.0之后的补丁只允许在ISD中执行,不能手工安装(zhengzy)
//不用了。
UINT __stdcall MSICanInstall(MSIHANDLE hInstall)
{
	OutputDebugString(_T("begin MSICanInstall"));	
	TCHAR*	pBuffer		= NULL;
	pBuffer= getProperty(hInstall, _T("TARGETDIR") );
	
	TCHAR szPath[MAX_PATH + 1];
	ZeroMemory(szPath,sizeof(szPath));

	if (pBuffer != NULL)
	{		
		if(pBuffer[lstrlen(pBuffer)-1] == '\\') //删除结尾的'\'
			wsprintf(szPath, _T("%s%s"), pBuffer,"PatchInstall.txt");
		else
			wsprintf(szPath, _T("%s%s"), pBuffer,"\\PatchInstall.txt");		
	}
    RELEASE(pBuffer);
	
	char szSrc[1024];
	DWORD dwBytesRead = 0;
	ZeroMemory(szSrc,sizeof(szSrc));
	int dwSize = sizeof(szSrc);

	BOOL bRight = FALSE;
	/*
	try
	{
		CStdioFile dsFile;
		CFileException ex;
		if(dsFile.Open(szPath, CFile::modeRead | CFile::shareDenyNone | CFile::typeText , &ex) == TRUE)
		{
			dsFile.Read(szSrc, dwSize);
			dsFile.Close();
			if(lstrcmp(szSrc, "ISD") == 0)
			{
				bRight = TRUE;
			}
			else
			{
				bRight = FALSE;
			}
		}
		else
		{
			bRight = FALSE;
		}
	}
	catch(CFileException e)
	{
		char log[1024];
		ZeroMemory(log,sizeof(log));
		ex.GetErrorMessage(log, 1024);  
		OutputDebugString(log);	
	}
	*/

	HANDLE hFile;  
	hFile = CreateFile(szPath,           // open MYFILE.TXT 
					GENERIC_READ,              // open for reading 
					FILE_SHARE_READ,           // share for reading 
					NULL,                      // no security 
					OPEN_EXISTING,             // existing file only 
					FILE_ATTRIBUTE_NORMAL,     // normal file 
					NULL);                     // no attr. template 
 
	if (hFile == INVALID_HANDLE_VALUE) 
	{ 
		bRight = FALSE;
	} 
	else
	{
		if (ReadFile(hFile, szSrc, dwSize, &dwBytesRead, NULL)) 
		{ 
			if(lstrcmp(szSrc, "ISD") == 0)
			{
				bRight = TRUE;
			}
			else
			{
				bRight = FALSE;
			}
		}
		CloseHandle(hFile); 
	}

	if(bRight == FALSE)
	{
		::MsiSetProperty(hInstall, _T("MSICANINSTALL"), _T("0"));
	}
	else
	{
		::MsiSetProperty(hInstall, _T("MSICANINSTALL"), _T("1"));
	}

	return ERROR_SUCCESS;
}



//
// 
//
//	生成临时文件,因为defer的custom action不能使用binary table,所以提前生成这些文件
// 
UINT __stdcall CreateBinaryFile(MSIHANDLE hInstall)
{
	g_hInstall=hInstall;
	TCHAR strTmpFile[MAX_PATH];	
	Log2Msi(_T("CCA- CreateBinaryFile!"));
	BinaryFileTempPath(hInstall,"gacutil",strTmpFile,1);
	Log2Msi(_T("CCA- CreateBinaryFile!%s"),strTmpFile);
	BinaryFileTempPath(hInstall,"RegAsm",strTmpFile,1);
	BinaryFileTempPath(hInstall,"RegAsm40",strTmpFile,1);
	BinaryFileTempPath(hInstall,"RegSvcs",strTmpFile,1);	
	return ERROR_SUCCESS;
}



























































评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值