program AddZTMsToHst;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.Classes,
System.SysUtils,
System.IOUtils,
System.Types,
Winapi.Windows;
var
gNumFilesPresent, gNumFilesAdded: integer;
{ ------------------------------------------------------------------------------------------------ }
procedure AddZTMsToZTWHST(const ZTPath: string);
var
PreviousDir: TFileName;
History: TStringList;
HistoryFile, TempFile, BackupFile: TFileName;
ZTMs: TStringDynArray;
ZTM: string;
begin
PreviousDir := GetCurrentDir;
SetCurrentDir(ZTPath);
HistoryFile := TPath.Combine(ZTPath, 'ZTW.HST');
History := TStringList.Create;
try
History.LoadFromFile(HistoryFile);
// Get a list of all the ZTM files
ZTMs := TDirectory.GetFiles(ZTPath, '*.ztm', TSearchOption.soTopDirectoryOnly,
function (const Path: string; const SearchRec: TSearchRec): boolean
var
Entry: string;
FileName: TFileName;
begin
FileName := TPath.Combine(Path, SearchRec.Name);
for Entry in History do begin
if (Entry.Length > 4) and Entry.StartsWith('zf') and (Entry.Substring(3, 1) = '@') then begin
Result := not SameFileName(FileName, ExpandFileName(Entry.Substring(4)));
if Result = False then begin
Inc(gNumFilesPresent);
WriteLn('Skipping: ', SearchRec.Name);
Exit;
end;
end;
end;
Result := True;
end);
for ZTM in ZTMs do begin
History.Add('zf=@' + ZTM);
Inc(gNumFilesAdded);
WriteLn('Adding: ', ExtractFileName(ZTM));
end;
if gNumFilesAdded > 0 then begin
TempFile := ChangeFileExt(HistoryFile, '.~' + ExtractFileExt(HistoryFile).Substring(2));
History.SaveToFile(TempFile);
BackupFile := HistoryFile + '.BAK';
if not ReplaceFile(PChar(HistoryFile), PChar(TempFile), PChar(BackupFile), REPLACEFILE_IGNORE_MERGE_ERRORS, nil, nil) then
RaiseLastOSError;
end;
finally
History.Free;
end;
SetCurrentDir(PreviousDir);
end {AddZTMsToZTWHST};
{ ------------------------------------------------------------------------------------------------ }
// From http://stackoverflow.com/a/1634007/60590
function Is64BitOS: Boolean;
type
TIsWow64Process = function(Handle:THandle; var IsWow64 : BOOL) : BOOL; stdcall;
var
hKernel32 : Integer;
IsWow64Process : TIsWow64Process;
IsWow64 : BOOL;
begin
// we can check if the operating system is 64-bit by checking whether
// we are running under Wow64 (we are 32-bit code). We must check if this
// function is implemented before we call it, because some older versions
// of kernel32.dll (eg. Windows 2000) don't know about it.
// see http://msdn.microsoft.com/en-us/library/ms684139.aspx
Result := False;
hKernel32 := LoadLibrary('kernel32.dll');
if (hKernel32 = 0) then RaiseLastOSError;
@IsWow64Process := GetProcAddress(hkernel32, 'IsWow64Process');
if Assigned(IsWow64Process) then begin
IsWow64 := False;
if (IsWow64Process(GetCurrentProcess, IsWow64)) then begin
Result := IsWow64;
end
else RaiseLastOSError;
end;
FreeLibrary(hKernel32);
end{Is64BitOS};
{ ------------------------------------------------------------------------------------------------ }
function FindZTreeWin: string;
var
ExeName: string;
BufferLength: Cardinal;
PFilenamePart: PChar;
begin
try
if Is64BitOS then
ExeName := 'ZTW64.EXE'
else
ExeName := 'ZTW.EXE';
BufferLength := 32768;
SetLength(Result, BufferLength - 1);
SetLength(Result, SearchPath(nil, PChar(ExeName), nil, BufferLength, PChar(Result), PFilenamePart));
// if Length(Result) = 0 then
// RaiseLastOSError;
// TODO: if not found in path, check the registry?
except
Exception.RaiseOuterException(Exception.CreateFmt('Could not find %s!', [ExeName]));
end;
end {FindZTreeWin};
{ ================================================================================================ }
var
ZTHome: string;
begin
try
if ParamStr(1) <> '' then begin
ZTHome := ParamStr(1)
end else begin
ZTHome := ExtractFilePath(FindZTreeWin);
if ZTHome = '' then begin
ZTHome := GetCurrentDir;
end;
end;
gNumFilesPresent := 0;
gNumFilesAdded := 0;
AddZTMsToZTWHST(ZTHome);
WriteLn(gNumFilesPresent + gNumFilesAdded, ' files found; ', gNumFilesAdded, ' files added to ZTW.HST.');
except
on E: Exception do
Writeln(ErrOutput, E.ClassName, ': ', E.Message);
end;
end.