Initial commit

This commit is contained in:
2026-07-13 10:02:53 +08:00
commit e73ef3aac0
8 changed files with 2733 additions and 0 deletions
+12
View File
@@ -0,0 +1,12 @@
#排除所有的编译目录
**/Win32/
#排除历史和恢复目录
__history/
__recovery/
#排除本地设置
*.~dsk
*.cbpr
*.local
*.rc
+1380
View File
File diff suppressed because it is too large Load Diff
+112
View File
@@ -0,0 +1,112 @@
//---------------------------------------------------------------------------
#include <vcl.h>
#include <tchar.h>
#include "UpgradeThread.h"
#include "UpgradeUnit.h"
#pragma hdrstop
//---------------------------------------------------------------------------
USEFORM("UpgradeUnit.cpp", UpgradeForm);
//---------------------------------------------------------------------------
String MAIN_APP_NAME;
BOOL ImprovePrivilege()
{
HANDLE token;
//ÌáÉýȨÏÞ
if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&token)){
MessageBox(NULL,L"´ò¿ª½ø³ÌÁîÅÆÊ§°Ü...",L"´íÎó",MB_ICONSTOP);
return FALSE;
}
BOOL bRet = true;
TOKEN_PRIVILEGES tkp;
tkp.PrivilegeCount = 1;
LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&tkp.Privileges[0].Luid);
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if(!AdjustTokenPrivileges(token,FALSE,&tkp,sizeof(tkp),NULL,NULL)){
MessageBox(NULL,L"µ÷ÕûÁîÅÆÈ¨ÏÞʧ°Ü...",L"´íÎó",MB_ICONSTOP);
bRet = FALSE;
}
CloseHandle(token);
return bRet;
}
int WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
{
int mode = 0, sid = 0;
String sVar;
if( ParamStr(1).IsEmpty() ){
return 0;
}
else{
String param = ParamStr(1).UpperCase();
if( param=="MD5" ){
mode = 1;
}
else if( ParamStr(2).IsEmpty() ){
return 0;
}
else{
if( param=="SHOW" )
mode = 0;
else if( param=="HIDE" )
mode = 2;
else if( param=="MOVE" )
mode = 3;
MAIN_APP_NAME = ParamStr(2);
sid = ParamStr(3).ToInt();
sVar = ParamStr(4);
#ifdef _DEBUG
// String msg = ParamStr(0) + " ";
// msg += ParamStr(1) + " ";
// msg += ParamStr(2) + " ";
// msg += ParamStr(3);
// ShowMessage( msg );
#endif
}
}
try{
Application->Initialize();
Application->Title = APPNAME;
ImprovePrivilege();
if( mode < 2 ){
Application->MainFormOnTaskBar = true;
Application->CreateForm(__classid(TUpgradeForm), &UpgradeForm);
UpgradeForm->m_iMode = mode;
UpgradeForm->m_idSoft = sid;
UpgradeForm->m_sVar = sVar;
Application->Run();
}
else{
TUpgradeThread* pThread = new TUpgradeThread( true, mode, sid, sVar );
pThread->Start();
pThread->WaitFor();
delete pThread;
}
}
catch (Exception &exception){
Application->ShowException(&exception);
}
catch (...){
try{
throw Exception("");
}
catch (Exception &exception){
Application->ShowException(&exception);
}
}
return 0;
}
//---------------------------------------------------------------------------
+922
View File
@@ -0,0 +1,922 @@
//---------------------------------------------------------------------------
#include <vcl.h>
#include <System.Hash.hpp>
#include <System.IOUtils.hpp>
#include <wininet.h>
#include <Tlhelp32.h>
#include <vector>
#include "UpgradeThread.h"
#pragma hdrstop
#pragma package(smart_init)
#pragma comment(lib, "wininet")
//---------------------------------------------------------------------------
#define UPDATE_APP_NAME "AppUpgrade.exe"
#define MD5_FILE_NAME "filemd5.lst"
//#define GLOBAL_VAR_FILE "glbvrf.cnf"
//#define DEFAULT_SERVER "23.236.66.46:88" //"127.0.0.1" //
#define GLOBAL_VAR_VERSION 0x03
extern String MAIN_APP_NAME;
typedef struct tGVFHeader{
char head[4];
WORD idSoftware;
WORD iUpdate;
tGVFHeader(){
head[0] = 'G';
head[1] = 'V';
head[2] = 'F';
head[3] = GLOBAL_VAR_VERSION;
iUpdate = 0;
}
} TGVFHEADER;
typedef struct tGetUrlParam
{
char server[128];
int idSoft;
int errCode;
HINTERNET hSession,
hRequest;
int sizeOut;
char *dataOut;
tGetUrlParam(){
memset( this, 0, sizeof(tGetUrlParam) );
};
} TGetUrlParam;
typedef struct tDownloadParam
{
char url[256];
char filename[256];
HWND hWnd;
int errCode;
HINTERNET hSession,
hRequest;
tDownloadParam(){
memset( this, 0, sizeof(tDownloadParam) );
};
} TDownloadParam;
using namespace std;
//---------------------------------------------------------------------------
DWORD WINAPI GetUrlProc(LPVOID args)
{
TGetUrlParam* param = (TGetUrlParam*)args;
param->hSession = InternetOpen( L"RookIE/1.0", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0 );
if( param->hSession ){
String api = L"http://" + (String)param->server + L"/Api/getUpgradeUrl?sid=" + IntToStr(param->idSoft);
param->hRequest = InternetOpenUrl( param->hSession, api.c_str(), NULL, 0,
INTERNET_FLAG_DONT_CACHE|INTERNET_FLAG_RELOAD|INTERNET_FLAG_PRAGMA_NOCACHE, 0 );
if( param->hRequest ){
int pos = 0;
DWORD dwByteRead = 0;
char szBuffer[1024];
ZeroMemory(szBuffer, sizeof(szBuffer));
ZeroMemory(param->dataOut, param->sizeOut);
// 循环读取缓冲区内容直到结束
while( InternetReadFile(param->hRequest, szBuffer, sizeof(szBuffer), &dwByteRead) && dwByteRead > 0){
if( pos + dwByteRead > param->sizeOut ){
param->errCode = ERROR_SIZE;
break;
}
// 复制输出数据
memcpy( param->dataOut+pos, szBuffer, dwByteRead );
pos += dwByteRead;
// 清空缓冲区以备下一次读取
ZeroMemory(szBuffer, sizeof(szBuffer));
}
param->dataOut[pos] = 0;
param->sizeOut = pos;
}
else
param->errCode = ERROR_INTERNET_REQ;
}
else
param->errCode = ERROR_INTERNET_OPEN;
return 0;
}
DWORD WINAPI DownloadProc(LPVOID args)
{
TDownloadParam* param = (TDownloadParam*)args;
param->hSession = InternetOpen( L"RookIE/1.0", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0 );
if( param->hSession ){
param->hRequest = InternetOpenUrl( param->hSession, ((String)param->url).c_str(), NULL, 0,
INTERNET_FLAG_DONT_CACHE|INTERNET_FLAG_RELOAD|INTERNET_FLAG_PRAGMA_NOCACHE, 0 );
if( param->hRequest ){
int pos = 0;
DWORD dwAllBytes = 0,
dwSize = 4;
if( param->hWnd ){
HttpQueryInfo( param->hRequest, HTTP_QUERY_CONTENT_LENGTH|HTTP_QUERY_FLAG_NUMBER,
&dwAllBytes, &dwSize, NULL );
}
FILE* fp = fopen( param->filename, "wb" );
if( fp ){
char szBuffer[2048] = "\0";
DWORD dwByteRead = 0, dwReceived = 0;
ZeroMemory(szBuffer, sizeof(szBuffer));
// 循环读取缓冲区内容直到结束
while (InternetReadFile(param->hRequest, szBuffer, sizeof(szBuffer), &dwByteRead) && dwByteRead > 0){
fwrite( szBuffer, 1, dwByteRead, fp );
if( param->hWnd ){
//显示进度
dwReceived += dwByteRead;
int pos = (int)( dwReceived * 100.0 / dwAllBytes + 0.5 );
SendMessage( param->hWnd, UM_PROGRESS, 1, pos );
}
// 清空缓冲区以备下一次读取
ZeroMemory(szBuffer, sizeof(szBuffer));
}
fclose( fp );
if( dwReceived==dwAllBytes ){
SendMessage( param->hWnd, UM_PROGRESS, 1, 100 );
param->errCode = 0;
}
else
param->errCode = ERROR_FILE_SIZE;
}
else
param->errCode = ERROR_OPEN_FILE;
}
else
param->errCode = ERROR_INTERNET_REQ;
}
else
param->errCode = ERROR_INTERNET_OPEN;
return 0;
}
//---------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
__fastcall TUpgradeThread::TUpgradeThread(bool CreateSuspended, int mode, int sid, String sVar, HWND hWnd)
: TThread(CreateSuspended)
{
m_iMode = mode;
m_idSoft = sid;
m_hWnd = hWnd;
m_lstFile = NULL;
m_bUpdateSelf = false;
m_AppPath = TPath::GetFullPath(ExtractFilePath(Application->ExeName));
m_PathName = m_AppPath + MAIN_APP_NAME;
// m_Server = DEFAULT_SERVER;
m_hSema = CreateSemaphore( NULL, 0, 1, NULL );
m_GlobalFile = m_AppPath + sVar;// GLOBAL_VAR_FILE;
}
//---------------------------------------------------------------------------
void __fastcall TUpgradeThread::Cancel()
{
Terminate();
ReleaseSemaphore( m_hSema, 1, NULL );
}
//---------------------------------------------------------------------------
void __fastcall TUpgradeThread::Execute()
{
int ret = 0;
//获取列表文件
//对比文件MD5码=>更新列表
//下载更新列表中的文件
if( m_iMode==3 ){
Sleep(1000); //等待app完全退出
if( UpdateFiles() ){
RegUpdateFlag( 0 );
RestartApp();
}
}
else if( m_iMode==1 ){
MakeMD5File();
}
else{
String strText, strProg1, strProg2;
//清空目录
ClearUpdateDir();
Randomize();
if( m_hWnd ){
strText = "正在获取更新列表";
SendMessage( m_hWnd, UM_SHOWTEXT, 0, (LPARAM)strText.c_str() );
strProg1 = L"——";
SendMessage( m_hWnd, UM_SHOWTEXT, 1, (LPARAM)strProg1.c_str() );
strProg2 = L"正在下载列表文件";
SendMessage( m_hWnd, UM_SHOWTEXT, 2, (LPARAM)strProg2.c_str() );
}
String umdfile = GetUpdateMD5File();
if( umdfile.Length()>0 && !Terminated ){
if( m_hWnd ){
strText = "正在检查更新列表";
SendMessage( m_hWnd, UM_SHOWTEXT, 0, (LPARAM)strText.c_str() );
}
TStringList* ufnLst = new TStringList;
int ret = GetUpdateFileList( umdfile, ufnLst );
if( ret==0 && !Terminated ){
int count = ufnLst->Count;
if( count > 0 ){
if( m_hWnd ){
strText = "正在下载更新文件";
SendMessage( m_hWnd, UM_SHOWTEXT, 0, (LPARAM)strText.c_str() );
}
for( int i=0; i<count && !Terminated; i++ ){
if( m_hWnd ){
strProg1 = L"文件数 " + IntToStr( i ) + L"/" + IntToStr( count );
SendMessage( m_hWnd, UM_SHOWTEXT, 1, (LPARAM)strProg1.c_str() );
int pos = (int)( i*100.0/count + 0.5 );
SendMessage( m_hWnd, UM_PROGRESS, 0, pos );
strProg2 = L"当前下载文件 " + (*ufnLst)[i];
SendMessage( m_hWnd, UM_SHOWTEXT, 2, (LPARAM)strProg2.c_str() );
}
// String ufn = (*ufnLst)[i];
if( !(*ufnLst)[i].CompareIC( UPDATE_APP_NAME ) )
m_bUpdateSelf = true;
int ran = Random( 1000000 );
String url = m_UpdateUrl + (*ufnLst)[i];
url += "?" + IntToStr( ran );
ret = DownloadFile( url, (*ufnLst)[i] );
if( ret!=0 )
break;
}
if( ret==0 ){
if( m_hWnd ){
SendMessage( m_hWnd, UM_PROGRESS, 0, 100 );
}
if( m_iMode==2 || m_bUpdateSelf ){
RegUpdateFlag( 1 );
}
if( m_iMode==0 ){
if( UpdateFiles() )
RestartApp();
}
}
}
else{
if( m_hWnd ){
strText = "未发现需要更新的文件";
SendMessage( m_hWnd, UM_SHOWTEXT, 0, (LPARAM)strText.c_str() );
}
}
}
delete ufnLst;
}
else
ret = ERROR_FILELIST_GET;
}
if( !Terminated && m_hWnd )
PostMessage( m_hWnd, UM_COMPLETE, ret, 0 );
}
//---------------------------------------------------------------------------
bool __fastcall TUpgradeThread::MakeMD5File()
{
String strText, strProg1, strProg2;
if( m_hWnd ){
strText = "正在生成MD5校验文件";
SendMessage( m_hWnd, UM_SHOWTEXT, 0, (LPARAM)strText.c_str() );
}
m_lstFile = new TStringList();
m_lstMD5 = new TStringList();
if( GetFileList( m_lstFile ) ){
String fname = m_AppPath + MD5_FILE_NAME;
FILE* fp = fopen( ((AnsiString)fname).c_str(), "wb" );
if( fp ){
for( int i=0; i<m_lstFile->Count && !Terminated; i++ ){
if( m_hWnd ){
strProg1 = L"文件数 " + IntToStr( i )
+ L"/" + IntToStr( m_lstFile->Count );
SendMessage( m_hWnd, UM_SHOWTEXT, 1, (LPARAM)strProg1.c_str() );
int pos = (int)( i*100.0/m_lstFile->Count + 0.5 );
SendMessage( m_hWnd, UM_PROGRESS, 0, pos );
strProg2 = L"当前文件 " + (*m_lstFile)[i];
SendMessage( m_hWnd, UM_SHOWTEXT, 2, (LPARAM)strProg2.c_str() );
}
String md5;
if( !GenerateFileMD5( (*m_lstFile)[i], md5 ) )
break;
if( m_hWnd )
SendMessage( m_hWnd, UM_PROGRESS, 1, 100 );
char text[256];
sprintf( text, "%s\t%s\n",
((AnsiString)(*m_lstFile)[i]).c_str(),
((AnsiString)md5).c_str() );
fwrite( text, 1, strlen(text), fp );
}
if( !Terminated && m_hWnd )
SendMessage( m_hWnd, UM_PROGRESS, 0, 100 );
fclose( fp );
}
}
delete m_lstFile;
delete m_lstMD5;
m_lstFile = NULL;
return !Terminated;
}
//---------------------------------------------------------------------------
bool __fastcall TUpgradeThread::GenerateFileMD5( String fname, String& md5 )
{
String strName = m_AppPath + fname;
THashMD5* pMD5 = new THashMD5();
TFileStream* fs = new TFileStream( strName, fmOpenRead | fmShareDenyNone );
fs->Position = 0;
int sizeBuf = 1024 * 1024;
char* buf = (char*)malloc( sizeBuf );
while( !Terminated && fs->Position < fs->Size ){
if( fs->Position + sizeBuf > fs->Size )
sizeBuf = fs->Size - fs->Position;
fs->ReadBuffer( buf, sizeBuf );
pMD5->Update( buf, sizeBuf );
if( m_hWnd ){
//显示进度
int pos = (int)( fs->Position * 100.0 / fs->Size + 0.5 );
SendMessage( m_hWnd, UM_PROGRESS, 1, pos );
}
}
if( !Terminated ){
md5 = pMD5->HashAsString();
}
free( buf );
delete fs;
delete pMD5;
return !Terminated;
}
//---------------------------------------------------------------------------
int __fastcall TUpgradeThread::DownloadFile( String url, String filename )
{
int ret = -1;
String path = m_AppPath + L"upgrade\\";
if(!DirectoryExists(path, false))
ForceDirectories(path);
DeleteUrlCacheEntry(url.c_str());
path += filename;
for( int i=0; i<3; i++ ){ //尝试3次
TDownloadParam param;
param.hWnd = m_hWnd;
strcpy( param.url, ((AnsiString)url).c_str() );
strcpy( param.filename, ((AnsiString)path).c_str() );
DWORD id;
HANDLE hThread = CreateThread( NULL, 0, DownloadProc, &param, 0, &id );
if( hThread ){
HANDLE aHandle[2] = { m_hSema, hThread };
DWORD dwRet = WaitForMultipleObjects( 2, aHandle, FALSE, INFINITE );
if( param.hRequest )
InternetCloseHandle( param.hRequest );
if( param.hSession )
InternetCloseHandle( param.hSession );
WaitForSingleObject( hThread, 200 );
CloseHandle( hThread );
if( dwRet==WAIT_OBJECT_0 ) //用户退出
break;
else if( dwRet==WAIT_OBJECT_0+1 ){ //线程正常退出
if( param.errCode==0 ){
ret = 0;
break;
}
else if( param.errCode==ERROR_OPEN_FILE )
break;
}
}
}
return ret;
}
//---------------------------------------------------------------------------
bool __fastcall TUpgradeThread::GetFileList( TStringList* pList )
{
TSearchRec sr;
int iAttr = 0;
String strPath = m_AppPath;
if( FindFirst(strPath + L"*.*", iAttr, sr)==0 ){
do{
if( !(iAttr & faDirectory) /*iAttr & faNormal*/
//&& !sr.Name.Pos(".log")
//&& !sr.Name.Pos(".txt")
//&& !sr.Name.Pos(".ico")
//&& !sr.Name.Pos(".cnf")
//&& !sr.Name.Pos("agcdstdt")
&& !sr.Name.Pos(".lst")){
pList->Add( sr.Name );
}
}
while( !Terminated && FindNext(sr)==0 );
FindClose(sr);
}
return !Terminated;
}
//---------------------------------------------------------------------------
String __fastcall TUpgradeThread::GetUpdateMD5File()
{
String locFile;
m_UpdateUrl = GetUpdateURL();
if( m_UpdateUrl.Length()>0 ){
int ran = Random( 1000000 );
String url = m_UpdateUrl + MD5_FILE_NAME;
url += "?" + IntToStr( ran );
int ret = DownloadFile( url, MD5_FILE_NAME );
if( ret==0 ){
locFile = m_AppPath + L"upgrade/" + MD5_FILE_NAME;
}
}
return locFile;
}
//---------------------------------------------------------------------------
int __fastcall TUpgradeThread::GetServers( TStringList* pList )
{
char szBuffer[2048] = "";
// bool bSave = false;
FILE* fp = NULL;
//读取文件配置
fp = fopen( ((AnsiString)m_GlobalFile).c_str(), "rb" );
if( fp ){
TGVFHEADER header;
header.idSoftware = m_idSoft;
int ret = fread( (void*)szBuffer, 1, sizeof(header), fp );
if( ret==sizeof(header) && !memcmp(szBuffer, header.head, sizeof(header.head)) ){
fseek( fp, 0, SEEK_END );
int size = ftell( fp ) - sizeof(header);
if( size>2048 )
size = 2048;
fseek( fp, sizeof(header), SEEK_SET );
fread( szBuffer, 1, size, fp );
char srvs[1024] = "";
char *tokenPtr=strtok(szBuffer,"\n");
while( tokenPtr ){
if( strstr(tokenPtr, "srv=") ){
strcpy( srvs, tokenPtr+4 );
break;
}
tokenPtr=strtok(NULL,"\n");
}
if( strlen(srvs) ){
char *tkn = strtok( srvs, ";" );
while( tkn!=NULL ){
pList->Add( tkn );
tkn = strtok(NULL, ";");
}
}
}
fclose( fp );
}
// else{
// pList->Add( m_Server );
// }
return 0;
}
//---------------------------------------------------------------------------
String __fastcall TUpgradeThread::GetUpdateURL()
{
String url;
TStringList* pServers = new TStringList;
GetServers( pServers );
for( int i=0; i<pServers->Count; i++ ){
int sizeOut = 2048;
char dataOut[2048];
TGetUrlParam param;
param.idSoft = m_idSoft;
param.sizeOut = sizeOut;
param.dataOut = dataOut;
strcpy( param.server, ((AnsiString)(*pServers)[i]).c_str() );
DWORD id;
HANDLE hThread = CreateThread( NULL, 0, GetUrlProc, &param, 0, &id );
if( hThread ){
HANDLE aHandle[2] = { m_hSema, hThread };
DWORD dwRet = WaitForMultipleObjects( 2, aHandle, FALSE, 10000 );
if( param.hRequest )
InternetCloseHandle( param.hRequest );
if( param.hSession )
InternetCloseHandle( param.hSession );
WaitForSingleObject( hThread, 200 );
CloseHandle( hThread );
if( dwRet==WAIT_OBJECT_0 ) //用户退出
break;
else if( dwRet==WAIT_OBJECT_0+1 && param.errCode==0 ){ //线程正常退出
if(dataOut[0]=='\"' && dataOut[param.sizeOut-1]=='\"')
dataOut[param.sizeOut-1] = 0;
char* p = strstr( dataOut, "url:" );
if( p ){
m_Server = (*pServers)[i];
char* str = p+4;
url = L"http://" + m_Server + L"/" + str;
break;
}
}
}
}
delete pServers;
return url;
}
//---------------------------------------------------------------------------
int __fastcall TUpgradeThread::GetUpdateFileList( String ufile, TStringList* ufnLst )
{
int err = 0;
String lfname = m_AppPath + MD5_FILE_NAME;
FILE *ufp = fopen( ((AnsiString)ufile).c_str(), "rb" ),
*lfp = fopen( ((AnsiString)lfname).c_str(), "rb" );
if( !ufp ){
err = -1;
goto exit_line;
}
else if( !lfp ){
if( !MakeMD5File() || !(lfp=fopen( ((AnsiString)lfname).c_str(), "rb" )) ){
err = -2;
goto exit_line;
}
}
{
char lbuf[4096] = "",
ubuf[4096] = "";
fseek( lfp, 0, SEEK_END );
fseek( ufp, 0, SEEK_END );
int lsize = ftell( lfp );
int usize = ftell( ufp );
if(usize==0)
goto exit_line;
fseek( lfp, 0, SEEK_SET );
fseek( ufp, 0, SEEK_SET );
fread( lbuf, 1, lsize, lfp );
fread( ubuf, 1, usize, ufp );
fclose( lfp );
fclose( ufp );
lfp = ufp = NULL;
TStringList *lfnLst = new TStringList,
*lmdLst = new TStringList,
*umdLst = new TStringList;
char *tokenPtr=strtok(lbuf,"\n");
while( tokenPtr ){
char* pos = strstr( tokenPtr, "\t" );
if( pos ){
char buf[256];
memcpy( buf, tokenPtr, pos-tokenPtr );
buf[pos-tokenPtr] = 0;
lfnLst->Add( buf );
lmdLst->Add( pos+1 );
}
tokenPtr=strtok(NULL,"\n");
}
tokenPtr=strtok(ubuf,"\n");
while( tokenPtr ){
char* pos = strstr( tokenPtr, "\t" );
if( pos ){
char buf[256];
memcpy( buf, tokenPtr, pos-tokenPtr );
buf[pos-tokenPtr] = 0;
ufnLst->Add( buf );
umdLst->Add( pos+1 );
}
tokenPtr=strtok(NULL,"\n");
}
String strProg1, strProg2;
int count = ufnLst->Count;
for( int i=ufnLst->Count-1; i>=0; i-- ){
if( m_hWnd ){
strProg1 = L"文件数 " + IntToStr( count-i-1 ) + L"/" + IntToStr(count);
SendMessage( m_hWnd, UM_SHOWTEXT, 1, (LPARAM)strProg1.c_str() );
int pos = (int)( (count-i-1)*100.0/count + 0.5 );
SendMessage( m_hWnd, UM_PROGRESS, 0, pos );
strProg2 = L"当前比对文件 " + (*ufnLst)[i];
SendMessage( m_hWnd, UM_SHOWTEXT, 2, (LPARAM)strProg2.c_str() );
}
int count2 = lfnLst->Count;
for( int j=lfnLst->Count-1; j>=0; j-- ){
if( m_hWnd ){
int pos = (int)( (count2-j)*100.0/count2 + 0.5 );
SendMessage( m_hWnd, UM_PROGRESS, 1, pos );
}
// String ufn = (*ufnLst)[i],
// lfn = (*lfnLst)[j];
if( !(*ufnLst)[i].CompareIC( (*lfnLst)[j] ) ){
// String umd = (*umdLst)[i],
// lmd = (*lmdLst)[j];
if( !(*umdLst)[i].CompareIC( (*lmdLst)[j] ) ){
ufnLst->Delete( i );
umdLst->Delete( i );
}
lfnLst->Delete( j );
lmdLst->Delete( j );
break;
}
}
}
delete lfnLst;
delete lmdLst;
delete umdLst;
}
exit_line:
if( ufp )
fclose( ufp );
if( lfp )
fclose( lfp );
return err;
}
//---------------------------------------------------------------------------
int __fastcall TUpgradeThread::RegUpdateFlag( int iUpdate )
{
FILE* fp = fopen( ((AnsiString)m_GlobalFile).c_str(), "r+b" );
if( fp ){
TGVFHEADER header;
header.idSoftware = m_idSoft;
header.iUpdate = iUpdate;
fseek( fp, 0, SEEK_SET );
fwrite( (void*)&header, sizeof(header), 1, fp );
fclose( fp );
}
return 0;
}
//---------------------------------------------------------------------------
int __fastcall TUpgradeThread::ClearUpdateDir()
{
TSearchRec sr;
int iAttr = 0;
String strPath = m_AppPath + L"upgrade\\";
if( FindFirst(strPath + L"*.*", iAttr, sr)==0 ){
do{
if( !(iAttr & faDirectory) ){
DeleteFile( strPath + sr.Name );
}
}
while( FindNext(sr)==0 );
FindClose(sr);
}
return 0;
}
//---------------------------------------------------------------------------
bool __fastcall TUpgradeThread::UpdateFiles()
{
bool bSuccess = true;
TSearchRec sr;
int iAttr = 0;
String strPath = m_AppPath + L"upgrade\\";
//先关闭主程序
StopApp();
Sleep(1000); //等待app完全退出
if( FindFirst(strPath + L"*.*", iAttr, sr)==0 ){
do{
if( !(iAttr & faDirectory) && sr.Name.CompareIC(UPDATE_APP_NAME) ){
String fOld = strPath + sr.Name,
fNew = m_AppPath + sr.Name;
if( !MoveFileEx( fOld.c_str(), fNew.c_str(), MOVEFILE_REPLACE_EXISTING|MOVEFILE_WRITE_THROUGH ) ){
bSuccess = false;
break;
}
}
}
while( FindNext(sr)==0 );
FindClose(sr);
}
return bSuccess;
}
//---------------------------------------------------------------------------
int __fastcall TUpgradeThread::RestartApp()
{
//启动主程序
HANDLE hToken = NULL,
hTokenDup = NULL;
if(OpenProcessToken(GetCurrentProcess(),TOKEN_ALL_ACCESS,&hToken)){
if(DuplicateTokenEx(hToken, TOKEN_ALL_ACCESS,NULL, SecurityIdentification,
TokenPrimary, &hTokenDup)){
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si,sizeof(STARTUPINFO));
ZeroMemory(&pi,sizeof(PROCESS_INFORMATION));
si.cb = sizeof(STARTUPINFO);
si.lpDesktop = NULL;
si.lpReserved = NULL;
si.lpTitle = NULL;
si.cbReserved2 = NULL;
si.lpReserved2 = NULL;
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_SHOWNORMAL;
String command = "\"" + m_AppPath + MAIN_APP_NAME + "\"";
CreateProcessAsUser(hTokenDup,NULL,command.c_str(),NULL,NULL,FALSE,0,NULL,NULL,&si,&pi);
}
}
return 0;
}
//---------------------------------------------------------------------------
bool __fastcall TUpgradeThread::StopApp()
{
HANDLE hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS,0 ); //获取进程快照
if( hSnapshot ){
DWORD idProcess = 0;
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof( PROCESSENTRY32 );
if(!Process32First( hSnapshot, &pe32 )){ //指向第一个进程
CloseHandle(hSnapshot);
return false;
}
do{
if( lstrcmpi( pe32.szExeFile, MAIN_APP_NAME.c_str() )==0 ){ //查找进程
if( SameModulePath( pe32.th32ProcessID )){
idProcess = pe32.th32ProcessID;
break;
}
}
}
while( Process32Next(hSnapshot, &pe32) ); // 循环直到取不到进程
if( idProcess ){
HANDLE hApp= OpenProcess( PROCESS_ALL_ACCESS, FALSE, idProcess ); //根据进程ID获取程序的句柄
if( hApp ){
if( WaitForSingleObject( hApp, 2000 )==WAIT_TIMEOUT )// 等待程序关闭2秒
TerminateProcess( hApp, 0 );
CloseHandle( hApp );
}
}
CloseHandle( hSnapshot );
}
return true;
}
//---------------------------------------------------------------------------
#define PSAPI_VERSION 1
#include <psapi.h>
#pragma comment(lib,"psapi")
bool __fastcall TUpgradeThread::SameModulePath(DWORD dwPID)
{
TCHAR sFilename[MAX_PATH];
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwPID);
if (hProcess == NULL)
return false;
bool bSame = false;
HMODULE hModule;
DWORD cbNeeded;
if (EnumProcessModules(hProcess, &hModule, sizeof(hModule), &cbNeeded)){
if (GetModuleFileNameEx(hProcess, hModule, sFilename, MAX_PATH)){
if(wcslen(sFilename)>0){
String sFullName = TPath::GetFullPath(sFilename);
if( !m_PathName.CompareIC( sFilename ) )
bSame = true;
}
}
}
else{
DWORD size = MAX_PATH;
if (QueryFullProcessImageName(hProcess, 0, sFilename, &size)){
if( !m_PathName.CompareIC( sFilename ) )
bSame = true;
}
}
CloseHandle(hProcess);
return bSame;
}
//---------------------------------------------------------------------------
+62
View File
@@ -0,0 +1,62 @@
//---------------------------------------------------------------------------
#ifndef UpgradeThreadH
#define UpgradeThreadH
//---------------------------------------------------------------------------
#define UM_SHOWTEXT WM_USER+0x1000
#define UM_PROGRESS WM_USER+0x1001
#define UM_COMPLETE WM_USER+0x1003
#define ERROR_OPEN_FILE 10
#define ERROR_MEMORY 11
#define ERROR_SIZE 12
#define ERROR_INTERNET_OPEN 13
#define ERROR_INTERNET_CONN 14
#define ERROR_INTERNET_REQ 15
#define ERROR_INTERNET_SEND 16
#define ERROR_FILELIST_GET 17
#define ERROR_FILE_SIZE 18
//---------------------------------------------------------------------------
class TUpgradeThread : public TThread
{
private:
int m_iMode,
m_idSoft;
HWND m_hWnd;
HANDLE m_hSema;
TStringList* m_lstMD5;
bool m_bUpdateSelf; //ÊÇ·ñ¸üÐÂ×ÔÉí
String m_AppPath,
m_PathName,
m_Server,
m_UpdateUrl,
m_GlobalFile;
bool __fastcall MakeMD5File();
bool __fastcall GetFileList(TStringList* pList);
bool __fastcall GenerateFileMD5( String fname, String& md5 );
String __fastcall GetUpdateMD5File();
int __fastcall GetUpdateFileList( String ufile, TStringList* pList );
int __fastcall DownloadFile( String url, String filename );
String __fastcall GetUpdateURL();
int __fastcall GetServers( TStringList* pList );
int __fastcall RegUpdateFlag( int iUpdate );
int __fastcall ClearUpdateDir();
bool __fastcall UpdateFiles();
int __fastcall RestartApp();
bool __fastcall StopApp();
bool __fastcall SameModulePath(DWORD dwPID);
protected:
void __fastcall Execute();
public:
TStringList* m_lstFile;
__fastcall TUpgradeThread(bool CreateSuspended, int mode, int sid, String sVar, HWND hWnd=NULL );
void __fastcall Cancel();
};
//---------------------------------------------------------------------------
#endif
+122
View File
@@ -0,0 +1,122 @@
//---------------------------------------------------------------------------
#include <vcl.h>
#include <stdio.h>
#pragma hdrstop
#include "UpgradeThread.h"
#include "UpgradeUnit.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TUpgradeForm *UpgradeForm;
//---------------------------------------------------------------------------
__fastcall TUpgradeForm::TUpgradeForm(TComponent* Owner)
: TForm(Owner)
{
m_pThread = NULL;
}
//---------------------------------------------------------------------------
void __fastcall TUpgradeForm::CreateParams(TCreateParams &Params)
{
TForm::CreateParams(Params);
// wcscpy(Params.WinClassName.data, (LPCTSTR)APPNAME);
wcscpy(Params.WinClassName, (LPCTSTR)APPNAME);
}
// ---------------------------------------------------------------------------
void __fastcall TUpgradeForm::FormDestroy(TObject *Sender)
{
if( m_pThread ){
((TUpgradeThread*)m_pThread)->Cancel();
m_pThread->WaitFor();
delete m_pThread;
m_pThread = NULL;
}
}
//---------------------------------------------------------------------------
void __fastcall TUpgradeForm::FormCloseQuery(TObject *Sender, bool &CanClose)
{
if( m_pThread ){
String msg = m_iMode==1 ? L"正在处理中,确认退出程序?"
: L"正在升级中,是否确定中止?";
int mrRet = MessageBox(Handle, msg.c_str(), L"退出",
MB_ICONQUESTION | MB_YESNO);;
if( mrRet==mrNo )
CanClose = false;
}
}
//---------------------------------------------------------------------------
void __fastcall TUpgradeForm::FormShow(TObject *Sender)
{
Caption = m_iMode==0 ? L"自动升级程序"
: L"MD5生成程序";
m_pThread = new TUpgradeThread(true, m_iMode, m_idSoft, m_sVar, Handle );
m_pThread->Start();
}
//---------------------------------------------------------------------------
void __fastcall TUpgradeForm::UMShowText(TMessage &msg)
{
TCHAR* str = (TCHAR*)msg.LParam;
if( msg.WParam==0 )
m_lblTxt->Caption = str;
else if( msg.WParam==1 )
m_lblFileCount->Caption = str;
else
m_lblFileName->Caption = str;
}
//---------------------------------------------------------------------------
void __fastcall TUpgradeForm::UMProgress(TMessage &msg)
{
if( msg.WParam==0 ){
m_progCount->Position = msg.LParam;
m_progCount->Update();
}
else{
m_progFile->Position = msg.LParam;
m_progFile->Update();
}
}
//---------------------------------------------------------------------------
void __fastcall TUpgradeForm::UMComplete(TMessage &msg)
{
if( m_pThread ){
m_pThread->WaitFor();
delete m_pThread;
m_pThread = NULL;
}
if( m_iMode==0 ){
if( msg.WParam!=0 )
ShowMessage( "本次更新未能完成" );
}
else if( m_iMode==1 ){
if( msg.WParam==0 )
ShowMessage( "处理完毕" );
else
ShowMessage( "异常中止" );
}
Close();
}
//---------------------------------------------------------------------------
void __fastcall TUpgradeForm::CancelClick(TObject *Sender)
{
Close();
}
//---------------------------------------------------------------------------
+71
View File
@@ -0,0 +1,71 @@
object UpgradeForm: TUpgradeForm
Left = 0
Top = 0
BorderIcons = [biSystemMenu, biMinimize]
BorderStyle = bsSingle
Caption = 'MD5'#29983#25104#31243#24207
ClientHeight = 203
ClientWidth = 509
Color = clBtnFace
DoubleBuffered = True
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
FormStyle = fsStayOnTop
Position = poDesktopCenter
Scaled = False
OnCloseQuery = FormCloseQuery
OnDestroy = FormDestroy
OnShow = FormShow
TextHeight = 13
object m_lblFileCount: TLabel
Left = 24
Top = 93
Width = 329
Height = 13
AutoSize = False
Caption = #22788#29702#25991#20214#25968
end
object m_lblTxt: TLabel
Left = 24
Top = 40
Width = 329
Height = 13
AutoSize = False
Caption = #27491#22312#22788#29702
end
object m_lblFileName: TLabel
Left = 24
Top = 141
Width = 329
Height = 13
AutoSize = False
Caption = #22788#29702#25991#20214
end
object m_progCount: TProgressBar
Left = 24
Top = 112
Width = 457
Height = 17
TabOrder = 0
end
object m_progFile: TProgressBar
Left = 24
Top = 160
Width = 457
Height = 17
TabOrder = 1
end
object m_btnCancel: TButton
Left = 400
Top = 35
Width = 75
Height = 25
Caption = #21462#28040
ModalResult = 2
TabOrder = 2
OnClick = CancelClick
end
end
+52
View File
@@ -0,0 +1,52 @@
//---------------------------------------------------------------------------
#ifndef UpgradeUnitH
#define UpgradeUnitH
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <Vcl.ComCtrls.hpp>
#define APPNAME "APP×Ô¶¯Éý¼¶³ÌÐò\0"
//---------------------------------------------------------------------------
class TUpgradeForm : public TForm
{
__published: // IDE-managed Components
TLabel *m_lblFileCount;
TProgressBar *m_progCount;
TLabel *m_lblTxt;
TProgressBar *m_progFile;
TLabel *m_lblFileName;
TButton *m_btnCancel;
void __fastcall FormDestroy(TObject *Sender);
void __fastcall FormCloseQuery(TObject *Sender, bool &CanClose);
void __fastcall FormShow(TObject *Sender);
void __fastcall CancelClick(TObject *Sender);
private: // User declarations
TThread *m_pThread;
void __fastcall CreateParams(TCreateParams &Params);
MESSAGE void __fastcall UMProgress(TMessage &msg);
MESSAGE void __fastcall UMShowText(TMessage &msg);
MESSAGE void __fastcall UMComplete(TMessage &msg);
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(UM_PROGRESS, TMessage, UMProgress)
MESSAGE_HANDLER(UM_SHOWTEXT, TMessage, UMShowText)
MESSAGE_HANDLER(UM_COMPLETE, TMessage, UMComplete)
END_MESSAGE_MAP(TForm)
public: // User declarations
__fastcall TUpgradeForm(TComponent* Owner);
int m_iMode;
int m_idSoft;
String m_sVar;
};
//---------------------------------------------------------------------------
extern PACKAGE TUpgradeForm *UpgradeForm;
//---------------------------------------------------------------------------
#endif