how to get recycle bin size lazarus / 34-Windows ---------------------------------------------------------------------- Ericktux · 2022-03-19 12:11 hello friends good morning a query, how can I get the size of the recycle bin in bytes ---------------------------------------------------------------------- trev · 2022-03-19 13:11 Operating system? ---------------------------------------------------------------------- Ericktux · 2022-03-19 15:13 Quote from: trev on March 19, 2022, 02:11:11 pmOperating system? hello friends, I am needing for windows ---------------------------------------------------------------------- balazsszekely · 2022-03-20 16:55 @Ericktux Quotehello friends good morning a query, how can I get the size of the recycle bin in bytes AFAIK there is no api for this, but you can read the value from registry. 1. Get the GUID of a drive with TProcess and mount volume: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i uses Process, Registry; function GetDriveGUID(ADrive: Char): String;var  Process: TProcess;  SL: TStringList;  P1, P2: Integer;begin  Result := '';  Process := TProcess.Create(nil);  try    Process.Executable := 'mountvol';    Process.Parameters.Add(ADrive + ':\');    Process.Parameters.Add('/L');    Process.Options := Process.Options + [poUsePipes];    Process.Execute;    SL := TStringList.Create;    try      SL.LoadFromStream(Process.Output);      if Trim(SL.Text) <> '' then      begin        P1 := Pos('{', SL.Text);        P2 := Pos('}', SL.Text);        if (P1 > 0) and (P2 > 0) then          Result := Copy(SL.Text, P1, P2 - P1 + 1);      end;    finally      SL.Free;    end;  finally    Process.Free;  end;end;                         2. Read the value from registry Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function ReadFromRegistry(AGUID: String): Integer;var  Registry: TRegistry;  RegKey: String;  RegValue: String;begin  Result := -1;  Registry := TRegistry.Create(KEY_READ);  try    Registry.RootKey := HKEY_CURRENT_USER;    RegKey := 'SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\BitBucket\Volume\' + AGUID;    RegValue := 'MaxCapacity';    if Registry.KeyExists(RegKey) then      if Registry.OpenKey(RegKey, False) then        Result := Registry.ReadInteger(RegValue); //the result is in MB  finally    Registry.Free;  end;end; 3. Convert the result from MB to Byte. I leave this step to you. ---------------------------------------------------------------------- Thaddy · 2022-03-20 16:59 There is an api, shellapi.... ---------------------------------------------------------------------- Ericktux · 2022-03-20 23:54 thank you very much friend getmem, as always very kind, sorry for not expressing myself well, what I want is to obtain the size used by the files inside the trash in windows ---------------------------------------------------------------------- BobDog · 2022-03-21 01:23 From shell Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i {$mode delphi}  uses  process;   function dir(path:ansistring;flag:ansistring='s'):ansistring;  var ans:ansistring=' ';  begin  RunCommand('c:\windows\system32\cmd.exe', ['/c', 'dir /'+flag+' '+path], ans);  exit(ans);  end;    var  s:ansistring;  begin   s:=dir('c:\$Recycle.bin');  writeln(s);  writeln;  writeln('Press return to exit');  readln;  end. ---------------------------------------------------------------------- Ericktux · 2022-03-21 04:09 thanks for the help friend, I see that an easy solution is to obtain the size of the folder "c:\$Recycle.bin" of course it would only be for the C drive, but it is a good start ---------------------------------------------------------------------- Remy Lebeau · 2022-03-21 17:13 The path to the Recycle Bin is, of course, configurable.  So you should ask the OS what the path actually is, using either SHGetFolderPath(CSIDL_BITBUCKET) or SHGetKnownFolderPath(FOLDERID_RecycleBinFolder). That being said, have a look at this blog article by Raymond Chen: Invoking commands on items in the Recycle Bin, which (amongst other things) shows you how to enumerate the items in the Recycle Bin using IShellItem.  And then you can query each item for its size to calculate the total size the Recycle Bin is using. ---------------------------------------------------------------------- BobDog · 2022-03-21 18:23 For the recycle bin (size only) then try: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i {$mode delphi}  uses  process,sysutils;   function dir(path:ansistring;flag:ansistring='s'):ansistring;  var ans:ansistring=' ';  begin  RunCommand('c:\windows\system32\cmd.exe', ['/c', 'dir /'+flag+' '+path], ans);  exit(ans);  end;    var  s:ansistring;  x:TStringArray;  begin   s:=dir('c:\$Recycle.bin | findstr File(s)');  x:=s.split(#10);  writeln(x[high(x)-1]);  writeln;  writeln('Press return to exit');  readln;  end.  If your bin is not on c drive then just change it  s:=dir('d:\$Recycle.bin | findstr File(s)'); Tested on Win 10. My result:             9331 File(s)    719,146,331 bytes Press return to exit So I should empty it anytime soon. ---------------------------------------------------------------------- Remy Lebeau · 2022-03-21 18:27 Not everyone installs Windows to the c:\windows folder, so you should ask the OS where the System32 folder is actually located (via GetSystemDirectory(), SHGetFolderPath(CSIDL_SYSTEM[X86]), or SHGetKnownFolderPath(FOLDERID_System[X86])), and then append cmd.exe to the end of it.  Or better, simply query the %CMDSPEC% environment variable instead, which will give you the full path to cmd.exe itself. ---------------------------------------------------------------------- BobDog · 2022-03-21 21:17 Remy Lebeau. I can use "where" to be more general to locate cmd.exe. (and thanks for reminding me that cmd.exe is not necessarily on the c drive) It has been so long since I have had a computer with hard drive partitions, but if I remember correctly there can be a recycle bin on each partition (drive), so I still leave that bit to the user. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i {$mode delphi}  uses  process,sysutils;   function dir(path:ansistring;flag:ansistring='s'):ansistring;  var ans:ansistring=' ';  var location :string='';  begin  RunCommand('where',['cmd.exe'],location);  RunCommand(trim(location), ['/c', 'dir /'+flag+' '+path], ans);  exit(ans);  end;    var  s:ansistring;  x:TStringArray;  begin      s:=dir('C:'+'\$Recycle.bin | findstr File(s)'); //<<--------- user chooses which drive recycle bin.  x:=s.split(#10);  writeln(x[high(x)-1]);  writeln;  writeln('Press return to exit');  readln;  end. ---------------------------------------------------------------------- 440bx · 2022-03-21 21:48 Quote from: BobDog on March 21, 2022, 10:17:25 pm if I remember correctly there can be a recycle bin on each partition (drive), so I still leave that bit to the user. That is the case, one recycle bin per partition.  The reason for it is, when the file is "deleted" it is simply moved to the recycle bin folder instead of copied to it (which is much faster and makes the time spent "deleting" independent of the file size.)  If there was only one recycle bin for all partitions then any "deletion" in the other partitions would require copying the file being deleted which could potentially be very time consuming and would also cause problems with disk space management. HTH. ---------------------------------------------------------------------- rvk · 2022-03-21 23:59 Quote from: 440bx on March 21, 2022, 10:48:39 pmThat is the case, one recycle bin per partition.  The reason for it is, when the file is "deleted" it is simply moved to the recycle bin folder instead of copied to it (which is much faster and makes the time spent "deleting" independent of the file size.)  Yes, it physically one recycle bin per partition. But I think if you use the object Shell.Application THEN the recycle bin will contain (show) the deleted files from ALL the partitions (just like when you open the recycle bin on your desktop, see for yourself by opening the recycle bin on your desktop). In powershell it's easy. It's a oneliner  Code: PowerShell  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i $sum=0; (New-Object -com shell.application).Namespace(10).items() | Foreach {$sum+=$_.Size}; $sum I tried in Lazarus but somehow I couldn't get NameSpace(10) to work correctly. For the C:\Temp it works. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i uses ComObj; procedure TForm1.Button1Click(Sender: TObject);var  ObjShell, ObjFolder: olevariant;  I: integer;begin  ObjShell := CreateOleObject('Shell.Application');  ObjFolder := ObjShell.NameSpace(10); // 10 = RECYCLE_BIN ???????  ObjFolder := ObjShell.NameSpace('C:\Temp'); // DESKTOP  if ObjFolder <> Null then  begin    Memo1.Lines.Add('Folder: ' + ObjFolder.Title);    for I := 0 to ObjFolder.Items.Count - 1 do      Memo1.Lines.Add(ObjFolder.Items.Item(I).Name + ' ' + IntToStr(ObjFolder.Items.Item(I).Size));  end;end; Now why doesn't it work for NameSpace(10) (which should work for the recycle bin). Edit: Ok, I got it working. You really need to pass HEX $A as Variant. This works now: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i uses ComObj; procedure TForm1.Button1Click(Sender: TObject);var  ObjShell, ObjFolder: olevariant;  I, Size: integer;begin  ObjShell := CreateOleObject('Shell.Application');  ObjFolder := ObjShell.NameSpace(OleVariant($A)); // 10 = RECYCLE_BIN  if ObjFolder <> Null then  begin    Memo1.Lines.Add('Folder: ' + ObjFolder.Title);    Size := 0;    for I := 0 to ObjFolder.Items.Count - 1 do      Size := Size + ObjFolder.Items.Item(I).Size;    Memo1.Lines.Add('Total size = ' + Size.ToString);  end;end; Can you work with this? (I found that it's not really lightning fast. I would expected it to iterate through the bin faster.) ---------------------------------------------------------------------- 440bx · 2022-03-22 02:59 Quote from: rvk on March 22, 2022, 12:59:25 amBut I think if you use the object Shell.Application THEN the recycle bin will contain (show) the deleted files from ALL the partitions (just like when you open the recycle bin on your desktop, see for yourself by opening the recycle bin on your desktop). Yes, you're right.  The Windows/File explorer "unifies" all the recycle bins and presents them as one.  Quote from: rvk on March 22, 2022, 12:59:25 amCan you work with this? I appreciate the code and I'm sure the OP will appreciate it even more   I'm just following the thread with some interest.  (the recycle bin is very rarely a concern of mine.) ---------------------------------------------------------------------- Remy Lebeau · 2022-03-22 16:35 Quote from: BobDog on March 21, 2022, 10:17:25 pmI can use "where" to be more general to locate cmd.exe. But why, though?  It is more efficient to just call an API that directly accesses the desired info from the OS's settings, rather than spawn an external program that searches the system and then requires you to manually capture and parse the output. Quote from: BobDog on March 21, 2022, 10:17:25 pmIt has been so long since I have had a computer with hard drive partitions, but if I remember correctly there can be a recycle bin on each partition (drive), so I still leave that bit to the user. All the more reason to use the approach that I or rvk described earlier, to enumerate the contents of the virtual Recycle Bin, which internally accesses the individual physical per-partition Recycle Bin folders for you.  The physical folders are just an implementation detail. ---------------------------------------------------------------------- BobDog · 2022-03-22 19:40 I cannot run rvk's code because I am using Geany ide and  TForm1.Button1Click doesn't go with Geany. Also I am having difficulty querying %CMDSPEC% Could you give an example Remy Lebeau. Here are two different methods to get the memory used (int32 value) Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i  {$mode delphi}  uses  process,sysutils;    function dir(path:ansistring;flag:ansistring='/s'):ansistring;  var ans:ansistring=' ';  var location :string='';  begin  RunCommand('where',['cmd.exe'],location);  RunCommand(trim(location), ['/c', 'dir '+flag+' '+path], ans);  exit(ans);  end;    function binsize(drive:ansistring='C:'):int32;  var  s,t:ansistring;  ans:ansistring='';  x:tstringarray;  c,z,i:int32;  begin   s:=dir(drive+'\$RECYCLE.BIN | FINDSTR /C:File(s)');  x:=s.split(#10);  x:=x[high(x)-1].split(' ');  t:=x[high(x)-1];  for i:=1 to length(t) do if t[i]<>',' then ans:=ans+t[i];  val(ans,z,c);  exit (z);  end;    function filelength(filename:ansistring):longword;Var F : File of byte;var L:longword;beginAssign (F,filename);  Reset (F);  L:=FileSize(F);  Close (F);  exit(L);end; function binsize2(drive:ansistring='C:'):int32;  var  L,i:int32;  a,b:ansistring;  t:tstringarray;  begin  L:=0;  a:=dir(drive+'\$RECYCLE.BIN','/s /b');  t:=a.split(#10);  for i:=low(t) to high(t) do  begin  b:=trim(t[i]);  if fileexists(b) then   L:=L+filelength(b);  end;  exit (L);  end;    var  t:int64;    begin  t:=gettickcount64; writeln(binsize,'  bytes  ','time taken ',gettickcount64-t); t:=gettickcount64; writeln(binsize2,'  bytes  ','time taken ',gettickcount64-t);    writeln('Press return to exit');  readln;  end. ---------------------------------------------------------------------- rvk · 2022-03-22 19:48 Quote from: BobDog on March 22, 2022, 08:40:15 pmI cannot run rvk's code because I am using Geany ide and  TForm1.Button1Click doesn't go with Geany. My code has nothing to do with Button1Click(). It was just a placeholder where I put the code. You can just extract it for your own use. I made another example with a function. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i uses ComObj; function GetRecycleBinSizeInBytes: Int64;var  ObjShell, ObjFolder: olevariant;  I, Size: integer;begin  Result := 0;  ObjShell := CreateOleObject('Shell.Application');  ObjFolder := ObjShell.NameSpace(olevariant($A)); // 10 = RECYCLE_BIN  for I := 0 to ObjFolder.Items.Count - 1 do    Result := Result + ObjFolder.Items.Item(I).Size;end; procedure YourMainProcedure;begin  Writeln(format('Total Recycle Bin Size in Bytes is %d bytes', [GetRecycleBinSizeInBytes]));  // or  // Memo1.Lines.Add(format('Total Recycle Bin Size in Bytes is %d bytes', [GetRecycleBinSizeInBytes]));  // or something else where you call GetRecycleBinSizeInBytesend; ---------------------------------------------------------------------- BobDog · 2022-03-22 20:40 OK, used that. Results from both yours and mine:  Your result:   Total Recycle Bin Size in Bytes is 172473113 bytes Time taken 49468 My result: 719146331  bytes  time taken 703 719146331  bytes  time taken 2422 Press return to exit My result agrees well with (disk cleanup - recycle bin size) ---------------------------------------------------------------------- rvk · 2022-03-22 20:44 Quote from: BobDog on March 22, 2022, 09:40:18 pmMy result: 719146331  bytes  time taken 703 719146331  bytes  time taken 2422 Do you have deleted folders (because I didn't implement that and a folder is 0 bytes in size in the api). So that probably also needs to be recursed into. ---------------------------------------------------------------------- BobDog · 2022-03-22 21:01 rvk I have some folders in it, I have a right hotchpotch of stuff, I should really empty the whole thing -- some day. ---------------------------------------------------------------------- rvk · 2022-03-23 09:28 Quote from: BobDog on March 22, 2022, 10:01:25 pmI have some folders in it, I have a right hotchpotch of stuff, I should really empty the whole thing -- some day. Ok, small adjustment for subfolders in the recycle bin. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program SizeOfRecycleBin; uses  SysUtils,  ComObj;   function GetRecycleBinSizeInBytes: int64;  var    ObjShell, ObjFolder: olevariant;     function SizeRecurse(Fld: olevariant): int64;    var    I: integer;    begin      Result := 0;      for I := 0 to Fld.Items.Count - 1 do      begin        Result := Result + Fld.Items.Item(I).Size;        if Fld.Items.Item(I).IsFolder then        Result := Result + SizeRecurse(Fld.Items.Item(I).GetFolder);      end;    end;   begin    Result := 0;    ObjShell := CreateOleObject('Shell.Application');    ObjFolder := ObjShell.NameSpace(olevariant($A)); // 10 = RECYCLE_BIN    Result := SizeRecurse(ObjFolder);  end;   procedure MainProcedure;  var    t: int64;  begin    t := gettickcount64;    Writeln(format('Size of Recycle Bin is %.0n bytes', [GetRecycleBinSizeInBytes + 0.0]));    writeln(format('This took %.0n ticks', [gettickcount64 - t + 0.0]));  writeln('Press return to exit');    readln;  end; begin  MainProcedure;end. Result for me: Code: Text  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Size of Recycle Bin is 195.844.203 bytesThis took 17.438 ticksPress return to exit Does anyone know why it's so slow? Are OLE objects inherently slow? But hey, at least it works  (I also don't need this code  ) ---------------------------------------------------------------------- BobDog · 2022-03-23 10:18 Size of Recycle Bin is 811,908,773 bytes This took 155,781 ticks Press return to exit (I need {$mode delphi} to use result) Mine 719146331  bytes  time taken 562 719146331  bytes  time taken 2438 Press return to exit Yours is slightly higher than mine. My second method also loops through all the files (paths), checking if the path actually is a file first and then adding up all the lengths. To get your code working in Geany ide I had to get hold of about ten extra units and put them in my units directory. So your code has a large dependency on external libs. You don't notice this on Lazarus, it runs straight off. ---------------------------------------------------------------------- rvk · 2022-03-23 11:01 Quote from: BobDog on March 23, 2022, 11:18:21 amSize of Recycle Bin is 811,908,773 bytes Mine 719146331  bytes  time taken 562 719146331  bytes  time taken 2438 Are you sure you are also listing hidden files in the recycle bin? The result of my program is bigger than yours. It should be exactly the same. (The dir /s /b doesn't list hidden files by default. Maybe you should use dir /a:h /b /s instead.) ---------------------------------------------------------------------- BobDog · 2022-03-23 11:44 using (in binsize2 only to test)  a:=dir(drive+'\$RECYCLE.BIN','/s /A /b '); I get the hidden files as well, 100 or so more bytes. Thanks for reminding me. ---------------------------------------------------------------------- Josh · 2022-03-23 11:49 hi just some thoughts the issue with cmd is that it is generally turned off in group policy for security reasons on company systems. also I thought windows cmd was being replaced with windows terminal in windows 11, so may not work as expected. again this would probably be disabled for security reasons. ---------------------------------------------------------------------- Thaddy · 2022-03-23 12:21 Quote from: BobDog on March 22, 2022, 08:40:15 pmI cannot run rvk's code because I am using Geany ide and  TForm1.Button1Click doesn't go with Geany. That is nonsense, Geany works perfectly well if your paths are OK. ---------------------------------------------------------------------- BobDog · 2022-03-23 12:33 I set paths to required units, I put all required units in a dedicated folder. In other words my freepascal is run completely via command line instructions, barring of course things like {$mode Delphi} in the source code. So maybe I can do  TForm1.Button1Click, I'll give it a try. Thank you Thaddy. ---------------------------------------------------------------------- Thaddy · 2022-03-23 12:51 If you need instructions to set up Geany for Lazarus code, then plz ask. I will be happy to help you. ---------------------------------------------------------------------- rvk · 2022-03-23 14:49 Quote from: BobDog on March 23, 2022, 11:18:21 am(I need {$mode delphi} to use result) Isn't the default ObjFPC in FPC? There Result should work too. Or are you working with TP mode normally? Orhas Geany ide another default? Quote from: BobDog on March 23, 2022, 12:44:02 pmusing (in binsize2 only to test)  a:=dir(drive+'\$RECYCLE.BIN','/s /A /b '); I get the hidden files as well, 100 or so more bytes. Thanks for reminding me. I take it you meant megabytes? Otherwise there still is a difference. ---------------------------------------------------------------------- BobDog · 2022-03-23 15:09 Just bytes 719193658  bytes  time taken 640 719193787  bytes  time taken 2922 Press return to exit first run omit hidden. second run use all files. Thanks for the offer of Geany help Thaddy. I do have Lazarus in a folder, but I rarely use it. I also use devpas ide sometimes, rarely, pointing to fpc 3.2.0, 64 bits. ---------------------------------------------------------------------- rvk · 2022-03-23 15:19 Quote from: BobDog on March 23, 2022, 04:09:44 pmJust bytes 719193658  bytes  time taken 640 719193787  bytes  time taken 2922 Press return to exit first run omit hidden. second run use all files. Weird. When I get a moment I need to look at why my method returns +800MB for you and the dir method much much less. ---------------------------------------------------------------------- BobDog · 2022-03-23 15:35 719193787/1024/1024 = 685.8766431808472 mb. and my disk clean up says 685 mb. in the recycle bin. ---------------------------------------------------------------------- rvk · 2022-03-23 15:38 Quote from: BobDog on March 23, 2022, 04:35:54 pm719193787/1024/1024 = 685.8766431808472 mb. and my disk clean up says 685 mb. in the recycle bin. Yes, and the ole method gave you 811,908,773 bytes so there must be something wrong with the counting there ---------------------------------------------------------------------- rvk · 2022-03-23 20:41 The $RECYCLE.BIN is even more weird. Mine was probably corrupted because it had files in it which where already purged from the bin and weren't even visible in the recycle bin. And yes, that was for my profile directory. The $RECYCLE.BIN also contains the recycle bin from other users. And you might not have access to it though your own account (only as administrator) with the dir method. Another thing is that for each file that is deleted (it will be renamed to something like $Rxxxx) there is a $Ixxxx file with some extra original file information (where the file was, when it was deleted, etc). That file also takes some space and the OLE method doesn't include those. @BobDog I still find it weird that the OLE method was bigger than your dir method because the dir method should have been larger because of the meta $I files. The only thing I kan think of is that the OLE method lists files on ALL drives and ALL profiles. You dir method only lists files (and $I meta) from the C: drive. Disk cleanup is also "per drive". Not for ALL drives. So maybe you have some deleted files on other volumes (which the OLE method included). Even so... I wouldn't use the exec(dir) method but if I wanted to cycle through all the files I would just use the FindFirst/FindNext files api to go through them. To summarize: The file iteration method is a better indication of the exact bytes (because the $I meta files are included and they take up space) but doesn't automatically take all drives. The OLE method counts real file-size of deleted files over all drives (so not meta) but is very slow with lots of files and less accurate when that count increases. ---------------------------------------------------------------------- BobDog · 2022-03-23 23:28 I only have one drive. But anyway, thanks for your feedback on this, and I have accordingly changed my profile. ---------------------------------------------------------------------- PascalDragon · 2022-03-24 16:19 Quote from: rvk on March 23, 2022, 03:49:41 pmQuote from: BobDog on March 23, 2022, 11:18:21 am(I need {$mode delphi} to use result) Isn't the default ObjFPC in FPC? There Result should work too. Or are you working with TP mode normally? Orhas Geany ide another default? The default mode of FPC itself is mode FPC, not ObjFPC. Lazarus usually overwrites that with its own settings. ---------------------------------------------------------------------- jcmontherock · 2022-03-24 17:27 I am using the following: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i ...TRecord = Record                               // offset   length  Header:   Int64;                               //   0        8  FileSize: Int64;                                 //   8        8  DelDate:  Array[0..7] of Byte;           //  16        8  FileLgth: Integer;                           //  24        4  Filename: Array[0..260] of WChar;  //  28        variableend;...procedure TForm1.GetTrashFileProp(              IFilename: String; Out RFilename: String; Out DelDate: TDateTime; Out iSize: Integer);var  DT: TDateTime;begin  fRecord := ReadFile(IFilename);  RFilename := UTF8Encode(UnicodeString(fRecord.Filename));  iSize := fRecord.FileSize;  DT := IncMilliSecond(encodedate(1601, 1, 1), UInt64(fRecord.DelDate) div 10000 );  DelDate := UniversalTimeToLocal(DT);  iSize   := fRecord.FileSize;End; function TForm1.ReadFile(sInputFilePath: String): TRecord;var  fsInFile: TFileStream;begin  Result := Default(TRecord);  if FileExists(sInputFilePath) then begin    fsInFile := TFileStream.Create(sInputFilePath, fmOpenRead);    fsInFile.Position := 0;    fsInFile.ReadBuffer(Result, fsInFile.Size);    fsInFile.Free;  end  else ShowMessage('Error: cannot open file "' + sInputFilePath + '"');end;  First you have to be sure that the i$ file is a file. Then in GetTrashFileProp, IFilename is the $i file and RFilename is the real deleted file name.