Pergunta
Alguém sabe de um método para fechar programaticamente a bandeja de CD no Windows 2000 ou superior?Abrir a gaveta do CD existe, mas eu não consigo fazer é fechar especialmente sob W2k.
Eu estou especialmente à procura de um método para fazer isso a partir de um arquivo em lotes, se possível, mas chamadas de API seria OK.
Solução
Aqui está uma maneira fácil usando a API do 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);
}
}
Outras dicas
Eu gosto de como usar DeviceIOControl, ele me dá a possibilidade de ejetar qualquer tipo de unidade removível (como flash USB e discos-CD bandejas).Da codez corretamente ejetar um disco usando DeviceIOControl é (basta adicionar adequada de tratamento de erros):
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;
}
Notei que Andreas Magnusson a resposta não funcionou exatamente o mesmo como o Explorer do botão de Ejecção fez.Especificamente, a unidade não estará esmaecida no Explorer usando Andreas código, mas era a de que se você usou o comando de Ejeção.Então eu fiz alguma investigação.
Eu corri API Monitor enquanto estiver executando o comando Ejetar a partir do Explorador do Windows (Windows 7 SP1 de 64 bits).Eu também achei uma boa MSKB artigo intitulado 165721 Como Ejetar a Mídia Removível no Windows NT/Windows 2000/Windows XP.A parte mais interessante do artigo MSKB é citado abaixo:
- Chamar CreateFile com GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, e OPEN_EXISTING.O parâmetro lpFileName deve ser \.\X:(onde X é a letra da unidade real).Todos os outros parâmetros podem ser zero.
- Bloquear o volume de emissão de FSCTL_LOCK_VOLUME IOCTL através de DeviceIoControl.Se qualquer outro aplicativo ou o sistema está usando o volume, este IOCTL falha.Uma vez que esta função retorna com êxito, o aplicativo é garantido que o volume não é usado por qualquer outra coisa no sistema.
- Desmontar o volume de emissão de FSCTL_DISMOUNT_VOLUME IOCTL.Isso faz com que o sistema de arquivos para remover todo o conhecimento do volume e o descarte de qualquer informação interna que mantém sobre o volume.
- Certifique-se de que a mídia pode ser removida através da emissão de IOCTL IOCTL_STORAGE_MEDIA_REMOVAL.O PreventMediaRemoval membro do conjunto da estrutura PREVENT_MEDIA_REMOVAL como FALSE antes de chamar este IOCTL.Este comando pára o dispositivo de impedir a remoção dos meios de comunicação.
- Ejetar mídia com a IOCTL_STORAGE_EJECT_MEDIA IOCTL.Se o dispositivo não permitir a ejecção automática, em seguida, IOCTL_STORAGE_EJECT_MEDIA pode ser ignorado e o usuário pode ser instruído para remover a mídia.
- Fechar o identificador de volume obtido na primeira etapa ou problema IOCTL FSCTL_UNLOCK_VOLUME.Isto permite a unidade ser usada por outros processos.
Andreas resposta, o artigo MSKB, e o meu API de intercepção do Explorer pode ser resumido como se segue:
CreateFile
chamada para abrir o volume.(Todos os métodos).DeviceIoControl
chamado comFSCTL_LOCK_VOLUME
.(Todos os métodos).DeviceIoControl
chamado comFSCTL_DISMOUNT_VOLUME
.(Andreas e MSKB apenas os métodos.Explorer não chamar isso por algum motivo.Este IOCTL parece ser o que afeta se a unidade está a cinzento no Explorer ou não.Eu não tenho certeza por isso Explorer não chamar esse).DeviceIoControl
chamado comIOCTL_STORAGE_MEDIA_REMOVAL
ePREVENT_MEDIA_REMOVAL
conjunto de membros paraFALSE
(MSKB e Explorador métodos.Este passo é falta de Andreas resposta).DeviceIoControl
chamado comIOCTL_STORAGE_EJECT_MEDIA
(Andreas e MSKB artigo) ouIOCTL_DISK_EJECT_MEDIA
(Explorer;nota este IOCTL foi obsoletos e substituídos com o ARMAZENAMENTO IOCTL.Não sei por que Explorer ainda usa o antigo).
Para concluir, eu decidi seguir o procedimento descrito no artigo MSKB, como parecia ser o mais completo e concluir o procedimento, feito com um artigo MSKB.
Nircmd é uma aplicação muito útil freeware utilitário de linha de comandos com várias opções, incluindo a abrir e fechar a bandeja de CD.
Para fechar a bandeja da unidade de fazer como descrito aqui mas em vez de usar DeviceIoControl com IOCTL_STORAGE_EJECT_MEDIA você precisa chamar DeviceIoControl com IOCTL_STORAGE_LOAD_MEDIA.