| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630 |
- #include "stdafx.h"
- #include "global.h"
- #include "AppXmlInfo.h"
- #include "InstallXmlInfo.h"
- #include "xunzip.h"
- #include "Wininet.h"
- #include <shlwapi.h>
- #include <stdio.h>
- #include <tchar.h>
- #include <afxinet.h>
- #include "atlbase.h"
- #include "shobjidl.h"
- #include <locale>
- #pragma comment(lib,"Wininet.lib")
- #pragma comment(lib, "shell32.lib")
- void DeleteDirectory(CString dir,bool delParenDir)
- {
- if(dir.IsEmpty())
- return ;
- CFileFind find;
- BOOL bFound = find.FindFile(dir + _T("\\*"),0);
- while(bFound)
- {
- bFound = find.FindNextFileW();
- if(find.IsDots())
- {
- continue;
- }
- SetFileAttributes(find.GetFilePath(),FILE_ATTRIBUTE_NORMAL);
- if(find.IsDirectory())
- {
- DeleteDirectory(find.GetFilePath(),true);
- }
- else
- {
- DeleteFile(find.GetFilePath());
- }
- }
- find.Close();
- if(delParenDir)
- RemoveDirectory(dir);
- return ;
- }
- void RemoveDirectoryRecursive(CString dir)
- {
- if(dir.IsEmpty())
- return ;
- CFileFind find;
- BOOL bFound = find.FindFile(dir + _T("\\*.*"),0);
- while(bFound)
- {
- bFound = find.FindNextFileW();
- if(find.IsDots())
- {
- continue;
- }
- SetFileAttributes(find.GetFilePath(),FILE_ATTRIBUTE_NORMAL);
- if(find.IsDirectory())
- {
- RemoveDirectoryRecursive(find.GetFilePath());
- }
-
- }
- find.Close();
- BOOL ret = RemoveDirectory(dir);
- return ;
- }
- CString GetSystemFolderByCSIDL(int csidl)
- {
- LPITEMIDLIST ppidl = NULL;
- TCHAR buffer[MAX_PATH];
- CString path;
- if (SHGetSpecialFolderLocation(NULL, csidl, &ppidl) == S_OK)
- {
- BOOL flag = SHGetPathFromIDList(ppidl, buffer);
- CoTaskMemFree(ppidl);
- path = buffer;
- }
- return path;
- }
- bool TestDownloadServer(CString url)
- {
- HINTERNET hInternet;
- hInternet=InternetOpen(_T("Testing"),INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0);
- if (hInternet==NULL)
- {
- return false;
- }
- HINTERNET hUrl;
- hUrl=InternetOpenUrl(hInternet,url,NULL,0,INTERNET_FLAG_RELOAD,0); //
- if (hUrl==NULL)
- {
- InternetCloseHandle(hInternet);
- return false;
- }
- InternetCloseHandle(hUrl);
- InternetCloseHandle(hInternet);
- return true;
-
- }
- bool ExecAppWaitForExit(CString appName ,CString workingDir )
- {
- BOOL bolSuccess ;
- STARTUPINFO StartupInfo;
- PROCESS_INFORMATION proinfo;
- memset(&StartupInfo,0,sizeof(STARTUPINFO));
- StartupInfo.cb=sizeof(STARTUPINFO);
- StartupInfo.lpReserved=NULL;
- StartupInfo.lpDesktop=NULL;
- StartupInfo.lpTitle=NULL;
- StartupInfo.dwFlags=STARTF_USESHOWWINDOW;
- StartupInfo.cbReserved2=0;
- StartupInfo.lpReserved2=NULL;
- StartupInfo.wShowWindow=SW_HIDE ;
- ZeroMemory(&proinfo, sizeof(proinfo));
- bolSuccess = CreateProcess(appName,NULL, NULL, NULL, TRUE,
- CREATE_UNICODE_ENVIRONMENT, NULL, workingDir, &StartupInfo, &proinfo) ;
- DWORD R = GetLastError();
- if ( bolSuccess !=0 ) //运行结束
- {
-
- CloseHandle( proinfo.hThread ) ;
- WaitForSingleObject( proinfo.hProcess ,INFINITE ) ;
- CloseHandle( proinfo.hProcess ) ;
- return true ;
- }
- else
- {
-
- return false ;
- }
-
- }
- bool MoveFileN(CString srcName,CString destName)
- {
- if(FileExist(destName))
- {
- DWORD dWold;
- dWold=::GetFileAttributes(destName);
- dWold&=~FILE_ATTRIBUTE_READONLY;
- ::SetFileAttributes(destName,dWold);
- ::DeleteFile(destName);
- }
- return ::MoveFile(srcName,destName)?true:false;
- }
- bool CreateSubDir(CString parentPath,CString childPath)
- {
- childPath.Replace(_T("/"),_T("\\"));
- CString strDir(childPath);//存放要创建的目录字符串
- //确保以'\'结尾以创建最后一个目录
- if (childPath.GetAt(childPath.GetLength()-1)!=_T('\\'))
- {
- childPath.AppendChar(_T('\\'));
- }
- //确保不以'\'开头
- if (childPath.GetAt(0)==_T('\\'))
- {
- childPath.Delete(0);
- }
- CStringArray vPath;//存放每一层目录字符串
- CString strTemp;//一个临时变量,存放目录字符串
- bool bSuccess = false;//成功标志
- //遍历要创建的字符串
- for (int i=0;i<childPath.GetLength();++i)
- {
- if (childPath.GetAt(i) != _T('\\'))
- {//如果当前字符不是'\\'
- strTemp.AppendChar(childPath.GetAt(i));
- }
- else
- {//如果当前字符是'\\'
- vPath.Add(strTemp);//将当前层的字符串添加到数组中
- strTemp.AppendChar(_T('\\'));
- }
- }
- //遍历存放目录的数组,创建每层目录
- for (int i=0;i<vPath.GetSize();i++)
- {
- //如果CreateDirectory执行成功,返回true,否则返回false
- bSuccess = CreateInstallPath(parentPath + _T("\\") + vPath.GetAt(i));
- if(!bSuccess)
- break;
- }
- if(bSuccess)
- {
- return bSuccess;
- }
- else
- {
- if(childPath.GetLength()==0)
- return true;
- else
- return false;
- }
- }
- bool FileExist(CString strFileName)
- {
- CFileFind fFind;
- return (fFind.FindFile(strFileName)!=0)?true:false;
- }
- bool ExtractFileFromZip(CString absolutPath,CString strZipFileName)
- {
- ZIPENTRYW ze;
- CString strZipFile = absolutPath + _T("\\") + strZipFileName;
- TCHAR * pszArchive = strZipFile.GetBuffer(strZipFile.GetLength());
- HZIP hz = OpenZip(pszArchive, 0, ZIP_FILENAME);
- bool succeed = false;
- if (hz)
- {
- ZRESULT zr = GetZipItem(hz, 0, &ze);
- if (zr == ZR_OK)
- {
- //ze.ctime.dwLowDateTime = ze.ctime.dwLowDateTime - 8*60*60;
- CString filename = ze.name;
- CString strItemFile = absolutPath + _T("\\")+filename ;
- TCHAR * targetFile = strItemFile.GetBuffer(strItemFile.GetLength());
- ZRESULT zr2 = UnzipItem(hz,0,targetFile,0,ZIP_FILENAME);
- if(zr2 == ZR_OK)
- {
- succeed = true;
- DWORD dWold;
- dWold=::GetFileAttributes(strItemFile);
- dWold&=~FILE_ATTRIBUTE_READONLY;
- ::SetFileAttributes(strItemFile,dWold);
- }
- }
- }
- CloseZip(hz);
- ::DeleteFile(strZipFile);
-
- return succeed;
- }
- CString GetSysPath(CString sEnvironmentName)
- {
-
- TCHAR buffer[1024];
- DWORD dwRet = GetEnvironmentVariable(sEnvironmentName, buffer, sizeof(buffer));
- CString value;
- if (dwRet > 0)
- {
- value = buffer;
- }
- return value;
- }
- bool FolderExist(CString strPath)
- {
- WIN32_FIND_DATA wfd;
- bool rValue = false;
- HANDLE hFind = FindFirstFile(strPath, &wfd);
-
- if ((hFind != INVALID_HANDLE_VALUE) && (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
- {
- rValue = true;
- }
- FindClose(hFind);
- return rValue;
- }
- bool CreateInstallPath(CString dir)
- {
- if(!FolderExist(dir))
- {
- if(::CreateDirectory( dir , NULL)==0)
- return false;
- }
- return true;
- }
- bool DownloadUpdatePackage(CString serverAppXmlLocalPath,CString serverInstallXmlLocalPath,ThreadParamInfo *info)
- {
- CInstallXmlInfo installInfo(serverInstallXmlLocalPath);
- CAppXmlInfo appInfo(serverAppXmlLocalPath);
- for(int i=0;i<installInfo.installPaths.GetSize();i++)
- {
- if(!CreateInstallPath(installInfo.installPaths.GetAt(i)))
- {
- ::PostMessage(info->hwnd,WM_USERMSG_UPGRADE_STATE,USER_PARAM_DIR_CREATE_ERROR,0);
- return false;
- }
- }
- if(info->stop) // 如果取消下载
- {
- AfxEndThread(0); // 结束下载线程
- }
- CString storePath = installInfo.tempPath + _T("\\");
- CString localAppXmlFile = installInfo.appPath + _T("\\") + serverAppXmlLocalPath.Mid(serverAppXmlLocalPath.ReverseFind('\\')+1);
- CString localInstallXmlFile = installInfo.appPath + _T("\\") + serverInstallXmlLocalPath.Mid(serverInstallXmlLocalPath.ReverseFind('\\')+1);
- //判断可用的下载服务器
- CString downloadserver;
- for(int i=0;i<appInfo.download_servers.GetSize();i++)
- {
- if(info->stop) // 如果取消下载
- {
- AfxEndThread(0); // 结束下载线程
- }
- if(TestDownloadServer(appInfo.download_servers.GetAt(i)))
- {
- downloadserver = appInfo.download_servers.GetAt(i);
- break;
- }
- }
- if(downloadserver.GetLength()==0)
- {
- ::PostMessage(info->hwnd,WM_USERMSG_UPGRADE_STATE,USER_PARAM_FILE_DOWNLOAD_ERROR,0);
- return false;
- }
- if(info->stop) // 如果取消下载
- {
- AfxEndThread(0); // 结束下载线程
- }
- //对本地文件和服务端文件进行差异化比较,形成下载文件列表
- CStringArray differenceFiles;
- CStringArray zipFileNames;//只是用于记录zip文件名,方便解压缩
- if(FileExist(localAppXmlFile))
- {
- CAppXmlInfo appLocalInfo(localAppXmlFile);
- for(int i=0;i<appInfo.download_files.GetSize();i++)
- {
- bool match = false;
- for(int j=0;j<appLocalInfo.download_files.GetSize();j++)
- {
- if(info->stop) // 如果取消下载
- {
- AfxEndThread(0); // 结束下载线程
- }
- if(appInfo.download_files.GetAt(i).fileName.CompareNoCase(appLocalInfo.download_files.GetAt(j).fileName)==0)
- {
- match = true;
- CString local = appLocalInfo.download_files.GetAt(j).lastUpdateTime;
- CString server = appInfo.download_files.GetAt(i).lastUpdateTime;
- COleDateTime localTime,currentTime;
- if(localTime.ParseDateTime(local)&¤tTime.ParseDateTime(server))
- {
- if(localTime<currentTime)
- {
- match = false;
- break;
- }
- }
- break;
- }
- }
- if(!match){
- differenceFiles.Add(downloadserver + appInfo.download_files.GetAt(i).fileName);
- zipFileNames.Add(appInfo.download_files.GetAt(i).fileName);
- }
- }
- }
- else
- {
- for(int i=0;i<appInfo.download_files.GetSize();i++)
- {
- differenceFiles.Add(downloadserver + appInfo.download_files.GetAt(i).fileName);
- zipFileNames.Add(appInfo.download_files.GetAt(i).fileName);
- }
- }
- if(info->stop) // 如果取消下载
- {
- AfxEndThread(0); // 结束下载线程
- }
- //下载差异化文件,之前清理一下storePaht已经存在的文件
- if(storePath.Find(_T("Temp"))>0)
- DeleteDirectory(storePath,false);//危险,请确保传入的路径是你想要删除的路径
- for(int i=0;i<differenceFiles.GetSize();i++)
- {
- if(i==0)
- ::PostMessage(info->hwnd,WM_USERMSG_UPGRADE_RANGE,differenceFiles.GetSize(),0);
- if(info->stop)
- {
- ::PostMessage(info->hwnd,WM_USERMSG_UPGRADE_STATE,USER_PARAM_FILE_DOWNLOAD_ABORT,0);
- return false;
- }
- if(DownloadFile(differenceFiles.GetAt(i),storePath,info))
- {
- ::PostMessage(info->hwnd,WM_USERMSG_UPGRADE_STATE,USER_PARAM_FILE_DOWNLOAD_OK,0);
- }
- else
- {
- ::PostMessage(info->hwnd,WM_USERMSG_UPGRADE_STATE,USER_PARAM_FILE_DOWNLOAD_ERROR,0);
- return false;
- }
- ::PostMessage(info->hwnd,WM_USERMSG_UPGRADE_PROGRESS,i+1,0);
- }
- //解压缩已经下载的zip文件
- for(int i=0;i<zipFileNames.GetSize();i++)
- {
- CString zipFileName = zipFileNames.GetAt(i);
- CString absolutePath = installInfo.tempPath;
- if(info->stop) // 如果取消下载
- {
- AfxEndThread(0); // 结束下载线程
- }
- if(!ExtractFileFromZip(absolutePath,zipFileName))
- {
- ::PostMessage(info->hwnd,WM_USERMSG_UPGRADE_STATE,USER_PARAM_FILE_UNZIP_ERROR,0);
- return false;
- }
- }
- bool needReplaceSetup = false;
- CString tmpDir = GetSysPath(_T("temp"));
- CString batName = tmpDir + _T("\\sncupdate_replaceself.bat");
- CString appMainName = AfxGetApp()->m_pszAppName;
- if(differenceFiles.GetSize()>0)
- {
- //按照install.xml的配置,安装已经解压缩的文件
- for(int i=0;i<installInfo.locations.GetSize();i++)
- {
- if(info->stop) // 如果取消下载
- {
- AfxEndThread(0); // 结束下载线程
- }
- CString fileName = installInfo.locations.GetAt(i).fileName;
- CString fileType = installInfo.locations.GetAt(i).fileType;
- CString subDir = installInfo.locations.GetAt(i).subDir;
- CString app = _T("app");
- CString data = _T("data");
- if(FileExist(installInfo.tempPath + _T("\\") + fileName))
- {
- CString destDir;
- if(fileType.CompareNoCase(app)==0)
- {
- destDir = installInfo.appPath ;
- }
- else if(fileType.CompareNoCase(data)==0)
- {
- destDir = installInfo.dataPath ;
- }
- if(fileName.CompareNoCase(appMainName+_T(".exe"))==0)
- {
- //替换升级程序
-
-
- CStdioFile file;
- if(file.Open(batName, CFile::modeCreate | CFile::modeWrite))
- {
- char * old_locale = _strdup(setlocale(LC_CTYPE,NULL));
- setlocale(LC_CTYPE,"chs");
- CString script;
- script = _T(":repeat \r\n");
- file.WriteString(script);
- script = _T( "del \"")+ installInfo.appPath + _T("\\") + fileName + _T("\"\r\n ") ;
- file.WriteString(script);
- script = _T("if exist \"") +installInfo.appPath + _T("\\") + fileName + _T("\" goto Repeat\r\n");
- file.WriteString(script);
- script = _T("move \"") +installInfo.tempPath + _T("\\") + fileName + _T("\" \"") + installInfo.appPath + _T("\\") + fileName + _T("\"\r\n");
- file.WriteString(script);
- script = _T("del \"") + batName + _T("\"\r\n");
- file.WriteString(script);
- //script = _T("PAUSE\r\n");;
- //file.WriteString(script);
- setlocale(LC_CTYPE,old_locale);
- free(old_locale);
- file.Close();
- }
- needReplaceSetup = true;
- continue;
- }
- if(CreateSubDir(destDir,subDir))
- {
- destDir = destDir + subDir;
- }
- else
- {
- ::PostMessage(info->hwnd,WM_USERMSG_UPGRADE_STATE,USER_PARAM_FILE_MOVE_ERROR,0);
- return false;
- }
-
- CString destName = destDir + _T("\\") + fileName;
- MoveFileN(installInfo.tempPath + _T("\\") + fileName,destName);
- }
- }
- }
- //移动配置文件到对应目录
- MoveFileN(serverAppXmlLocalPath,localAppXmlFile);
- MoveFileN(serverInstallXmlLocalPath,localInstallXmlFile);
-
- ::PostMessage(info->hwnd,WM_USERMSG_UPGRADE_STATE,USER_PARAM_VERSION_UPDATED,0);
- //Sleep(1000);
-
-
- //完成安装,按照顺序启动程序进行设置
- CString on = _T("on");
- CString off = _T("off");
- for(int i=0;i<appInfo.run_apps.GetSize();i++)
- {
- CString appname = appInfo.run_apps.GetAt(i).appname;
- CString mode = appInfo.run_apps.GetAt(i).mode;
- CString runPath = installInfo.appPath + _T("\\") + appname;
- if(info->stop) // 如果取消下载
- {
- AfxEndThread(0); // 结束下载线程
- }
- if(mode.CompareNoCase(on)==0)
- {
- ExecAppWaitForExit(runPath,installInfo.appPath);
- }
- else if(mode.CompareNoCase(off)==0)
- {
- if(i!=appInfo.run_apps.GetSize()-1)
- {
- ExecAppWaitForExit(runPath,installInfo.appPath);
- }
- else
- {
- ::PostMessage(info->hwnd,WM_USERMSG_UPGRADE_STATE,USER_PARAM_SETUP_FINISH,0);
- Sleep(1000);
- if(needReplaceSetup)
- ShellExecute(NULL,_T("open"),batName,NULL,tmpDir,SW_HIDE);
- ShellExecute(NULL,_T("open"),runPath,NULL,installInfo.appPath,SW_SHOW);
- ::PostMessage(info->hwnd,WM_USERMSG_UPGRADE_STATE,USER_PARAM_SETUP_EXIT,0);
- }
- }
- }
- return true;
- }
- UINT ThreadFun(LPVOID lpParam)
- {
- ThreadParamInfo *info = (ThreadParamInfo*)lpParam;
- CString appXmlUrl,installXmlUrl;
- if(info->isproduct)
- {
- appXmlUrl= _T(STATIC_APP_CONFIG_URL);
- installXmlUrl = _T(STATIC_INSTALL_CONFIG_URL);
- }
- else
- {
- appXmlUrl= _T(STATIC_APP_CONFIG_URL_TEST);
- installXmlUrl = _T(STATIC_INSTALL_CONFIG_URL_TEST);
- }
- CString tmpPath = GetSysPath(_T("TEMP")) ;
- CString storePath = tmpPath + _T("\\SpeedNumCube");
- CString serverAppXmlLocalPath = storePath + _T("\\") + appXmlUrl.Mid(appXmlUrl.ReverseFind('/')+1);
- CString serverInstallXmlLocalPath = storePath + _T("\\") + installXmlUrl.Mid(installXmlUrl.ReverseFind('/')+1);
- if(!FolderExist(storePath))
- {
- //SECURITY_ATTRIBUTES attrib;
- if(::CreateDirectory( storePath,NULL)==0)
- {
- ::PostMessage(info->hwnd,WM_USERMSG_UPGRADE_STATE,USER_PARAM_DIR_CREATE_ERROR,0);
- return 0;
- }
- }
- Sleep(1000);
- if(DownloadFile(appXmlUrl,storePath,info) && DownloadFile(installXmlUrl,storePath,info) )
- {
- ::PostMessage(info->hwnd,WM_USERMSG_UPGRADE_STATE,USER_PARAM_NETWORK_AVAIABLE,0);
- if(!DownloadUpdatePackage(serverAppXmlLocalPath,serverInstallXmlLocalPath,info))
- {
- return 0;
- }
- }
- else
- {
- ::PostMessage(info->hwnd,WM_USERMSG_UPGRADE_STATE,USER_PARAM_NETWORK_NOT_AVAIABLE,0);
- return 0;
- }
- return 1;
- }
- bool DownloadFile(CString szUrl,CString storePath,ThreadParamInfo *info)
- {
- char buffer[10240];
- CInternetSession session;
- CStdioFile *httpfile;
- try
- {
- httpfile = session.OpenURL(szUrl,1,INTERNET_FLAG_TRANSFER_BINARY | INTERNET_FLAG_RELOAD);
- COleDateTime dlStart = COleDateTime::GetCurrentTime();
- ULONGLONG fileBytes = httpfile->SeekToEnd();
- httpfile->SeekToBegin();
- // 在当前目录创建新的目标文件
- CFile localfile;
- CFileException e;
- if(TRUE!=localfile.Open(storePath + _T("\\") + httpfile->GetFileName(), CFile::modeCreate | CFile::modeWrite | CFile::typeBinary,&e))
- {
- httpfile->Close();
- return false;
- }
-
- UINT bytesfetch; // 读取的的字节数
- ULONGLONG byteswrite = 0; // 已经写入的字节数
- double nperc,kbrecv; // 进度条的百分比,获取到的数据大小(Kbs为单位)
- double secs,kbsec; // 记录秒数, 速度(KB/秒)
- while (bytesfetch = httpfile->Read(buffer, sizeof(buffer))) // 读取文件
- {
-
- if(info->stop) // 如果取消下载
- {
- localfile.Close(); // 关闭我们的目标文件
- httpfile->Close(); // 关闭远程文件
- delete httpfile; // 删除CStdioFile对象,以防止泄漏
- AfxEndThread(0); // 结束下载线程
- }
- // 根据开始时间与当前时间比较,获取秒数
- COleDateTimeSpan dlElapsed = COleDateTime::GetCurrentTime() - dlStart;
- secs = dlElapsed.GetTotalSeconds();
- byteswrite = byteswrite + bytesfetch; // 设置新的进度条位置
- localfile.Write(buffer, bytesfetch); // 将实际数据写入文件
-
- nperc = (double)byteswrite * 100 / (double)fileBytes; // 进度百分比
- kbrecv = (double )byteswrite / 1024; // 获取收到的数据
- kbsec = kbrecv / secs; // 获取每秒下载多少(KB)
- WPARAM para = (WPARAM)nperc;
- if(byteswrite%102400==0 && byteswrite/102400>0)
- ::PostMessage(info->hwnd,WM_USERMSG_UPGRADE_CHILD_PROGRESS,para,0);
- }
- // 下载完成,关闭文件
- localfile.Close();
- }
- catch(CInternetException *IE)
- {
- CString strerror;
- TCHAR error[255];
- IE->GetErrorMessage(error,255); // 获取错误消息
- strerror = error;
- if(!httpfile)
- delete httpfile;
- IE->Delete(); // 删除异常对象,以防止泄漏
- return false;
- }
- return true;
- }
|