FAQ VCL
Файлы и файловая система

:: Меню ::
:: На главную ::
:: FAQ ::
:: Заметки ::
:: Практика ::
:: Win API ::
:: Проекты ::
:: Скачать ::
:: Секреты ::
:: Ссылки ::

:: Сервис ::
:: Написать ::

:: MVP ::

:: RSS ::

Яндекс.Метрика

Как узнать версию программы?

// Способ первый
// Данная функция универсальна, она позволяет
// узнать не только версию программы, но и 
// другие данные

const
  TypeInfo: array[0..9] of string = ( 'CompanyName',
                                      'FileDescription',
                                      'FileVersion',
                                      'InternalName',
                                      'LegalCopyright',
                                      'LegalTrademarks',
                                      'OriginalFilename',
                                      'ProductName',
                                      'ProductVersion',
                                      'Comments' );

function FileVersion( AFileName, Info: string ): string;
var
  szName: array[0..255] of Char; 
  P: Pointer; 
  Value: Pointer; 
  Len: UINT;
  GetTranslationString: string;
  FFileName: PChar; 
  FValid: boolean;
  FSize: DWORD; 
  FHandle: DWORD; 
  FBuffer: PChar; 
begin 
   try
      FFileName := StrPCopy( StrAlloc( Length( AFileName ) + 1 ), AFileName );
      FValid := False;
      FSize := GetFileVersionInfoSize( FFileName, FHandle );
      if FSize > 0 then
      try
         GetMem( FBuffer, FSize );
         FValid := GetFileVersionInfo( FFileName, FHandle, FSize, FBuffer );
      except
         FValid := False;
         raise;
      end;
      Result := '';
      if FValid then
         VerQueryValue( FBuffer, '\VarFileInfo\Translation', P, Len )
      else
         P := nil;
      if P <> nil then
         GetTranslationString := IntToHex( MakeLong( HiWord( Longint( P^ ) ),
                                           LoWord( Longint( P^ ) ) ), 8 );
      if FValid then
      begin
         StrPCopy( szName, '\StringFileInfo\' + GetTranslationString + '\' + Info );
         if VerQueryValue( FBuffer, szName, Value, Len ) then
            Result := StrPas( PChar( Value ) );
      end;
   finally
      if FBuffer <> nil then
         FreeMem( FBuffer, FSize );
      StrDispose( FFileName );
   end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
   ShowMessage( FileVersion( ParamStr( 0 ), TypeInfo[2] ) );
end;

// Способ второй
function GetFileVersion(const FileName: string): string;
type
  PDWORD = ^DWORD;
  PLangAndCodePage = ^TLangAndCodePage;
  TLangAndCodePage = packed record
    wLanguage: WORD;
    wCodePage: WORD;
  end;
  PLangAndCodePageArray = ^TLangAndCodePageArray;
  TLangAndCodePageArray = array[0..0] of TLangAndCodePage;
var
  loc_InfoBufSize: DWORD;
  loc_InfoBuf: PChar;
  loc_VerBufSize: DWORD;
  loc_VerBuf: PChar;
  cbTranslate: DWORD;
  lpTranslate: PDWORD;
  i: DWORD;
begin
   Result := '';
   if ( Length( FileName ) = 0 ) or ( not FileExists( FileName ) ) then
      Exit;
   loc_InfoBufSize := GetFileVersionInfoSize( PChar( FileName ), loc_InfoBufSize );
   if loc_InfoBufSize > 0 then
   begin
      loc_VerBuf := nil;
      loc_InfoBuf := AllocMem( loc_InfoBufSize );
      try
         if not GetFileVersionInfo( PChar( FileName ), 0, loc_InfoBufSize, loc_InfoBuf ) then
            Exit;
         if not VerQueryValue( loc_InfoBuf, '\\VarFileInfo\\Translation',
                               Pointer( lpTranslate ), DWORD( cbTranslate ) ) then
            Exit;
         for i := 0 to ( cbTranslate div SizeOf( TLangAndCodePage ) ) - 1 do
         begin
            if VerQueryValue( loc_InfoBuf,
                              PChar( Format( 'StringFileInfo\0%x0%x\FileVersion',
                                             [PLangAndCodePageArray(lpTranslate)[i].wLanguage,
                                              PLangAndCodePageArray(lpTranslate)[i].wCodePage] ) ),
                              Pointer( loc_VerBuf ),
                              DWORD( loc_VerBufSize ) ) then
            begin
               Result := loc_VerBuf;
               Break;
            end;
         end;
      finally
         FreeMem( loc_InfoBuf, loc_InfoBufSize );
      end;
   end;
end;

// Способ третий
procedure GetFileVersion( FileName: string; var Major1, Major2,
  Minor1, Minor2: Integer );
var
  Info: Pointer;
  InfoSize: DWORD;
  FileInfo: PVSFixedFileInfo;
  FileInfoSize: DWORD;
  Tmp: DWORD;
begin
   InfoSize := GetFileVersionInfoSize( PChar( FileName ), Tmp );

   if InfoSize <> 0 then
   begin
      GetMem( Info, InfoSize );
      try
         GetFileVersionInfo( PChar( FileName ), 0, InfoSize, Info );
         VerQueryValue( Info, '\', Pointer( FileInfo ), FileInfoSize );
         Major1 := FileInfo.dwFileVersionMS shr 16;
         Major2 := FileInfo.dwFileVersionMS and $FFFF;
         Minor1 := FileInfo.dwFileVersionLS shr 16;
         Minor2 := FileInfo.dwFileVersionLS and $FFFF;
      finally
         FreeMem( Info, FileInfoSize );
      end;
   end;
end;

// Несколько расширенный вариант третьего способа
function GetFileVersion( FileName: string; var Major1, Major2,
  Minor1, Minor2: Integer ): string;
var
  pInfo,pPointer: Pointer;
  nSize: DWORD;
  nHandle: DWORD;
  pVerInfo: PVSFIXEDFILEINFO;
  nVerInfoSize: DWORD;
begin
   Result := '?.?.?.?';
   Major1 := -1;
   Major2 := -1;
   Minor1 := -1;
   Minor2 := -1;

   nSize:=GetFileVersionInfoSize( PChar( FileName ), nHandle );
   if ( nSize <> 0 ) then
   begin
      GetMem( pInfo,nSize );
      try
         FillChar( pInfo^, nSize, 0 );

         if ( GetFileVersionInfo( PChar( FileName ), nHandle, nSize, pInfo ) ) then
         begin
            nVerInfoSize := SizeOf( VS_FIXEDFILEINFO );
            GetMem( pVerInfo, nVerInfoSize );
            try
               FillChar( pVerInfo^, nVerInfoSize, 0 );
               pPointer := Pointer( pVerInfo );
               VerQueryValue( pInfo, '\', pPointer, nVerInfoSize );
               Major1 := PVSFIXEDFILEINFO( pPointer )^.dwFileVersionMS shr 16;
               Major2 := PVSFIXEDFILEINFO( pPointer )^.dwFileVersionMS and $FFFF;
               Minor1 := PVSFIXEDFILEINFO( pPointer )^.dwFileVersionLS shr 16;
               Minor2 := PVSFIXEDFILEINFO( pPointer )^.dwFileVersionLS and $FFFF;

               Result := IntToStr( Major1 )+ '.' + IntToStr( Major2 ) + '.' +
                         IntToStr( Minor1 )+ '.' + IntToStr( Minor2 );
            finally
               FreeMem( pVerInfo, nVerInfoSize );
            end;
         end;
      finally
         FreeMem( pInfo, nSize );
      end;
   end;
end;


Как определить тип приложения?

// Способ первый
// подходит только для exe
function GetEXEType(FileName: string): string;
var
  BinaryType: DWORD;
begin
   if GetBinaryType(PChar(FileName), Binarytype) then
      case BinaryType of
         SCS_32BIT_BINARY: Result := 'Win32 executable';       // 32-bit Windows-based
         SCS_WOW_BINARY: Result := 'Win16 executable';         // 16-bit Windows-based
         SCS_DOS_BINARY: Result := 'DOS executable';           // MS-DOS – based
         SCS_PIF_BINARY: Result := 'PIF file';                 // PIF for MS-DOS – based
         SCS_POSIX_BINARY: Result := 'POSIX executable';       // POSIX – based
         SCS_OS216_BINARY: Result := 'OS/2 16 bit executable'; // 16bit-OS/2
         SCS_64BIT_BINARY: Result := 'Win64 executable';       // 64-bit Windows-based
         else
            Result := 'Unknown executable';                    // Wrong Binary File
      end
   else
      Result := 'File is not an executable';
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
   ShowMessage(GetEXEType('c:\Some.exe'));
end;

// Способ второй
// подходит как для exe, так и для dll
type
  TMachineType = (mtUnknown, mt32Bit, mt64Bit, mtOther);

function GetLibMachineType(const AFileName: string): TMachineType;
var
  oFS: TFileStream;
  iPeOffset: Integer;
  iPeHead: LongWord;
  iMachineType: Word;
begin
   Result := mtUnknown;
   // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/pecoff_v8.doc
   // Offset to PE header is always at 0x3C.
   // PE header starts with "PE\0\0" = 0x50 0x45 0x00 0x00,
   // followed by 2-byte machine type field (see document above for enum).
   try
      oFS := TFileStream.Create(AFileName, fmOpenRead or fmShareDenyNone);
      try
         oFS.Seek($3C, soFromBeginning);
         oFS.Read(iPeOffset, SizeOf(iPeOffset));
         oFS.Seek(iPeOffset, soFromBeginning);
         oFS.Read(iPeHead, SizeOf(iPeHead));
         // "PE\0\0", little-endian then
         if iPeHead <> $00004550 then
            Exit;
         oFS.Read(iMachineType, SizeOf(iMachineType));
         case iMachineType of
         $8664, // AMD64
         $0200: // IA64
            Result := mt64Bit;
         $014C: // I386
            Result := mt32Bit;
         else
            Result := mtOther;
         end;
      finally
         oFS.Free;
      end;
   except
      // none
   end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
   case GetLibMachineType('c:\Program Files\PLSQL Developer 12\PlugIns\plsqldoc.dll') of
      mt32Bit: ShowMessage('x32');
      mt64Bit: ShowMessage('x64');
      else
         ShowMessage('не удалось определить');
   end;
end;


Как отобразить свойства файла?

uses
  {...,} ShellAPI;

procedure TForm1.ShowFileProperties(const FileName: string);
var
  ShellExecuteInfo: TShellExecuteInfo;
begin
   // Инициализация структуры TShellExecuteInfo
   FillChar( ShellExecuteInfo, SizeOf( TShellExecuteInfo ), 0 );
   // Заполнение структуры TShellExecuteInfo
   ShellExecuteInfo.cbSize := SizeOf( TShellExecuteInfo );
   ShellExecuteInfo.lpFile := PChar( FileName );
   ShellExecuteInfo.lpVerb := 'properties';
   ShellExecuteInfo.fMask := SEE_MASK_INVOKEIDLIST;
   // Отображение свойств файла
   ShellExecuteEx( @ShellExecuteInfo );
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
   ShowFileProperties( 'c:\autoexec.bat' );
end;

// Или немного иначе
uses
  {...,} ShellAPI;

procedure TForm1.ShowPropertiesDialog(FName: string);
var
  SExInfo: TSHELLEXECUTEINFO;
begin
   ZeroMemory( Addr( SExInfo ), SizeOf( SExInfo ) );
   SExInfo.cbSize := SizeOf( SExInfo );
   SExInfo.lpFile := PChar( FName );
   SExInfo.lpVerb := 'properties';
   SExInfo.fMask := SEE_MASK_INVOKEIDLIST;
   ShellExecuteEx( Addr( SExInfo ) );
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
   ShowPropertiesDialog( 'c:\autoexec.bat' );
end;


Как определить время последнего доступа к файлу?

// Способ первый
procedure TForm1.Button1Click(Sender: TObject);
var 
  SearchRec: TSearchRec;
  Success: integer;
  DT: TFileTime;
  ST: TSystemTime;
begin
   Success := SysUtils.FindFirst( 'C:\autoexec.bat', faAnyFile, SearchRec );
   if ( Success = 0 ) and
      ( ( SearchRec.FindData.ftLastAccessTime.dwLowDateTime <> 0 ) or
      ( SearchRec.FindData.ftLastAccessTime.dwHighDateTime <> 0 ) )
   then
   begin
      FileTimeToLocalFileTime( SearchRec.FindData.ftLastAccessTime, DT );
      FileTimeToSystemTime( DT, ST );
      Memo1.Lines.Clear;
      Memo1.Lines.Add( 'AutoExec.Bat последний раз был изменен:' );
      Memo1.Lines.Add( 'Year - ' + IntToStr( st.wYear ) );
      Memo1.Lines.Add( 'Month - ' + IntToStr( st.wMonth ) );
      Memo1.Lines.Add( 'DayOfWeek - ' + IntToStr( st.wDayOfWeek ) );
      Memo1.Lines.Add( 'Day - ' + IntToStr( st.wDay ) );
      Memo1.Lines.Add( 'Hour - ' + IntToStr( st.wHour ) );
      Memo1.Lines.Add( 'Minute - ' + IntToStr( st.wMinute ) );
      Memo1.Lines.Add( 'Second - ' + IntToStr( st.wSecond ) );
      Memo1.Lines.Add( 'Milliseconds - ' + IntToStr( st.wMilliseconds ) );
   end;
   SysUtils.FindClose( SearchRec );
end;

// Способ второй
function GetFileDate( FileName: string ): string;
var
  FHandle: Integer;
begin
   FHandle := FileOpen( FileName, 0 );
   try
      Result := DateTimeToStr( FileDateToDateTime( FileGetDate( FHandle ) ) );
   finally
      FileClose( FHandle );
   end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
   ShowMessage( GetFileDate( 'c:\autoexec.bat' ) );
end;

// Способ третий
procedure TForm1.Button1Click(Sender: TObject);
begin
   ShowMessage( DateTimeToStr( FileDateToDateTime( FileAge( 'c:\autoexec.bat' ) ) ) );
end;


Как удалить каталог вместе со всем содержимым?

// Способ первый
function TForm1.DeleteDir(Dir: string): boolean;
var
  isFound: boolean;
  sRec: TSearchRec;
begin
   Result := false;
   ChDir( Dir );
   if IOResult <> 0 then
   begin
      ShowMessage( 'Не могу войти в каталог: ' + Dir );
      Exit;
   end;
   isFound := FindFirst( '*.*', faAnyFile, sRec ) = 0;
   while isFound do
   begin
      if ( sRec.Name <> '.' ) and ( sRec.Name <> '..' ) then
         if ( sRec.Attr and faDirectory ) = faDirectory then
         begin
            if not DeleteDir( sRec.Name ) then
               Exit;
         end
         else
            if not DeleteFile( sRec.Name ) then
            begin
               ShowMessage( 'Не могу удалить файл: ' + sRec.Name );
               Exit;
            end;
      isFound := FindNext( sRec ) = 0;
   end;
   FindClose( sRec );
   ChDir( '..' );
   RmDir( Dir );
   Result := IOResult = 0;
end;

// Способ второй
function ClearDir( Dir: string ): Boolean;
var
  isFound: boolean;
  sRec: TSearchRec;
begin
   Result := false;
   ChDir( Dir );
   if IOResult <> 0 then
   begin
      ShowMessage( 'Не могу войти в каталог: ' + Dir );
      Exit;
   end;
   if Dir[Length(Dir)] <> '\' then Dir := Dir + '\';
   isFound := FindFirst( Dir + '*.*', faAnyFile, sRec ) = 0;
   while isFound do
   begin
   if ( sRec.Name <> '.' ) and ( sRec.Name <> '..' ) then
      if ( sRec.Attr and faDirectory ) = faDirectory then
      begin
         if not ClearDir( Dir + sRec.Name ) then
            Exit;
         if ( sRec.Name <> '.' ) and ( sRec.Name <> '..' ) then
            if ( Dir + sRec.Name ) <> Dir then
            begin
               ChDir( '..' );
               RmDir( Dir + sRec.Name );
            end;
      end
      else
         if not DeleteFile( Dir + sRec.Name ) then
         begin
            ShowMessage( 'Не могу удалить файл: ' + sRec.Name );
            Exit;
         end;
      isFound := FindNext( sRec ) = 0;
   end;
   FindClose( sRec );
   Result := IOResult = 0;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
   ClearDir( 'C:\Windows\Temp' );
end;

// Способ третий
// Файлы удаляются в корзину
uses
  {...,} ShellAPI;

procedure TForm1.Button1Click(Sender: TObject);
var
  SH: SHFILEOPSTRUCT; // TSHFileOpStruct
  Error: Integer;
begin
   // ZeroMemory( @SH, SizeOf( SH ) );
   with SH do
   begin
      Wnd := Handle;
      wFunc := FO_DELETE;
      pFrom := 'c:\dir_name' + #0;
      pTo := nil;
      fFlags := FOF_ALLOWUNDO or FOF_NOCONFIRMATION or FOF_NOERRORUI or FOF_SILENT;
      fAnyOperationsAborted := False;
      hNameMappings := nil;
      lpszProgressTitle := nil;
   end;
   Error := SHFileOperation( SH );
   if Error <> NO_ERROR then
      ShowMessage( SysErrorMessage( Error ) );
end;


Как определить размер каталога?

var
  Form1: TForm1;
  tSize: int64;

procedure TForm1.GetTotalSize( Path: string; var TotalSize: int64 );
var
  sRec: TSearchRec;
  isFound: boolean;
begin
   isFound := FindFirst( Path + '\*.*', faAnyFile, sRec ) = 0;
   while isFound do
   begin
      if ( sRec.Name <> '.' ) and ( sRec.Name <> '..' ) then
      begin
         if ( sRec.Attr and faDirectory ) = faDirectory then
            GetTotalSize( Path + '\' + sRec.Name, TotalSize );
         TotalSize := TotalSize + sRec.Size;
      end;
      isFound := FindNext( sRec ) = 0;
   end;
   FindClose( sRec );
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
   tSize := 0;
   GetTotalSize( 'C:\WINNT', tSize );
   ShowMessage( IntToStr( tSize ) );
end;


Как скопировать каталог вместе со всем содержимым?

// Способ первый
procedure TForm1.CopyFiles(FromCopy, ToCopy: string);
  procedure FCopy( Path: string );
  var
    sRec: TSearchRec;
    isFound: boolean;
    tempPath: string;
  begin
     if not DirectoryExists( ToCopy ) then CreateDir( ToCopy );
     tempPath := ToCopy;
     isFound := FindFirst( Path + '\*.*', faAnyFile, sRec ) = 0;
     while isFound do
     begin
        if ( ( sRec.Name <> '.' ) and ( sRec.Name <> '..' ) ) and
           ( ( sRec.Attr and faDirectory ) = faDirectory ) then
           begin
              tempPath := Path + '\' + sRec.Name;
              Delete( tempPath, 1, Length( FromCopy ) );
              tempPath := ToCopy + tempPath;
              if not DirectoryExists( tempPath ) then
                 CreateDir( tempPath );
              FCopy( Path + '\' + sRec.Name );
              Application.ProcessMessages;
           end
           else
           begin
              tempPath := Path + '\' + sRec.Name;
              Delete( tempPath, 1, Length( FromCopy ) );
              tempPath := ToCopy + tempPath;
              CopyFile( PChar( Path + '\' + sRec.Name ),
                        PChar( tempPath ), false );
              ProgressBar1.Position := ProgressBar1.Position + sRec.Size;
              Application.ProcessMessages;
           end;
           isFound := FindNext( sRec ) = 0;
        Application.ProcessMessages;
     end;
     FindClose( sRec );
  end;
begin
   FCopy( FromCopy );
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
   CopyFiles( 'c:\откуда', 'd:\куда' );
end;

// Способ второй
uses
  {...,} ShellAPI;

function CopyDir( const fromDir, toDir: string ): boolean;
var
  fos: TSHFileOpStruct;
begin
   ZeroMemory( @fos, SizeOf( fos ) );
   with fos do
   begin
      wFunc := FO_COPY;
      fFlags := FOF_FILESONLY;
      pFrom := PChar( fromDir + #0 );
      pTo := PChar( toDir )
   end;
   Result := ( 0 = ShFileOperation( fos ) );
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  i: integer;
  List: TStringList;
begin
   List := TStringList.Create;
   List.Add( 'Путь к каталогу, который нужно скопировать' );
   for i := 0 to List.Count-1 do
      if CopyDir( List.Strings[i], 'C:\' ) then
         ShowMessage( 'файлы скопированы' );
   List.Free;
end;


Как открыть диалог "Open With...", если открываемый файл ни с чем не ассоциирован?

uses
  {...,} ShellAPI;

procedure OpenFileAs( Path: string );
var
  Err: integer;
begin
    Err := ShellExecute( Application.Handle, 'open', PChar( Path ), nil, nil, SW_SHOW );
    if ( Err = SE_ERR_NOASSOC ) or ( Err = SE_ERR_ASSOCINCOMPLETE ) then
    begin
       Path := 'shell32.dll,OpenAs_RunDLL ' + Path;
       ShellExecute( Application.Handle, 'open', 'Rundll32.exe', PChar( Path ), nil, SW_SHOW );
   end;
end;


Как вычислить CRC (контрольную сумму) для файла?

// Способ первый
uses
  ImageHlp;

procedure ComputeChecksum;
var
  M: TMemoryStream;
  I, C: Integer;
begin
  M := TMemoryStream.Create;
  try
    M.LoadFromFile('C:\calc.exe');
    CheckSumMappedFile(M.Memory, M.Size, @I, @C);
    ShowMessageFmt('%x', [C]);
  finally
    M.Free;
  end;
end;

// Способ второй
uses
  ImageHlp;

//function ComputeChecksum(const AFile: string; out AResult: DWORD): Boolean;
//var
//  h, hfm: THandle;
//  pv: Pointer;
//  dwHeaderSum: DWORD;
//begin
//  h := CreateFile(PChar(AFile), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
//  hfm := CreateFileMapping(h, 0, PAGE_READONLY, 0, 0, 0);
//  pv := MapViewOfFile(hfm, FILE_MAP_READ, 0, 0, 0);
//  CheckSumMappedFile(pv, GetFileSize(h, nil), @dwHeaderSum, @AResult);
//  UnmapViewOfFile(pv);
//  CloseHandle(hfm);
//  CloseHandle(h);
//  Result := True;
//end;

function ComputeChecksum(const AFile: String; out AResult: DWORD): Boolean;
var
  h, hfm: THandle;
  pv: Pointer;
  dwHeaderSum: DWORD;
begin
  Result := False;
  h := CreateFile(PChar(AFile), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  if h <> INVALID_HANDLE_VALUE then
  begin
    hfm := CreateFileMapping(h, 0, PAGE_READONLY, 0, 0, 0);
    if hfm > 0 then
    begin
      pv := MapViewOfFile(hfm, FILE_MAP_READ, 0, 0, 0);
      if Assigned(pv) then
      begin
        if CheckSumMappedFile(pv, GetFileSize(h, nil), @dwHeaderSum, @AResult) <> nil then
          Result := True;
        UnmapViewOfFile(pv);
      end;
      CloseHandle(hfm);
    end;
    CloseHandle(h);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  crc: Cardinal;
begin
  ComputeChecksum('c:\calc.exe', crc);
  ShowMessageFmt('%x', [crc]);
end;

// Способ третий
function GetCheckSum(FileName: string): DWORD;  
var
  F: file of DWORD;  
  P: Pointer;  
  Fsize: DWORD;  
  Buffer: array[0..500] of DWORD;
begin
  FileMode := 0;
  AssignFile(F, FileName);
  Reset(F);
  Seek(F, FileSize(F) div 2);
  Fsize := FileSize(F) - 1 - FilePos(F);
  if Fsize > 500 then Fsize := 500;
  BlockRead(F, Buffer, Fsize);
  Close(F);
  P := @Buffer;
  asm
    xor eax, eax
    xor ecx, ecx
    mov edi , p
    @again:
    add eax, [edi + 4*ecx]
    inc ecx
    cmp ecx, fsize
    jl @again
    mov @result, eax
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  ShowMessage(IntToStr(GetCheckSum('c:\SetupDemoDB.exe')));
end;


Как получить атрибуты файла?

function GetAttribut( Path: string ): string;
var
  Atr: Integer;
begin
   Result := '----';
   Atr := FileGetAttr( Path );
   if ( Atr and faReadOnly ) = faReadOnly then
      Result[1] := 'r';
   if ( Atr and faHidden ) = faHidden then
      Result[2] := 'h';
   if ( Atr and faSysFile ) = faSysFile then
      Result[3] := 's';
   if ( Atr and faArchive ) = faArchive then
      Result[4] := 'a';
end;

При использовании материала - ссылка на сайт обязательна