Pregunta

¿Alguien conoce un método para cerrar mediante programación la bandeja del CD en Windows 2000 o superior?Existe una bandeja de CD abierta, pero parece que no puedo cerrarla, especialmente en W2k.

Estoy buscando especialmente un método para hacer esto desde un archivo por lotes, si es posible, pero las llamadas API estarían bien.

¿Fue útil?

Solución

A continuación se muestra una forma sencilla de utilizar la API de Win32:


[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);
    }
}

Otros consejos

Me gusta usar DeviceIOControl ya que me da la posibilidad de expulsar cualquier tipo de unidad extraíble (como USB y discos flash, así como bandejas de CD).El código para expulsar correctamente un disco usando DeviceIOControl es (simplemente agregue el manejo de errores adecuado):

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;
}

Me di cuenta de que la respuesta de Andreas Magnusson no funcionaba exactamente igual que el botón Expulsar del Explorador.Específicamente, la unidad no estaba atenuada en Explorer usando el código de Andreas, pero sí si usaba el comando Expulsar.Así que investigué un poco.

Ejecuté API Monitor mientras ejecutaba el comando Expulsar desde Explorer (Windows 7 SP1 de 64 bits).También encontré un buen artículo de MSKB 165721 titulado Cómo expulsar medios extraíbles en Windows NT/Windows 2000/Windows XP.La parte más interesante del artículo de MSKB se cita a continuación:

  1. Llame a CreateFile con GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE y OPEN_EXISTING.El parámetro lpFileName debe ser \.\X:(donde X es la letra de unidad real).Todos los demás parámetros pueden ser cero.
  2. Bloquee el volumen emitiendo FSCTL_LOCK_VOLUME IOCTL a través de DeviceIoControl.Si alguna otra aplicación o el sistema está utilizando el volumen, este IOCTL falla.Una vez que esta función regresa exitosamente, la aplicación tiene la garantía de que el volumen no será utilizado por nada más en el sistema.
  3. Desmonte el volumen emitiendo el IOCTL FSCTL_DISMOUNT_VOLUME.Esto hace que el sistema de archivos elimine todo conocimiento del volumen y descarte cualquier información interna que guarde sobre el volumen.
  4. Asegúrese de que los medios se puedan eliminar emitiendo el IOCTL_STORAGE_MEDIA_REMOVAL IOCTL.Establezca el miembro PreventMediaRemoval de la estructura PREVENT_MEDIA_REMOVAL en FALSE antes de llamar a este IOCTL.Esto evita que el dispositivo impida la extracción del medio.
  5. Expulse los medios con IOCTL_STORAGE_EJECT_MEDIA IOCTL.Si el dispositivo no permite la expulsión automática, entonces se puede omitir IOCTL_STORAGE_EJECT_MEDIA y se le puede indicar al usuario que retire el medio.
  6. Cierre el identificador de volumen obtenido en el primer paso o emita FSCTL_UNLOCK_VOLUME IOCTL.Esto permite que la unidad sea utilizada por otros procesos.

La respuesta de Andreas, el artículo de MSKB y mi análisis de API de Explorer se pueden resumir de la siguiente manera:

  1. CreateFile Llamado para abrir el volumen.(Todos los métodos).
  2. DeviceIoControl llamado con FSCTL_LOCK_VOLUME.(Todos los métodos).
  3. DeviceIoControl llamado con FSCTL_DISMOUNT_VOLUME.(Únicamente los métodos de Andreas y MSKB.Explorer no llama a esto por alguna razón.Este IOCTL parece ser lo que afecta si la unidad aparece atenuada en Explorer o no.No estoy seguro de por qué Explorer no llama a esto).
  4. DeviceIoControl llamado con IOCTL_STORAGE_MEDIA_REMOVAL y PREVENT_MEDIA_REMOVAL miembro establecido en FALSE (Métodos MSKB y Explorer.Este paso falta en la respuesta de Andreas).
  5. DeviceIoControl llamado con IOCTL_STORAGE_EJECT_MEDIA (artículo de Andreas y MSKB) o IOCTL_DISK_EJECT_MEDIA (Explorador;tenga en cuenta que este IOCTL quedó obsoleto y fue reemplazado por STORAGE IOCTL.No estoy seguro de por qué Explorer todavía usa el anterior).

Para concluir, decidí seguir el procedimiento descrito en el artículo de MSKB, ya que parecía ser el procedimiento más minucioso y completo, respaldado con un artículo de MSKB.

nicmd es una utilidad de línea de comandos gratuita muy útil con varias opciones, incluida abrir y cerrar la bandeja del CD.

Para cerrar la bandeja de la unidad, haga lo que se describe aquí pero en lugar de usar DeviceIoControl con IOCTL_STORAGE_EJECT_MEDIA necesitas llamar a DeviceIoControl con IOCTL_STORAGE_LOAD_MEDIA.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top