How do I find out how much disk space each user is currently using on a computer?
If you are using disk quotas, then use the Win32_DiskQuota class and retrieve the values of the User and DiskSpaceUsed properties.
const wbemFlagForwardOnly = $00000020; var FSWbemLocator : OLEVariant; FWMIService : OLEVariant; FWbemObjectSet: OLEVariant; FWbemObject : OLEVariant; oEnum : IEnumvariant; iValue : LongWord; begin; FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator'); FWMIService := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', ''); FWbemObjectSet:= FWMIService.ExecQuery('SELECT * FROM Win32_DiskQuota','WQL',wbemFlagForwardOnly); oEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant; while oEnum.Next(1, FWbemObject, iValue) = 0 do begin Writeln(Format('Disk Space Used %d',[Integer(FWbemObject.DiskSpaceUsed)])); Writeln(Format('Quota Volume %s',[String(FWbemObject.QuotaVolume)])); Writeln(Format('User %s',[String(FWbemObject.User)])); Writeln(''); FWbemObject:=Unassigned; end; end;
How do I determine when a removable drive has been added to or removed from a computer?
Use a monitoring code that queries the Win32_VolumeChangeEvent class.
function EventTypeStr(EventType:Integer):string; begin case EventType of 1 : Result:='Configuration Changed'; 2 : Result:='Device Arrival'; 3 : Result:='Device Removal'; 4 : Result:='Docking'; end; end; var FSWbemLocator : OLEVariant; FWMIService : OLEVariant; FWbemObjectSet: OLEVariant; FWbemObject : OLEVariant; begin; Writeln('Press Ctrl-C to terminate'); FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator'); FWMIService := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', ''); FWbemObjectSet:= FWMIService.ExecNotificationQuery('SELECT * FROM Win32_VolumeChangeEvent'); while true do begin FWbemObject := FWbemObjectSet.NextEvent; if not VarIsClear(FWbemObject) then begin Writeln(Format('Drive Name %s',[String(FWbemObject.DriveName)])); Writeln(Format('Event Type %s',[EventTypeStr(FWbemObject.EventType)])); end; Writeln(''); FWbemObject:=Unassigned; end; end;
How do I determine if a CD is in a CD-ROM drive?
Use the Win32_CDROMDrive class and the MediaLoaded property.
const wbemFlagForwardOnly = $00000020; var FSWbemLocator : OLEVariant; FWMIService : OLEVariant; FWbemObjectSet: OLEVariant; FWbemObject : OLEVariant; oEnum : IEnumvariant; iValue : LongWord; begin; FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator'); FWMIService := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', ''); FWbemObjectSet:= FWMIService.ExecQuery('SELECT * FROM Win32_CDROMDrive','WQL',wbemFlagForwardOnly); oEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant; while oEnum.Next(1, FWbemObject, iValue) = 0 do begin Writeln(Format('Device ID %s',[String(FWbemObject.DeviceID)])); Writeln(Format('Media Loaded %s',[String(FWbemObject.MediaLoaded)])); Writeln(''); FWbemObject:=Unassigned; end; end;
How do I distinguish between a fixed hard disk and a removable hard disk?
Use the Win32_LogicalDisk class and check the value of the DriveType property.
Value | Meaning |
---|---|
|
Unknown |
|
No Root Directory |
|
Removable Disk |
|
Local Disk |
|
Network Drive |
|
Compact Disc |
|
RAM Disk |
function DriveTypeStr(DriveType:integer): string; begin case DriveType of 0 : Result:='Unknown'; 1 : Result:='No Root Directory'; 2 : Result:='Removable Disk'; 3 : Result:='Local Disk'; 4 : Result:='Network Drive'; 5 : Result:='CD/DVD Disc'; 6 : Result:='RAM Disk'; end; end; const wbemFlagForwardOnly = $00000020; var FSWbemLocator : OLEVariant; FWMIService : OLEVariant; FWbemObjectSet: OLEVariant; FWbemObject : OLEVariant; oEnum : IEnumvariant; iValue : LongWord; begin; FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator'); FWMIService := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', ''); FWbemObjectSet:= FWMIService.ExecQuery('SELECT * FROM Win32_LogicalDisk','WQL',wbemFlagForwardOnly); oEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant; while oEnum.Next(1, FWbemObject, iValue) = 0 do begin Writeln(Format('Device ID %s',[String(FWbemObject.DeviceID)])); Writeln(Format('DriveType %s',[DriveTypeStr(FWbemObject.DriveType)])); Writeln(''); FWbemObject:=Unassigned; end; end;
How do I determine what file system is in use on a drive?
Use the Win32_LogicalDisk class and the FileSystem property.
const wbemFlagForwardOnly = $00000020; var FSWbemLocator : OLEVariant; FWMIService : OLEVariant; FWbemObjectSet: OLEVariant; FWbemObject : OLEVariant; oEnum : IEnumvariant; iValue : LongWord; begin; FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator'); FWMIService := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', ''); FWbemObjectSet:= FWMIService.ExecQuery('SELECT * FROM Win32_LogicalDisk','WQL',wbemFlagForwardOnly); oEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant; while oEnum.Next(1, FWbemObject, iValue) = 0 do begin Writeln(Format('Device ID %s',[String(FWbemObject.DeviceID)])); if not VarIsNull(FWbemObject.FileSystem) then Writeln(Format('File System %s',[String(FWbemObject.FileSystem)])); Writeln(''); FWbemObject:=Unassigned; end; end;
How do I determine how much free space is available on a drive?
Use the Win32_LogicalDisk class and the FreeSpace property.
const wbemFlagForwardOnly = $00000020; var FSWbemLocator : OLEVariant; FWMIService : OLEVariant; FWbemObjectSet: OLEVariant; FWbemObject : OLEVariant; oEnum : IEnumvariant; iValue : LongWord; begin; FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator'); FWMIService := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', ''); FWbemObjectSet:= FWMIService.ExecQuery('SELECT * FROM Win32_LogicalDisk','WQL',wbemFlagForwardOnly); oEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant; while oEnum.Next(1, FWbemObject, iValue) = 0 do begin Writeln(Format('Device ID %s',[String(FWbemObject.DeviceID)])); if not VarIsNull(FWbemObject.FreeSpace) then Writeln(Format('Free Space %d',[Int64(FWbemObject.FreeSpace)])); Writeln(''); FWbemObject:=Unassigned; end; end;
How do I determine the size of a drive?
Use the Win32_LogicalDisk class, and the Size property.
const wbemFlagForwardOnly = $00000020; var FSWbemLocator : OLEVariant; FWMIService : OLEVariant; FWbemObjectSet: OLEVariant; FWbemObject : OLEVariant; oEnum : IEnumvariant; iValue : LongWord; begin; FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator'); FWMIService := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', ''); FWbemObjectSet:= FWMIService.ExecQuery('SELECT * FROM Win32_LogicalDisk','WQL',wbemFlagForwardOnly); oEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant; while oEnum.Next(1, FWbemObject, iValue) = 0 do begin Writeln(Format('Device ID %s',[String(FWbemObject.DeviceID)])); if not VarIsNull(FWbemObject.Size) then Writeln(Format('Disk Size %d',[Int64(FWbemObject.Size)])); Writeln(''); FWbemObject:=Unassigned; end; end;
How do I find out what drives are mapped on a computer?
Use the Win32_MappedLogicalDisk class.
const wbemFlagForwardOnly = $00000020; var FSWbemLocator : OLEVariant; FWMIService : OLEVariant; FWbemObjectSet: OLEVariant; FWbemObject : OLEVariant; oEnum : IEnumvariant; iValue : LongWord; begin; FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator'); FWMIService := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', ''); FWbemObjectSet:= FWMIService.ExecQuery('SELECT * FROM Win32_MappedLogicalDisk','WQL',wbemFlagForwardOnly); oEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant; while oEnum.Next(1, FWbemObject, iValue) = 0 do begin Writeln(Format('Device ID %s',[String(FWbemObject.DeviceID)])); Writeln(Format('Name %s',[String(FWbemObject.Name)])); Writeln(''); FWbemObject:=Unassigned; end; end;
How do I defragment a hard disk?
Use the Win32_Volume class and the Defrag method.
const wbemFlagForwardOnly = $00000020; var FSWbemLocator : OLEVariant; FWMIService : OLEVariant; FWbemObjectSet: OLEVariant; FWbemObject : OLEVariant; oEnum : IEnumvariant; iValue : LongWord; begin; FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator'); FWMIService := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', ''); FWbemObjectSet:= FWMIService.ExecQuery('SELECT * FROM Win32_Volume Where Name = "F:\\" ','WQL',wbemFlagForwardOnly); oEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant; if oEnum.Next(1, FWbemObject, iValue) = 0 then begin FWbemObject.Defrag(); FWbemObject:=Unassigned; end; end;
How do I detect which drive letter is associated with a logical disk partition?
- Start with the Win32_DiskDrive class and query for instances of Win32_DiskPartition using the DeviceID property and the Win32_DiskDriveToDiskPartition association class. Now you have a collection of the partitions on the physical drive.
- Query for the Win32_LogicalDisk that represents the partition using the Win32_DiskPartition.DeviceID property and Win32_LogicalDiskToPartition association class.
- Get the drive letter from the Win32_LogicalDisk.DeviceID.
const wbemFlagForwardOnly = $00000020; var FSWbemLocator : OLEVariant; FWMIService : OLEVariant; wmiDiskDrives : OLEVariant; wmiDiskPartitions : OLEVariant; wmiLogicalDisks : OLEVariant; wmiDiskDrive : OLEVariant; wmiDiskPartition : OLEVariant; wmiLogicalDisk : OLEVariant; oEnum : IEnumvariant; oEnum2 : IEnumvariant; oEnum3 : IEnumvariant; iValue : LongWord; DeviceID : string; begin; FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator'); FWMIService := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', ''); //Get the physical disk drive wmiDiskDrives := FWMIService.ExecQuery('SELECT Caption, DeviceID FROM Win32_DiskDrive','WQL',wbemFlagForwardOnly); oEnum := IUnknown(wmiDiskDrives._NewEnum) as IEnumVariant; while oEnum.Next(1, wmiDiskDrive, iValue) = 0 do begin //Use the disk drive device id to find associated partition DeviceID:=StringReplace(String(wmiDiskDrive.DeviceID),'\','\\',[rfReplaceAll]); wmiDiskPartitions := FWMIService.ExecQuery('ASSOCIATORS OF {Win32_DiskDrive.DeviceID="'+DeviceID+'"} WHERE AssocClass = Win32_DiskDriveToDiskPartition','WQL',wbemFlagForwardOnly); oEnum2 := IUnknown(wmiDiskPartitions._NewEnum) as IEnumVariant; while oEnum2.Next(1, wmiDiskPartition, iValue) = 0 do begin wmiLogicalDisks := FWMIService.ExecQuery('ASSOCIATORS OF {Win32_DiskPartition.DeviceID="'+String(wmiDiskPartition.DeviceID)+'"} WHERE AssocClass = Win32_LogicalDiskToPartition','WQL',wbemFlagForwardOnly); oEnum3 := IUnknown(wmiLogicalDisks._NewEnum) as IEnumVariant; while oEnum3.Next(1, wmiLogicalDisk, iValue) = 0 do begin Writeln(Format('Drive letter associated with disk drive %s %s Partition %s is %s',[String(wmiDiskDrive.Caption),String(wmiDiskDrive.DeviceID),String(wmiDiskPartition.DeviceID),String(wmiLogicalDisk.DeviceID)])); wmiLogicalDisk:=Unassigned; end; wmiDiskPartition:=Unassigned; end; wmiDiskDrive:=Unassigned; Writeln; end; end;
This post is based in the MSDN entry WMI Tasks: Disks and File Systems
October 25, 2011 at 4:34 pm
How do you specify a drive letter for a FWMIService.ExecQuery rather than selecting * all drives? For example:
October 25, 2011 at 4:46 pm
try this
and use like this
October 25, 2011 at 4:51 pm
Thanks…
October 25, 2011 at 7:17 pm
This function fails because while oEnum.Next( 1, FWbemObject, iValue ) 0.
Why would it not be 0? WMIGetDriveTypei( aDrive ) = 5 returns true but oEnum.Next( 1, FWbemObject, iValue ) 0.
October 25, 2011 at 7:59 pm
In the query against the Win32_CDROMDrive class you must use to compare the Drive property not DeviceID.
So you must write a code like this
Another advice, it seems which you are writting a set of helper functions to retrieve hardware information. If you want improve the performance use a single WMI connection and share that connection between the ExecQuery calls.
October 25, 2011 at 9:48 pm
If i call WMI at system startup period and WMI service is not ready, what will happen? Getting information failed or wait for WMI sevice ready and return ok automaticly?
October 26, 2011 at 8:42 pm
If the WMI service is stopped, the WMI operation will fail.
October 26, 2011 at 12:36 pm
“If you want improve the performance use a single WMI connection and share that connection between the ExecQuery calls.” Is this what you mean:
I have all of your snippets in this unit as functions and procedures. At the moment everything works except two functions… When I finish would you like the demo and unit?
October 26, 2011 at 8:30 pm
Yes something like that, but I prefear use a class with all the logic encapsulated instead of global variables.
October 27, 2011 at 7:35 am
good and nice code!