В этой статье мы познакомимся с функциями для поиска файлов на дисках Вашего (и не только компьютера. Для тех кто собирается писать вирусы или что-то подобное используя приведенный алгоритм, то предупреждаю: создание вредоносных программ карается по УК РФ!!! Так что думайте сами, а тем кому интересно как же найти файл на диске с помощью Делфьи, то читайте дальше...
Для поиска файлов на диске в Delphi существует две функции, первая из них - это FindFirst, ниже приведено ее описание:
function FindFirst(const Path: string; Attr: Integer; var F: TSearchRec): Integer;
Path - путь, по которому искать файл, включая его имя и расширение (возможно использовать символ *).
attr - атрибуты файла. Может принимать следующие значения:
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
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;