Files
winapp/RBmaster.cpp
2026-06-12 22:37:02 +08:00

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;
}
//---------------------------------------------------------------------------