我试过这段代码:
uses MMSystem;
mciSendString('Set cdaudio door open wait', nil, 0, handle);
mciSendString('Set cdaudio door closed wait', nil, 0, handle);
但没有效果。我听说这不适用于所有系统。
我正试图让驱动器在Windows XP上弹出,并希望通过驱动器号指定驱动器(对于具有多个驱动器的系统是必需的)。
答案 0 :(得分:10)
这是使用 DeviceIOControl() API函数的代码,适用于Windows XP(使用Delphi 5编译和测试):
function DeviceIOControlHelper(ADeviceHandle: THandle;
ADeviceIOControlCode: DWORD): boolean;
var
BytesReturned: Cardinal;
begin
Result := DeviceIOControl(ADeviceHandle, ADeviceIOControlCode,
nil, 0, nil, 0, BytesReturned, nil);
end;
function SetDriveDoorOpen(ADriveLetter: char; AValue: boolean): boolean;
const
FILE_DEVICE_FILE_SYSTEM = 9;
FILE_ANY_ACCESS = 0;
FILE_READ_ACCESS = 1;
METHOD_BUFFERED = 0;
IOCTL_STORAGE_BASE = $2D;
(*
#define CTL_CODE( DeviceType, Function, Method, Access ) ( \
((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
*)
// FSCTL_LOCK_VOLUME = CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 6,
// METHOD_BUFFERED, FILE_ANY_ACCESS);
FSCTL_LOCK_VOLUME = (FILE_DEVICE_FILE_SYSTEM shl 16)
or (FILE_ANY_ACCESS shl 14)
or (6 shl 2) or METHOD_BUFFERED;
// FSCTL_DISMOUNT_VOLUME = CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 8,
// METHOD_BUFFERED, FILE_ANY_ACCESS);
FSCTL_DISMOUNT_VOLUME = (FILE_DEVICE_FILE_SYSTEM shl 16)
or (FILE_ANY_ACCESS shl 14)
or (8 shl 2) or METHOD_BUFFERED;
// IOCTL_STORAGE_EJECT_MEDIA = CTL_CODE(IOCTL_STORAGE_BASE, 0x0202,
// METHOD_BUFFERED, FILE_READ_ACCESS);
IOCTL_STORAGE_EJECT_MEDIA = (IOCTL_STORAGE_BASE shl 16)
or (FILE_READ_ACCESS shl 14)
or ($0202 shl 2) or METHOD_BUFFERED;
// IOCTL_STORAGE_LOAD_MEDIA = CTL_CODE(IOCTL_STORAGE_BASE, 0x0203,
// METHOD_BUFFERED, FILE_READ_ACCESS);
IOCTL_STORAGE_LOAD_MEDIA = (IOCTL_STORAGE_BASE shl 16)
or (FILE_READ_ACCESS shl 14)
or ($0203 shl 2) or METHOD_BUFFERED;
var
DriveCmdStr: string;
DriveHandle: THandle;
begin
Result := FALSE;
DriveCmdStr := Format('\\.\%s:', [ADriveLetter]);
DriveHandle := CreateFile(PChar(DriveCmdStr), GENERIC_READ, FILE_SHARE_WRITE,
nil, OPEN_EXISTING, 0, 0);
if DriveHandle <> INVALID_HANDLE_VALUE then begin
if AValue then begin
Result := DeviceIOControlHelper(DriveHandle, FSCTL_LOCK_VOLUME)
and DeviceIOControlHelper(DriveHandle, FSCTL_DISMOUNT_VOLUME)
and DeviceIOControlHelper(DriveHandle, IOCTL_STORAGE_EJECT_MEDIA);
end else
Result := DeviceIOControlHelper(DriveHandle, IOCTL_STORAGE_LOAD_MEDIA);
CloseHandle(DriveHandle);
end;
end;
忽略错误处理。
答案 1 :(得分:2)
uses ComObj;
function EjectDrive(const ADriveLetter: string): Boolean;
var
WMP: Variant;
CDROMs: Variant;
Drive: Variant;
begin
WMP := CreateOleObject('WMPlayer.OCX.7');
CDROMs := WMP.CDROMCollection;
Drive := CDROMs.GetByDriveSpecifier(ADriveLetter + ':');
Drive.Eject;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
EjectDrive('Q');
end;
编辑:如您所见,我没有编写任何错误处理代码。如果指定了无效的驱动器,此代码将引发异常。