Windows CDROM Eject - PullRequest
       33

Windows CDROM Eject

10 голосов
/ 12 сентября 2008

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

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

Ответы [ 5 ]

12 голосов
/ 17 сентября 2008

Мне нравится использовать 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;
}
6 голосов
/ 12 сентября 2008

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

3 голосов
/ 28 мая 2015

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

Я запускал API Monitor при запуске команды «Извлечь» из Проводника (64-разрядная версия Windows 7 с пакетом обновления 1). Я также нашел хорошую статью 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 IOCTL_STORAGE_MEDIA_REMOVAL. Установите для элемента PreventMediaRemoval структуры PREVENT_MEDIA_REMOVAL значение FALSE перед вызовом этого IOCTL. Это мешает устройству предотвращать удаление носителя.
  5. Извлечение носителя с IOCTL IOCTL_STORAGE_EJECT_MEDIA. Если устройство не допускает автоматического извлечения, то 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 (Explorer; обратите внимание, этот IOCTL был устаревшим и заменен на IOCTL STORAGE. Не уверен, почему Explorer по-прежнему использует старый один).

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

1 голос
/ 03 сентября 2015

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

1 голос
/ 12 сентября 2008

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...