Вопрос

Кто-нибудь знает способ программного закрытия лотка для компакт-дисков в Windows 2000 или выше?Открытый лоток для компакт-дисков существует, но я не могу его закрыть, особенно под W2k.

Я особенно ищу способ сделать это из пакетного файла, если это возможно, но вызовы API будут в порядке.

Это было полезно?

Решение

Вот простой способ использования 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);
    }
}

Другие советы

Мне нравится использовать DeviceIOControl, поскольку он дает мне возможность извлечь любой съемный диск (например, USB-диски и флэш-диски, а также лотки для компакт-дисков).Код для правильного извлечения диска с помощью DeviceIOControl (просто добавьте правильную обработку ошибок):

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

Я заметил, что ответ Андреаса Магнуссона работал не совсем так, как кнопка «Извлечь» в Проводнике.В частности, диск не был выделен серым цветом в Проводнике с использованием кода Андреаса, но был, если вы использовали команду «Извлечь».Поэтому я провел небольшое расследование.

Я запустил API Monitor, одновременно выполняя команду Eject из проводника (64-разрядная версия Windows 7 SP1).Я также нашел хорошую статью MSKB 165721 под названием Как извлечь съемный носитель в Windows NT/Windows 2000/Windows XP.Самая интересная часть статьи MSKB приведена ниже:

  1. Вызовите CreateFile с помощью GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE и OPEN_EXISTING.Параметр lpFileName должен быть \.\X:(где X — настоящая буква диска).Все остальные параметры могут быть нулевыми.
  2. Заблокируйте том, выдав FSCTL_LOCK_VOLUME IOCTL через DeviceIoControl.Если какое-либо другое приложение или система использует том, этот IOCTL не будет выполнен.После успешного завершения этой функции приложению гарантируется, что том не используется ничем другим в системе.
  3. Отключите том, выполнив FSCTL_DISMOUNT_VOLUME IOCTL.Это приводит к тому, что файловая система удаляет все сведения о томе и всю внутреннюю информацию, хранящуюся в отношении тома.
  4. Убедитесь, что носитель можно удалить, выполнив IOCTL_STORAGE_MEDIA_REMOVAL IOCTL.Установите для элемента PreventMediaRemoval структуры PREVENT_MEDIA_REMOVAL значение FALSE перед вызовом этого IOCTL.Это не позволяет устройству препятствовать извлечению носителя.
  5. Извлеките носитель с помощью IOCTL_STORAGE_EJECT_MEDIA IOCTL.Если устройство не поддерживает автоматическое извлечение, то IOCTL_STORAGE_EJECT_MEDIA можно пропустить и дать пользователю указание удалить носитель.
  6. Закройте дескриптор тома, полученный на первом этапе, или выполните FSCTL_UNLOCK_VOLUME IOCTL.Это позволяет использовать диск другим процессами.

Ответ Андреаса, статью MSKB и мой анализ API Explorer можно резюмировать следующим образом:

  1. CreateFile вызывается, чтобы открыть том.(Все методы).
  2. DeviceIoControl позвонил с FSCTL_LOCK_VOLUME.(Все методы).
  3. DeviceIoControl позвонил с FSCTL_DISMOUNT_VOLUME.(Только методы Андреаса и MSKB.Explorer почему-то этого не вызывает.Похоже, что этот IOCTL влияет на то, будет ли диск выделен серым цветом в Проводнике или нет.Я не уверен, почему Explorer не вызывает это).
  4. DeviceIoControl позвонил с IOCTL_STORAGE_MEDIA_REMOVAL и PREVENT_MEDIA_REMOVAL член настроен на FALSE (методы MSKB и Explorer.Этот шаг отсутствует в ответе Андреаса).
  5. DeviceIoControl позвонил с IOCTL_STORAGE_EJECT_MEDIA (статья Андреаса и MSKB) или IOCTL_DISK_EJECT_MEDIA (Проводник;обратите внимание, что этот IOCTL устарел и заменен STORAGE IOCTL.Непонятно, почему Explorer до сих пор использует старую версию).

В заключение я решил следовать процедуре, описанной в статье MSKB, поскольку она показалась мне наиболее тщательной и полной процедурой, подкрепленной статьей MSKB.

Ниркмд — очень удобная бесплатная утилита командной строки с различными опциями, включая открытие и закрытие лотка для компакт-дисков.

Чтобы закрыть лоток для дисков, сделайте, как описано. здесь но вместо использования DeviceIoControl с IOCTL_STORAGE_EJECT_MEDIA вам нужно вызвать DeviceIoControl с IOCTL_STORAGE_LOAD_MEDIA.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top