Pobieranie informacji o napędach systemu
Adam Boduch
Aby zidentyfikować napędy zainstalowane w systemie, konieczne jest użycie funkcji WinAPI. W gruncie rzeczy jest to proste, należy jednak poznać kilka fundamentalnych zasad i poznać sposób użycia funkcji WinAPI.
Podstawową funkcją jest GetDriveType
. Funkcja ta zawiera jeden parametr, a mianowicie literę dysku dla którego chcesz uzyskać informacje.
Funkcja ta zwraca takie oto wartości:
0 - Typ napędu niemożliwy do określenia.
1 - Nie istnieje napęd o podanej literze.
DRIVE_REMOVABLE - Dyskietka lub napęd wymienny
DRIVE_FIXED - Napęd niewymienny
DRIVE_REMOTE - Napęd sieciowy
DRIVE_CDROM - CD - ROM
DRIVE_RMADISK - Ram-dysk - wirtualny dysk.
W tym artykule napiszemy program, który będzie właśnie podawał informacje dotyczące dysku. Na formularzu umieść komponent ListView
- w nim będą zaznaczone dyski. Umieść na formie także komponent ImageList
. Dodaj do niego z dwie ikony symbolizujące odpowiednio: ikonę CD oraz ikonę dysku twardego.
Dobrze przejdźmy do rzeczy najważniejszej, czyli uzyskanie informacji o dyskach. Oto procedura OnCreate
naszego programu:
procedure TMainForm.FormCreate(Sender: TObject);
var
i : Integer; // zmienna potrzebna do wykonania petli
DriveType : Integer; // informacja o typie dysku
ListItem: TListItem;
Bufor:array[0..MAX_PATH] of Char; // zawiera etykiete dysku
MaxCompLength, FileSystemFlags : DWORD;
begin
{ wykonaj petle analizujac kazda litere dysku }
for I := Ord('A') to Ord('Z') do
begin
DriveType := GetDriveType(PChar(Chr(i) + ':\')); // pobierz typ dysku
{ jezeli typ dysku to 0 ( nie mozna okreslic ) lub 1 ( nie istnieje taki dysk ) to pomin w opisie. }
if not (DriveType = 0) and not (DriveType = 1) then
begin
{ uzyskaj informacje dotyczace etykiety dysku }
GetVolumeInformation(PChar(Chr(i) + ':\'), Bufor, SizeOf(Bufor),
nil, MaxCompLength, FileSystemFlags, nil, 0);
ListItem := ListView.Items.Add; // dodaj pozycje
ListItem.Caption := Chr(i) + ':\' + ' ' + Bufor; // ustaw tekst
{ Tutaj w zaleznosci od rodzaju dysku do komponentu ListView do okreslnej
pozycji zostaje przypisana okreslona ikonka symoblizujaca dysk. }
if (DriveType = DRIVE_CDROM) then ListItem.ImageIndex := 0;
if (DriveType = DRIVE_FIXED) then ListItem.ImageIndex := 1;
if (DriveType = DRIVE_REMOVABLE) then ListItem.ImageIndex := -1;
end;
end;
end;
Wiadomo, że dyski mogą być ponumerowane od A do Z. Na początek do zmiennej DriveType zostaje przypisany rezultat wykonania funkcji GetDriveType
. Później następuje sprawdzenie, czy zmienna DriveType nie ma przypadkiem wartości 0 lub 1 co oznaczałoby, że niemożliwe jest określenie dysku - wtedy operacje zostaną pominięte. Jeżeli dysk jest następuje pobranie jego etykiety, a później tworzona jest nowa pozycja w komponencie TListView
. To nie wszystko. Trzeba jeszcze wybrać ikonę. Właściwość ImageIndex
określa numer ikony. Po prostu dobierana jest odpowiednia ikona w zależności od rodzaju dysku. Bardzo ważna rzecz: trzeba we właściwości LargeImages
komponentu ListView
wybrać komponent ImageList1
.
Dobrze, wiesz już jak uzyskać listę dysków znajdujących się w systemie. Teraz coś trudniejszego mianowicie uzyskanie dokładniejszych informacji o samych dyskach, czyli liczba klasterów, sektory przypadający na klaster itp. To wszystko umożliwia nam funkcja GetDiskFreeSpace
. Trzeba w niej podać wszystkie zmienne, które przechowywać będą informacje o właściwościach dysku.
Zadeklarujmy te zmienne:
var
DirName: String; // litera dysku
Sectors: DWORD; // sektory w klasterze
Bytes: DWORD; // bajty w sektorze
FreeClust: DWORD; // wolne klastery
TotalClust: DWORD; // wszystkie klastery
Dobrze. Teraz trzeba jakoś zdobyć literę zaznaczonej pozycji w komponencie. Zrób to w ten sposób:
DirName := ListView.Selected.Caption[1]; // pobierz pierwszy znak napisu - litere dysku
Po prostu uzyskujemy pierwszy znak zaznaczonej pozycji... Na formularzu umieść 4 etykiety tekstowe, które wyświetlały będą te informacje. Teraz samo wywłanie funkcji GetDiskFreeSpace
:
{ Funkcja GetDiskFreeSpace podaje rozne informacje dotyczace danego dysku }
if GetDiskFreeSpace(PChar(DirName + ':\'), Sectors, Bytes, FreeClust, TotalClust) then
begin
{ przypisz dane do etykiet tekstowych }
lblSectors.Caption := 'Sektory w klastrze: ' + IntToStr(Sectors);
lblBytes.Caption := 'Bajty w sektorze: ' + IntToStr(Bytes);
lblFreeClust.Caption := 'Wolne klastry: ' + IntToStr(FreeClust);
lblTotalClust.Caption := 'Wszystkie klastry: ' + IntToStr(TotalClust);
{ jezeli niemozliwe jest odczytanie wlasciwosci przypisz etykieta symbolom znak ???? }
end else
begin
lblSectors.Caption := '???';
lblBytes.Caption := '???';
lblFreeClust.Caption := '???';
lblTotalClust.Caption := '???';
end;
Jeżeli nie jest możliwe określenie danych z dysku to na etykietach przypisany zostaje znak ???.
Oto cały kod programu:
//////////////////////////////////////////////////////////////////
// //
// Unit MainFrm for DrivesInfo //
// Copyright ? 2001 by Adam Boduch //
// Service for programmers: http://programowanie.of.pl //
// E-mail: boduch@poland.com //
// 29.06.2001 r. //
// //
//////////////////////////////////////////////////////////////////
unit MainFrm;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ComCtrls, ImgList, StdCtrls;
type
TMainForm = class(TForm)
ListView: TListView;
ImageList1: TImageList;
lblSectors: TLabel;
lblBytes: TLabel;
lblFreeClust: TLabel;
lblTotalClust: TLabel;
procedure FormCreate(Sender: TObject);
procedure ListViewClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
MainForm: TMainForm;
implementation
{$R *.DFM}
procedure TMainForm.FormCreate(Sender: TObject);
var
i : Integer; // zmienna potrzebna do wykonania petli
DriveType : Integer; // informacja o typie dysku
ListItem: TListItem;
Bufor:array[0..MAX_PATH] of Char; // zawiera etykiete dysku
MaxCompLength, FileSystemFlags : DWORD;
begin
{ wykonaj petle analizujac kazda litere dysku }
for I := Ord('A') to Ord('Z') do
begin
DriveType := GetDriveType(PChar(Chr(i) + ':\')); // pobierz typ dysku
{ jezeli typ dysku to 0 ( nie mozna okreslic ) lub 1 ( nie istnieje taki dysk ) to pomin w opisie. }
if not (DriveType = 0) and not (DriveType = 1) then
begin
{ uzyskaj informacje dotyczace etykiety dysku }
GetVolumeInformation(PChar(Chr(i) + ':\'), Bufor, SizeOf(Bufor),
nil, MaxCompLength, FileSystemFlags, nil, 0);
ListItem := ListView.Items.Add; // dodaj pozycje
ListItem.Caption := Chr(i) + ':\' + ' ' + Bufor; // ustaw tekst
{
Tutaj w zaleznosci od rodzaju dysku do komponentu ListView do okreslnej
pozycji zostaje przypisana okreslona ikonka symoblizujaca dysk.
}
if (DriveType = DRIVE_CDROM) then ListItem.ImageIndex := 0;
if (DriveType = DRIVE_FIXED) then ListItem.ImageIndex := 1;
if (DriveType = DRIVE_REMOVABLE) then ListItem.ImageIndex := -1;
end;
end;
end;
procedure TMainForm.ListViewClick(Sender: TObject);
var
DirName: String; // litera dysku
Sectors: DWORD; // sektory w klastru
Bytes: DWORD; // bajty w sektorze
FreeClust: DWORD; // wolne klastery
TotalClust: DWORD; // wszystkie klastery
begin
DirName := ListView.Selected.Caption[1]; // pobierz pierwszy znak napisu - litere dysku
{ Funkcja GetDiskFreeSpace podaje rozne informacje dotyczace danego dysku }
if GetDiskFreeSpace(PChar(DirName + ':\'), Sectors, Bytes, FreeClust, TotalClust) then
begin
{ przypisz dane do etykiet tekstowych }
lblSectors.Caption := 'Sektory w klastrze: ' + IntToStr(Sectors);
lblBytes.Caption := 'Bajty w sektorze: ' + IntToStr(Bytes);
lblFreeClust.Caption := 'Wolne klastry: ' + IntToStr(FreeClust);
lblTotalClust.Caption := 'Wszystkie klastry: ' + IntToStr(TotalClust);
{ jezeli niemozliwe jest odczytanie wlasciwosci przypisz etykieta symbolom znak ???? }
end else
begin
lblSectors.Caption := '???';
lblBytes.Caption := '???';
lblFreeClust.Caption := '???';
lblTotalClust.Caption := '???';
end;
end;
end.
Przydatną może także być funkcja DiskSize, która podaje pojemność dysku oraz DiskFree, która podaje ilość wolnego miejsca na dysku. Funkcje te zwracają rezultat w postaci zmiennej typu Int64. Jako parametr tych funkcji trzeba podać numer dysku. Dysk opatrzony literą A ma numer 1; dysk B - numer 2 itd. Czyli np:
WolneMiejsce.Caption := IntToStr(DiskFree(3)); // wolne miejsce na dysku C:
hahaha, nagrywarka CD Read_Only Memory ;]
Ale po czym można odróżnić napęd CD-ROM od nagrywarki CD-ROM
poczym poznać nagrywarke CD-ROM
Bardzo dobry artykuł. Ale czy można odróżnić napęd CD-ROM od nagrywarki CD-ROM lub DVD
tego potrzebowałem, dzięki!