winapi - Windows CDROM Udstødning

Indlæg af Hanne Mølgaard Plasc

Problem



Er der nogen der kender en metode til at lukke cd-skuffen programmatisk i Windows 2000 eller nyere?
Åbn cd-skuffen eksisterer, men jeg kan ikke synes at gøre det tæt, især under W2k.


Jeg leder især efter en metode til at gøre dette fra en batch-fil, hvis det er muligt, men API-opkald ville være OK.

Bedste reference


Her er en nem måde at bruge Win32 API:



[DllImport("winmm.dll", EntryPoint = "mciSendStringA", CharSet = CharSet.Ansi)]
        protected static extern int mciSendString(string lpstrCommand,StringBuilder lpstrReturnString,int uReturnLength,IntPtr hwndCallback);

 public void OpenCloseCD(bool Open)
 {
    if (Open)
    {
        mciSendString("set cdaudio door open", null, 0, IntPtr.Zero);
    }
    else
    {
        mciSendString("set cdaudio door closed", null, 0, IntPtr.Zero);
    }
}


Andre referencer 1


Jeg kan godt lide at bruge DeviceIOControl, da det giver mig mulighed for at skubbe enhver form for flytbart drev (som f.eks. USB- og flashdiske samt cd-bakker). Da codez til korrekt udstødning en disk ved hjælp af DeviceIOControl er (tilføj kun korrekt fejlhåndtering):


bool ejectDisk(TCHAR driveLetter)
{
  TCHAR tmp[10];
  \_stprintf(tmp, \_T("\\.\\%c:"), driveLetter);
  HANDLE handle = CreateFile(tmp, GENERIC\_READ, FILE\_SHARE\_WRITE, 0, OPEN\_EXISTING, 0, 0);
  DWORD bytes = 0;
  DeviceIoControl(handle, FSCTL\_LOCK\_VOLUME, 0, 0, 0, 0, &bytes, 0);
  DeviceIoControl(handle, FSCTL\_DISMOUNT\_VOLUME, 0, 0, 0, 0, &bytes, 0);
  DeviceIoControl(handle, IOCTL\_STORAGE\_EJECT\_MEDIA, 0, 0, 0, 0, &bytes, 0);
  CloseHandle(handle);
  return true;
}

Andre referencer 2


Jeg bemærkede, at Andreas Magnussons svar ikke virkede helt nøjagtigt det samme som Explorer 's Eject-knappen gjorde. Specifikt blev drevet ikke udgravet i Explorer ved hjælp af Andreas-kode, men hvis du brugte kommandoen Eject. Jeg gjorde nogle undersøgelser.


Jeg kørte API Monitor mens du kører Eject-kommandoen fra Explorer (Windows 7 SP1 64-bit). Jeg fandt også en god MSKB artikel 165721 med titlen How to Ejecting Removable Media i Windows NT/Windows 2000/Windows XP. Den mest interessante del af MSKB artiklen er citeret nedenfor: [15]



  

      
  1. Ring til Opret fil med GENERIC\_READ | GENERIC\_WRITE, FILE\_SHARE\_READ | FILE\_SHARE\_WRITE og OPEN\_EXISTING. Parameteren lpFileName skal være \. \ X: (hvor X er det ægte drevbogstav). Alle andre parametre kan være nul.

  2.   
  3. Lås lydstyrken ved at udstede FSCTL\_LOCK\_VOLUME IOCTL via DeviceIoControl. Hvis en anden applikation eller systemet bruger lydstyrken, fejler denne IOCTL. Når denne funktion vender tilbage, er programmet garanteret, at lydstyrken ikke bruges af noget andet i systemet.

  4.   
  5. Afbryd lydstyrken ved at udstede FSCTL\_DISMOUNT\_VOLUME IOCTL. Dette medfører, at filsystemet fjerner al viden om lydstyrken og bortfalder interne oplysninger, som den holder med hensyn til lydstyrken.

  6.   
  7. Sørg for, at mediet kan fjernes ved at udstede IOCTL\_STORAGE\_MEDIA\_REMOVAL IOCTL. Indstil PreventMediaRemoval-medlemmet af PREVENT\_MEDIA\_REMOVAL strukturen til FALSE, før du ringer til denne IOCTL. Dette stopper enheden fra at forhindre fjernelse af mediet.

  8.   
  9. Skub medierne ud med IOCTL\_STORAGE\_EJECT\_MEDIA IOCTL. Hvis enheden ikke tillader automatisk udstødning, kan IOCTL\_STORAGE\_EJECT\_MEDIA springes over, og brugeren kan få instrueret at fjerne mediet.

  10.   
  11. Luk det lydstyrkehåndtag, der blev opnået i det første trin, eller udsted FSCTL\_UNLOCK\_VOLUME IOCTL. Dette gør det muligt for drevet at blive brugt af andre
      processer.

  12.   



Andreas svar, MSKB artiklen og min API sniffing af Explorer kan opsummeres som følger:



  1. CreateFile kaldes for at åbne lydstyrken. (Alle metoder).

  2. DeviceIoControl kaldes med FSCTL\_LOCK\_VOLUME. (Alle metoder).

  3. DeviceIoControl kaldes med FSCTL\_DISMOUNT\_VOLUME. (Andreas 's og MSKB metoder. Explorer kaller ikke dette af en eller anden grund.Denne IOCTL synes at være, hvad der påvirker om drevet er nedtonet i Explorer eller ej. Jeg er ikke sikker på, hvorfor Explorer ikke kalder dette).

  4. DeviceIoControl kaldet med IOCTL\_STORAGE\_MEDIA\_REMOVAL og PREVENT\_MEDIA\_REMOVAL medlem sat til FALSE (MSKB og Explorer metoder. Dette trin mangler fra Andreas svar).

  5. DeviceIoControl kaldet med IOCTL\_STORAGE\_EJECT\_MEDIA (Andreas og MSKB artiklen) eller IOCTL\_DISK\_EJECT\_MEDIA (Explorer; bemærk, at denne IOCTL var forældet og erstattet med LAGRINGS-IOCTL. Ikke sikker på, hvorfor Explorer stadig bruger den gamle én).



Til sidst besluttede jeg at følge proceduren beskrevet i MSKB-artiklen, da det syntes at være den mest grundige og komplette procedure, støttet op med en MSKB-artikel. [16] [17] [18] [[[19]

Andre referencer 3


Nircmd er et meget praktisk freeware kommandolinjeværktøj med forskellige muligheder, herunder åbning og lukning af cd-skuffen. [20]

Andre referencer 4


For at lukke drevbakken skal du gøre det som beskrevet her, men i stedet for at bruge DeviceIoControl med IOCTL\_STORAGE\_EJECT\_MEDIA skal du ringe DeviceIoControl med IOCTL\_STORAGE\_LOAD\_MEDIA.