BSOne.SFC/eCrmHE/EXE_eCrmHomeEdition/Thread/ThdWinUpdateScan.pas

231 lines
5.9 KiB
Plaintext

{*******************************************************}
{ }
{ ThdWinUpdateScan }
{ }
{ Copyright (C) 2022 kku }
{ }
{*******************************************************}
unit ThdWinUpdateScan;
interface
uses
Tocsg.Thread, System.SysUtils, System.Classes, Winapi.Windows, Tocsg.Win32;
type
TThdWinUpdateScan = class(TTgThread)
protected
dwCheckTick_: DWORD;
ProcInfo_: TProcessInformation;
dtHlpBegin_: TDateTime;
Mtx_: TTgMutex;
hRcvWnd_,
hHlpWnd_: HWND;
procedure SetRcvWnd(h: HWND);
procedure Execute; override;
public
Constructor Create(hRcvWnd: HWND);
Destructor Destroy; override;
procedure DoCheckUpdate;
property RcvWnd: HWND write SetRcvWnd;
end;
implementation
uses
Tocsg.WinInfo, ManagerService, Tocsg.Exception, Winapi.ActiveX,
System.Win.ComObj, System.Variants, superobject, Tocsg.Path, GlobalDefine,
DefineHelper, Tocsg.Process, System.DateUtils;
{ TThdWinUpdateScan }
Constructor TThdWinUpdateScan.Create(hRcvWnd: HWND);
begin
Inherited Create;
hRcvWnd_ := hRcvWnd;
dwCheckTick_ := 0;
dtHlpBegin_ := 0;
hHlpWnd_ := 0;
ZeroMemory(@ProcInfo_, SizeOf(ProcInfo_));
Mtx_ := TTgMutex.Create('Global\WUS_' + IntToStr(NativeUInt(Self)));
end;
Destructor TThdWinUpdateScan.Destroy;
begin
FreeAndNil(Mtx_);
Inherited;
end;
procedure TThdWinUpdateScan.DoCheckUpdate;
begin
dwCheckTick_ := 0;
end;
procedure TThdWinUpdateScan.SetRcvWnd(h: HWND);
begin
hHlpWnd_ := h;
end;
//{$DEFINE _INTERNAL_SCAN_}
procedure TThdWinUpdateScan.Execute;
var
sHlpExe: String;
procedure CreateProcessHLP;
var
hProcess: THandle;
O: ISuperObject;
sParam: String;
begin
if not FileExists(sHlpExe) then
exit;
try
if ProcInfo_.dwProcessId <> 0 then
TerminateProcessByPid(ProcInfo_.dwProcessId);
hHlpWnd_ := 0;
dtHlpBegin_ := 0;
ZeroMemory(@ProcInfo_, SizeOf(ProcInfo_));
O := SO;
O.I['RcvWnd'] := hRcvWnd_;
O.I['Cmd'] := HLP_ROLE_WINDOWS_UPDATE_SCAN;
O.S['Mtx'] := Mtx_.MutexName;
if SaveJsonObjToFile(O, GetRunExePathDir + DIR_CONF + DAT_PARAM) then
begin
ProcInfo_ := ExecuteApp(sHlpExe, Format('-p "%s"', [sParam]), SW_SHOWNORMAL);
if ProcInfo_.dwProcessId = 0 then
begin
{$IFDEF DEBUG}
ASSERT(false);
{$ELSE}
_Trace('Fail .. CreateProcessHLP() .. ExecuteApp()');
{$ENDIF}
end else
dtHlpBegin_ := Now;
end else
_Trace('Fail .. CreateProcessHLP() .. SaveJsonObjToFile()');
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. CreateProcessHLP()');
end;
end;
const
INTERVAL_SEC = 15;
var
dwTick: DWORD;
oUpdateSession,
oUpdateSearcher,
oUpdateEntry,
oUpdateSearchResult,
oUpdateCollection: OleVariant;
oEnum: IEnumvariant;
iValue: LongWord;
bUpdateAlbe: Boolean;
Label
LB_CreateObject;
begin
sHlpExe := GetRunExePathDir + DIR_CONF + EXE_HLP;
if not FileExists(sHlpExe) then
_Trace('Not found HelperExe..');
CoInitialize(nil);
try
{$IFDEF _INTERNAL_SCAN_}
oUpdateSession := varNull;
bUpdateAlbe := false;
LB_CreateObject :
try
oUpdateSession := CreateOleObject('Microsoft.Update.Session');
oUpdateSearcher := oUpdateSession.CreateUpdateSearcher;
bUpdateAlbe := true;
except
on E: Exception do
ETgException.TraceException(E, 'Fail .. Fail .. CreateOleObject()');
end;
if (not Terminated and not GetWorkStop) and
not bUpdateAlbe then
begin
Sleep(1000);
goto LB_CreateObject;
end;
{$ENDIF}
while not Terminated and not GetWorkStop do
begin
bUpdateAlbe := false;
try
dwTick := GetTickCount;
if (dwCheckTick_ = 0) or
(((dwTick - dwCheckTick_) div 1000) >= 15) then
begin
dwCheckTick_ := dwTick;
{$IFDEF _INTERNAL_SCAN_}
try
// oUpdateSearchResult := oUpdateSearcher.Search('IsInstalled = 1'); // for Test
oUpdateSearchResult := oUpdateSearcher.Search('IsInstalled = 0 and Type != ''Driver'' and IsHidden = 0 and BrowseOnly = 0');
oUpdateCollection := oUpdateSearchResult.Updates;
oEnum := IUnknown(oUpdateCollection._NewEnum) as IEnumVariant;
oEnum.Reset;
try
while oEnum.Next(1, oUpdateEntry, iValue) = 0 do
begin
bUpdateAlbe := true;
// _Trace(oUpdateEntry.Title);
VarClear(oUpdateEntry);
oUpdateEntry := Unassigned;
break;
end;
finally
// oEnum._Release;
// VarClear(oUpdateEntry);
oUpdateCollection := Unassigned;
VarClear(oUpdateCollection);
oUpdateSearchResult := Unassigned;
VarClear(oUpdateSearchResult);
end;
except
// ..
end;
gMgSvc.SetPatchUpdate(not bUpdateAlbe);
{$ELSE}
// 직접 처리하면 메모리릭이 발생해서 별도 프로세스로 뺌... 22_1222 10:38:08 kku
if (hHlpWnd_ = 0) or (ProcInfo_.dwProcessId = 0) or
(GetProcessNameByPid(ProcInfo_.dwProcessId) = '') or
( (dtHlpBegin_ > 0) and
(HoursBetween(dtHlpBegin_, Now) >= 4) ) then
begin
CreateProcessHLP;
end else
PostMessage(hHlpWnd_, WM_REQUEST_HLEPER, HLP_ROLE_WINDOWS_UPDATE_SCAN, 0);
{$ENDIF}
end;
Sleep(1000);
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. Execute()');
end;
end;
finally
VarClear(oUpdateSearcher);
VarClear(oUpdateSession);
CoUninitialize;
end;
end;
end.