В этой статье мы познакомимся с функциями для поиска файлов на дисках Вашего (и не только 🙂 компьютера. Для тех кто собирается писать вирусы или что-то подобное используя приведенный алгоритм, то предупреждаю: создание вредоносных программ карается по УК РФ!!! Так что думайте сами, а тем кому интересно как же найти файл на диске с помощью Делфьи, то читайте дальше…
Для поиска файлов на диске в Delphi существует две функции, первая из них — это FindFirst, ниже приведено ее описание:
function FindFirst(const Path: string; Attr: Integer; var F: TSearchRec): Integer;
Path — путь, по которому искать файл, включая его имя и расширение (возможно использовать символ *).
attr — атрибуты файла. Может принимать следующие значения:
faReadOnly $00000001 Только чтение
faHidden $00000002 Скрытый
faSysFile $00000004 Системный
faVolumeID $00000008 Метка диска
faDirectory $00000010 Директория
faArchive $00000020 Обычный
faAnyFile $0000003F Любой файл
F- переменная типа TsearchRec, в нее Delphi запихивает все характеристики найденного файла. Описание типа TsearchRec (предлагаю только для того, чтобы было проще освоиться, сам тип уже описан в SysUtils).
type
TSearchRec = record
Time: Integer; // время создания
Size: Integer; //размер файла в байтах
Attr: Integer; // Атрибуты
Name: TFileName; //имя файла
ExcludeAttr: Integer;
FindHandle: THandle; //хандл на файл
FindData: TWin32FindData; //доп. информация о файле
end;
Теперь приведу простой пример использования этой функции. Поставьте на форму одну кнопку TButton, а обработчик события OnClick у нее должен иметь примерно такой вид:
procedure TForm1.Button1Click(Sender: TObject);
var sr:TSearchRec;
begin
findFirst(‘*.exe’,faAnyFile,sr);
edit1.Text:=sr.Name;
end;
Чтобы искать следующий такой же файл, надо написать FindNext (Sr); Если файл найден, то процедуры FindFirst и FindNext возвращают 0 (зеро).
Ну а теперь собственно о том, как можно применить эти функции на практике, то есть опять пример!!! Чтобы разобраться с использованием этих функций попробуем написать программку, которая выдавала список всех программ с расширением *.exe в указанной директории, а затем при нажатии на кнопку включалась бы выбранная программа. На примере я покажу, как найти все .exe файлы в директории Windows, а затем объясню как можно модифицировать программку!
Итак, ставим на форму компонент TListBox в него мы будем выводить список найденных файлов. Обработчик события OnClick для нашей первой кнопки заменяем на такой:
procedure TForm1.Button1Click(Sender: TObject);
var sr:TSearchRec;
Result:word;
begin
ChDir(‘C:windows’);//меняем папку на C:Windows
Result := FindFirst (‘*.exe’,faAnyFile,sr);
ListBox1.Clear;
While result=0 do
Begin
Result:=FindNext (sr);
ListBox1.Items.add(sr.name);
End;
end;
Как видите мы просто организовали цикличный проход по директории C:Windows, который прекращается, как только функции возвращает не ноль! Функция ChDir была использована для смены папки с текущей на папку C:windows
Но приведенный выше способ находит файлы лишь в том каталоге, который задан переменной Path:String. Мне кажется, этого недостаточно для решения большей части поисковых проблем, поэтому стоит написать алгоритм поиска файлов в каждой найденной директории.
У меня расширенная процедура поиска выглядит вот так:
procedure ffind(cat:string); //каталог, откуда начать поиск
var sea:TSearchRec;
res:integer; //результат поиска (0 или нет)
begin
res:=FindFirst(cat+’*.*’,faAnyFile,sea); //ищем первый файл
res:=findNext(sea);//ищем следующий файл
While res=0 do
begin
if (Sea.Attr=faDirectory) and ((Sea.Name=’.’)or(Sea.Name=’..’)) then//чтобы не было файлов . и..
begin
Res:=FindNext(sea);
Continue;//продолжаем цикл
end;
if (Sea.Attr=faDirectory) then//если нашли директорию, то ищем файлы в ней
begin
Ffind(cat+Sea.Name+»);//рекурсивно вызываем нашу процедуру
Res:=FindNext(Sea);//ищем след. файл
Continue;//продолжаем цикл
end;
form1.ListBox1.Items.Add(Sea.Name);//добавляем в Listbox:Tlistbox имя файла
Res:=FindNext(Sea);//ищем след. файл
end;
FindClose(Sea);//освобождаем пересенную поиска
end;
Здесь была использована процедура FindClose(var sea: TsearchRec); она необходима для освобождения поисковой переменной. В следующих примерах ее я использовать не буду, но Вы имейте ее в виду!!!
Возможно, этот алгоритм не самый быстрый и удобный, но он работает.
Для того, чтобы ваше приложение не выглядело подвисшим, можно добавить Application.ProcessMessages в начало нашей процедуры.
Теперь поставьте на форму еще кнопку для того, чтобы по ее нажатии запускать выбранную в ListBox’e программу. Обработчик события Onclick для нашей второй кнопки у меня получился таким:
procedure TForm1.Button2Click(Sender: TObject);
begin
WinExec(pchar(listbox1.Items[listbox1.itemindex]),sw_show);
end;
Поскольку файлы находятся в директории Windows, то при вызове метода WinExec путь к файлам можно не указывать, а если вы используете какую-либо другую директорию, то вызов метода WinExec должен быть примерно таким:
WinExec(pchar(‘C:Путь к вашей папке’+listbox1.Items[listbox1.itemindex]),sw_show);
Ну если вы хотите искать файлы в указанном пользователем каталоге можно использовать компонент DirectoryListBox, который дает доступ к каталогам на вашем компьютере и позволяет менять текущий каталог двойным нажатием мыши. Узнать выбранный каталог можно так:
DirectoryListBox1.Directory
Поэтому в обработчике первой кнопки нужно убрать вызов функции ChDir. А в обработчике второй кнопки вставить приведенную выше конструкцию.
Таким образом приведу полный код приложения, которое получилось у меня с использованием компонента DirectoryListBox
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, FileCtrl;
type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
ListBox1: TListBox;
Button2: TButton;
DirectoryListBox1: TDirectoryListBox;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
var sr:TSearchRec;
Result:word;
begin
Result := FindFirst (‘*.exe’,faAnyFile,sr);
ListBox1.Clear;
While result=0 do
Begin
Result:=FindNext (sr);
ListBox1.Items.add(sr.name);
End;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
WinExec(pchar(DirectoryListBox1.Directory+»+listbox1.Items[listbox1.itemindex]),sw_show);
end;
end.