{*******************************************************} { } { 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.