2008-09-12 3 views
8

¿Alguien sabe un método para cerrar programáticamente la bandeja de CD en Windows 2000 o superior? Existe una bandeja de CD abierta, pero parece que no puedo cerrarla especialmente bajo W2k.Windows CDROM Eject

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

Respuesta

5

Aquí es una manera fácil 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); 
    } 
} 

+1

¿Cómo funciona esto en un sistema con varias unidades? No veo nada para especificar un disco. – OwenP

+3

-1 Votación hacia abajo, mci es una antigua tecnología (Win3.x) y solo funciona bien para una sola unidad. También Windows Media Player debe estar instalado? pero no estoy seguro Las versiones europeas 'N' de Windows no vienen con Media Player, así que ten cuidado. – unixman83

+0

@unixman ¿cuál es la alternativa recomendada? ¿Es ese DeviceIoControl? – jalf

1

Nircmd es una utilidad muy útil de línea de comandos freeware con varias opciones, incluida la apertura y el cierre de la bandeja de CD.

+0

FYI: www.nirsoft.net está bloqueado por mi empresa y he encontrado esto sobre el programa. http://spywarefiles.prevx.com/RRIDCH001610050/NIRCMD.EXE.html – kenny

+1

Al leer esa descripción no me preocupa, parece que les preocupa Nircmd porque es una utilidad que puede hacer cosas. Ni Sophos, Avast ni ESET bloquean nircmd en ninguno de mis sistemas, ni en casa ni en el trabajo. Por otro lado, nunca he oído hablar de Prevx. –

11

me gusta usar DeviceIOControl ya que me da la posibilidad de expulsar cualquier tipo de unidad extraíble (como USB y flash-discos como bien como bandejas de CD). Da codez para expulsar un disco correctamente usando DeviceIOControl está (sólo añadir control de errores adecuada):

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

Esto funciona muy bien, pero tenga en cuenta la ortografía correcta 'DeviceIoControl' (sin mayúscula' O'). – Nate

+0

@Nate: ¡Gracias, lo arregló! –

+0

¿Cómo uso este código? ¿Qué idioma es? – deed02392

3

me di cuenta de que la respuesta de Andreas Magnusson no funcionó bastante exactamente el mismo que el botón de expulsión del Explorador hizo. Específicamente, el disco no estaba atenuado en el Explorador utilizando el código de Andreas, pero lo era si usaba el comando Expulsar. Así que investigué un poco.

Ejecuté el Monitor de API mientras ejecutaba el comando Expulsar desde el Explorador (Windows 7 SP1 de 64 bits). También encontré un buen artículo de MSKB 165721 titulado How To Ejecting Removable Media in Windows NT/Windows 2000/Windows XP. La parte más interesante del artículo MSKB se cita a continuación:

  1. CreateFile llamada 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 con éxito, la aplicación tiene garantizado que el volumen no será utilizado por ninguna otra cosa en el sistema.
  3. Desmonta el volumen emitiendo FSCTL_DISMOUNT_VOLUME IOCTL. Esto hace que el sistema de archivos elimine todo el conocimiento del volumen y descarte cualquier información interna que guarde con respecto al volumen.
  4. Asegúrese de que los medios se puedan eliminar emitiendo 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 evite la eliminación de los medios.
  5. Expulsa el medio con IOCTL_STORAGE_EJECT_MEDIA IOCTL. Si el dispositivo no permite la expulsión automática, se puede omitir IOCTL_STORAGE_EJECT_MEDIA y se puede indicar al usuario que elimine el medio.
  6. Cierre el controlador de volumen obtenido en el primer paso o emita FSCTL_UNLOCK_VOLUME IOCTL. Esto permite que el disco sea utilizado por otros procesos .

respuesta de Andreas, el artículo MSKB, y mi API olfateando del Explorador se pueden resumir de la siguiente manera:

  1. CreateFile llamada para abrir el volumen. (Todos los métodos).
  2. llamada FSCTL_LOCK_VOLUME.(Todos los métodos).
  3. DeviceIoControl llamado con FSCTL_DISMOUNT_VOLUME. (Solo para los métodos de Andreas y MSKB. Explorer no llama a esto por algún motivo. Parece que IOCTL afecta a si la unidad está 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 (Explorer; tenga en cuenta que esta IOCTL estaba obsoleta y se reemplazó por la IOCTL de ALMACENAMIENTO. No estoy seguro de por qué Explorer todavía usa la anterior).

Para concluir, decidí seguir el procedimiento descrito en el artículo MSKB, ya que parecía ser el procedimiento más exhaustiva y completa, respaldada con un artículo MSKB.

+0

El póster original pregunta cómo cerrar la bandeja del CD-ROM, no expulsarlo. –

+0

@RossRidge: ¿Y por eso el título dice "Expulsar CDROM de Windows"? –

+0

A pesar del título, la pregunta es clara. "¿Alguien sabe un método para ** cerrar ** programáticamente la bandeja de CD en Windows 2000 o superior?" (Énfasis mío) –

0

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

Cuestiones relacionadas