Delphi:如何使用驱动器号以编程方式弹出CD

Art*_*hur 2 windows delphi

我试过这段代码:

uses MMSystem;

mciSendString('Set cdaudio door open wait', nil, 0, handle);

mciSendString('Set cdaudio door closed wait', nil, 0, handle);
Run Code Online (Sandbox Code Playgroud)

但是没有效果.我听说这不适用于所有系统.

我正试图让驱动器在Windows XP上弹出,并希望通过驱动器号指定驱动器(对于具有多个驱动器的系统是必需的).

mgh*_*hie 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;
Run Code Online (Sandbox Code Playgroud)

错误处理省略.