336 lines
8.9 KiB
C++
336 lines
8.9 KiB
C++
//---------------------------------------------------------------------------
|
|
#include <vcl.h>
|
|
#include <tchar.h>
|
|
#include <System.IOUtils.hpp>
|
|
#include <Winternl.h>
|
|
#pragma hdrstop
|
|
|
|
#include "CommonV8Handler.h"
|
|
#include "GlobalUnit.h"
|
|
|
|
//---------------------------------------------------------------------------
|
|
#include <Vcl.Styles.hpp>
|
|
#include <Vcl.Themes.hpp>
|
|
#pragma package(smart_init)
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// 获取父进程函数
|
|
typedef struct _PROCESS_BASIC_INFORMATIONWOW64 {
|
|
NTSTATUS ExitStatus;
|
|
ULONG64 PebBaseAddress;
|
|
ULONG64 AffinityMask;
|
|
LONG BasePriority;
|
|
ULONG64 UniqueProcessId;
|
|
ULONG64 InheritedFromUniqueProcessId;
|
|
} PROCESS_BASIC_INFORMATION_WOW64;
|
|
|
|
typedef LONG (WINAPI *PNTQUERYINFORMATIONPROCESS)(HANDLE,UINT,PVOID,ULONG,PULONG);
|
|
|
|
DWORD GetParentProcessId(DWORD pid)//获取指定进程的父进程ID
|
|
{
|
|
DWORD dwParentPID = 0;
|
|
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
|
|
if( !hProcess ){
|
|
//ShowMessage( "OpenProcess err" );
|
|
return -1;
|
|
}
|
|
PNTQUERYINFORMATIONPROCESS NtQueryInformationProcess = NULL;
|
|
BOOL bProcWow = FALSE;
|
|
IsWow64Process(hProcess, &bProcWow);
|
|
if( bProcWow==TRUE ){
|
|
//ShowMessage( "32bit" );
|
|
NtQueryInformationProcess = (PNTQUERYINFORMATIONPROCESS)GetProcAddress(GetModuleHandleA("ntdll.dll"),
|
|
"NtWow64QueryInformationProcess64");
|
|
PROCESS_BASIC_INFORMATION_WOW64 pbi;
|
|
NTSTATUS status = NtQueryInformationProcess(hProcess, ProcessBasicInformation, (PVOID)&pbi,
|
|
sizeof(PROCESS_BASIC_INFORMATION_WOW64), NULL);
|
|
//ShowMessage("NtWow64Query return: " + IntToHex((int)status));
|
|
if( NT_SUCCESS(status) )
|
|
dwParentPID = (DWORD)pbi.InheritedFromUniqueProcessId;
|
|
}
|
|
else{
|
|
//ShowMessage( "64bit" );
|
|
NtQueryInformationProcess = (PNTQUERYINFORMATIONPROCESS)GetProcAddress(GetModuleHandleA("ntdll.dll"),
|
|
"NtQueryInformationProcess");
|
|
PROCESS_BASIC_INFORMATION pbi;
|
|
NTSTATUS status = NtQueryInformationProcess(hProcess, ProcessBasicInformation, (PVOID)&pbi,
|
|
sizeof(PROCESS_BASIC_INFORMATION), NULL);
|
|
//ShowMessage("NtQuery return: " + IntToHex((int)status));
|
|
if( NT_SUCCESS(status) )
|
|
dwParentPID = (DWORD)pbi.Reserved3;
|
|
}
|
|
CloseHandle(hProcess);
|
|
|
|
|
|
return dwParentPID;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// 定义枚举窗口回调函数
|
|
BOOL CALLBACK EnumWndProc(HWND hwnd, LPARAM lParam)
|
|
{
|
|
HANDLE h = GetProp(hwnd, _TEXT(APPABBR));
|
|
if(h == (HANDLE)SOFTWARE_ID) {
|
|
*(HANDLE*)lParam = hwnd;
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// CEF初始化函数
|
|
|
|
bool InitCef()
|
|
{
|
|
GlobalCEFApp = new TCefApplication;
|
|
|
|
GlobalCEFApp->Cache = String(g_AppPath) + "cache";
|
|
GlobalCEFApp->Locale = "zh-CN";
|
|
GlobalCEFApp->AcceptLanguageList = "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6";
|
|
|
|
if(g_bTesting){
|
|
GlobalCEFApp->LogFile = "debug-" + IntToStr(DateTimeToUnix(Now(), false)) + ".log";
|
|
GlobalCEFApp->LogSeverity = LOGSEVERITY_INFO; //LOGSEVERITY_VERBOSE; //
|
|
}
|
|
else{
|
|
GlobalCEFApp->LogSeverity = LOGSEVERITY_DISABLE;
|
|
}
|
|
|
|
GlobalCEFApp->CheckCEFFiles = false;
|
|
// GlobalCEFApp->PackLoadingDisabled = false;
|
|
GlobalCEFApp->PersistSessionCookies = true;
|
|
// GlobalCEFApp->PersistUserPreferences = true;
|
|
GlobalCEFApp->IgnoreCertificateErrors = true;
|
|
GlobalCEFApp->NoSandbox = true;
|
|
GlobalCEFApp->MuteAudio = true;
|
|
GlobalCEFApp->EnableGPU = true;
|
|
GlobalCEFApp->SitePerProcess = true; //78.0以上iframe运行js代码必须设置
|
|
GlobalCEFApp->DisableWebSecurity = true; //78.0以上iframe运行js代码必须设置
|
|
GlobalCEFApp->DisableSiteIsolationTrials = true; //78.0以上iframe运行js代码必须设置
|
|
GlobalCEFApp->DisableChromeLoginPrompt = true;
|
|
GlobalCEFApp->EnableMediaStream = false; //true; //
|
|
GlobalCEFApp->LogProcessInfo = false; //true; //
|
|
GlobalCEFApp->SingleProcess = false; //true; //
|
|
GlobalCEFApp->MultiThreadedMessageLoop = true;
|
|
GlobalCEFApp->WindowlessRenderingEnabled = true;
|
|
GlobalCEFApp->DisableImageLoading = true;
|
|
|
|
GlobalCEFApp->OnWebKitInitialized = _di_TOnWebKitInitializedEvent(new TWebKitInitializeEvent());
|
|
|
|
if( !GlobalCEFApp->StartMainProcess() )
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// 子进程判断函数
|
|
bool IsRestart()
|
|
{
|
|
HWND hWnd = NULL;
|
|
if(SINGLE_INSTANCE){
|
|
EnumWindows(EnumWndProc,(LPARAM)&hWnd); //枚举所有运行的窗口
|
|
}
|
|
else{
|
|
String strFullName = TPath::GetFullPath(Application->ExeName);
|
|
HWND hWnd = FindWindow( (LPCTSTR)strFullName.c_str(), NULL );
|
|
}
|
|
|
|
if( hWnd ){
|
|
//ShowMessage("restart");
|
|
|
|
DWORD wndProcess_id = 0;
|
|
DWORD parent_id=GetParentProcessId(GetCurrentProcessId());
|
|
GetWindowThreadProcessId( hWnd, &wndProcess_id );
|
|
|
|
if( wndProcess_id==parent_id ){
|
|
//ShowMessage("SubProcess");
|
|
InitCef();
|
|
return true;
|
|
}
|
|
else{
|
|
SendMessage( hWnd, UM_RESTORE, 0, 0 );
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// 程序自动升级函数
|
|
void StartUpgrade( int mode )
|
|
{
|
|
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 = mode==2 ? SW_SHOWNORMAL //显示进程窗口
|
|
: SW_HIDE; //隐藏进程窗口
|
|
|
|
String command = "\"" + (String)g_AppPath + UPDATE_APP_NAME + "\"";
|
|
if( mode==3 )
|
|
command += " move ";
|
|
else if( mode==2 )
|
|
command += " show ";
|
|
else
|
|
command += " hide ";
|
|
|
|
command += ExtractFileName(Application->ExeName);
|
|
command += " " + IntToStr(SOFTWARE_ID);
|
|
command += " " + String(GLOBAL_VAR_FILE);
|
|
|
|
CreateProcessAsUser(hTokenDup,NULL,command.c_str(),NULL,NULL,FALSE,0,NULL,NULL,&si,&pi);
|
|
}
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
extern bool g_bBacData;
|
|
|
|
void InitUserPath()
|
|
{
|
|
String sAppPath = g_AppPath;
|
|
String sUserPath = sAppPath + "user\\";
|
|
if(!DirectoryExists( sUserPath, false)){
|
|
ForceDirectories( sUserPath );
|
|
}
|
|
|
|
if(g_bBacData){
|
|
String sDataPath = sAppPath + "data\\";
|
|
if(!DirectoryExists( sDataPath, false)){
|
|
ForceDirectories( sDataPath );
|
|
}
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
USEFORM("RBmasterMain.cpp", MainForm);
|
|
//---------------------------------------------------------------------------
|
|
bool Startup()
|
|
{
|
|
String strAppPath = ExtractFileDir(ParamStr(0)) + "\\";
|
|
strcpy( g_AppPath, ((AnsiString)strAppPath).c_str() );
|
|
|
|
for(int i=1; i<=ParamCount(); i++){
|
|
String sParam = LowerCase(ParamStr(i));
|
|
if (sParam == "-d")
|
|
g_bBacData = true;
|
|
else if (sParam == "-testing")
|
|
g_bTesting = true;
|
|
}
|
|
|
|
if( IsRestart() ){
|
|
return false;
|
|
}
|
|
|
|
try{
|
|
Application->Initialize();
|
|
|
|
int tag = 0;
|
|
if( !InitCef() ){
|
|
tag = -5;
|
|
}
|
|
else{
|
|
InitUserPath();
|
|
Application->Title = APPNAME;
|
|
Application->CreateForm(__classid(TMainForm), &MainForm);
|
|
Application->MainFormOnTaskBar = true;
|
|
tag = Application->MainForm->Tag;
|
|
}
|
|
|
|
bool bRun(0);
|
|
if( tag==0 ){
|
|
bRun = true;
|
|
}
|
|
else if( tag==-1 ){
|
|
ShowMessage( "加载应用模块失败,退出程序" );
|
|
}
|
|
else if( tag==-3 ){
|
|
ShowMessage( "连接服务器失败,退出程序" );
|
|
}
|
|
else if( tag==-4 ){
|
|
ShowMessage( "软件已停止运行,退出程序" );
|
|
}
|
|
else if( tag==-5 ){
|
|
ShowMessage( "初始化网络模块失败,退出程序" );
|
|
return false;
|
|
}
|
|
else{
|
|
int mode = tag;
|
|
if( tag==4 ){
|
|
int mrRet = MessageBox(NULL, L"检测到有新的版本,是否立即升级?",
|
|
APPNAME, MB_ICONQUESTION | MB_YESNO);
|
|
if( mrRet==mrYes )
|
|
mode = 2;
|
|
else
|
|
mode = 0;
|
|
}
|
|
else if( tag==2 ){
|
|
ShowMessage( "软件运行需更新相关组件,即将启动更新程序" );
|
|
}
|
|
|
|
bRun = mode<=1;
|
|
|
|
if( mode>0 )
|
|
StartUpgrade( mode );
|
|
}
|
|
|
|
if(bRun){
|
|
if(!g_bTesting)
|
|
SetProp(Application->MainFormHandle, _TEXT(APPABBR), (HANDLE)SOFTWARE_ID);
|
|
|
|
Application->HintHidePause = 10000;
|
|
Application->MainForm->Show();
|
|
|
|
Application->Run();
|
|
|
|
if(!g_bTesting)
|
|
RemoveProp(Application->MainFormHandle, _TEXT(APPABBR));
|
|
}
|
|
|
|
DestroyGlobalCEFApp();
|
|
}
|
|
catch (Exception &exception)
|
|
{
|
|
Application->ShowException(&exception);
|
|
}
|
|
catch (...)
|
|
{
|
|
try
|
|
{
|
|
throw Exception("");
|
|
}
|
|
catch (Exception &exception)
|
|
{
|
|
Application->ShowException(&exception);
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
int WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
|
|
{
|
|
if( !Startup() )
|
|
return -1;
|
|
|
|
return 0;
|
|
}
|
|
//---------------------------------------------------------------------------
|