Windows 2000以降でプログラムでCDトレイを閉じる方法を知っている人はいますか?開いているCDトレイはありますが、特にW2kでは閉じることができないようです。
可能であれば、バッチファイルからこれを行う方法を特に探していますが、API呼び出しは問題ありません。
あらゆる種類のリムーバブル ドライブ (USB やフラッシュ ディスク、CD トレイなど) を取り出すことができるので、私は DeviceIOControl を使用するのが好きです。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;
}
Win32APIを使用する簡単な方法は次のとおりです。
[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);
}
}
Andreas Magnusson の回答は、Explorer の「イジェクト」ボタンとまったく同じには機能しないことに気付きました。具体的には、アンドレアスのコードを使用した場合、ドライブは Explorer でグレー表示されませんでしたが、Eject コマンドを使用した場合はグレー表示されました。というわけで色々調べてみました。
エクスプローラー (Windows 7 SP1 64 ビット) から Eject コマンドを実行しているときに、API モニターを実行しました。また、Windows NT/Windows 2000/Windows XP でリムーバブル メディアを取り出す方法というタイトルの優れた (現在は廃止された) MSKB 記事 165721 も見つけました。この記事の最も興味深い部分を以下に引用します。
- GENERIC_READ|GENERIC_WRITE、FILE_SHARE_READ|FILE_SHARE_WRITE、および OPEN_EXISTING を指定して CreateFile を呼び出します。lpFileName パラメータは \\.\X: (X は実際のドライブ文字) である必要があります。他のすべてのパラメーターはゼロにすることができます。
- DeviceIoControl 経由で FSCTL_LOCK_VOLUME IOCTL を発行して、ボリュームをロックします。他のアプリケーションまたはシステムがボリュームを使用している場合、この IOCTL は失敗します。この関数が正常に戻ると、ボリュームがシステム内の他のものによって使用されていないことがアプリケーションで保証されます。
- FSCTL_DISMOUNT_VOLUME IOCTL を発行してボリュームをマウント解除します。これにより、ファイル システムはボリュームに関するすべての情報を削除し、ボリュームに関して保持している内部情報をすべて破棄します。
- IOCTL_STORAGE_MEDIA_REMOVAL IOCTL を発行して、メディアを削除できることを確認します。この IOCTL を呼び出す前に、PREVENT_MEDIA_REMOVAL 構造体の PreventMediaRemoval メンバーを FALSE に設定します。これにより、デバイスがメディアの削除を妨げなくなります。
- IOCTL_STORAGE_EJECT_MEDIA IOCTL でメディアを取り出します。デバイスで自動取り出しが許可されていない場合は、IOCTL_STORAGE_EJECT_MEDIA をスキップして、ユーザーにメディアを取り出すように指示できます。
- 最初の手順で取得したボリューム ハンドルを閉じるか、FSCTL_UNLOCK_VOLUME IOCTL を発行します。これにより、ドライブを他のプロセスで使用できるようになります。
Andreas の回答、MSKB の記事、および Explorer の API スニッフィングは、次のように要約できます。
CreateFile
ボリュームを開くために呼び出されます。(すべての方法)。DeviceIoControl
で呼び出されFSCTL_LOCK_VOLUME
ます。(すべての方法)。DeviceIoControl
で呼び出されFSCTL_DISMOUNT_VOLUME
ます。(Andreas と MSKB のメソッドのみ。Explorer は何らかの理由でこれを呼び出しません。この IOCTL は、ドライブが Explorer でグレー表示されるかどうかに影響するようです。Explorer がこれを呼び出さない理由はわかりません)。DeviceIoControl
で呼び出されIOCTL_STORAGE_MEDIA_REMOVAL
、PREVENT_MEDIA_REMOVAL
メンバーがFALSE
(MSKB および Explorer メソッド。このステップは Andreas の回答にありません) に設定されます。DeviceIoControl
( IOCTL_STORAGE_EJECT_MEDIA
Andreas and MSKB article) またはIOCTL_DISK_EJECT_MEDIA
(Explorer; この IOCTL は廃止され、STORAGE IOCTL に置き換えられたことに注意してください。Explorer がまだ古いものを使用している理由は不明です)。結論として、私は MSKB 記事で説明されている手順に従うことにしました。これは、MSKB 記事で裏付けられた最も徹底した完全な手順であると思われたためです。
Nircmdは、CDトレイの開閉など、さまざまなオプションを備えた非常に便利なフリーウェアのコマンドラインユーティリティです。