質問
Windows 2000 以降で CD トレイをプログラムで閉じる方法を知っている人はいますか?開いた CD トレイは存在しますが、特に 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、フラッシュ ディスク、CD トレイなど) を取り出すことができるからです。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;
}
Andreas Magnusson の答えは、Explorer の [取り出し] ボタンとまったく同じように機能しないことに気付きました。具体的には、Andreas のコードを使用したエクスプローラーではドライブがグレー表示されませんでしたが、Eject コマンドを使用するとグレー表示されました。そこで、いくつか調べてみました。
エクスプローラー (Windows 7 SP1 64 ビット) から Eject コマンドを実行しながら、API モニターを実行しました。また、MSKB 記事 165721 というタイトルの優れた記事も見つけました。 Windows NT/Windows 2000/Windows XP でリムーバブル メディアを取り出す方法. 。MSKB 記事の最も興味深い部分を以下に引用します。
- 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 がなぜこれを呼び出さないのかはわかりません)。DeviceIoControl
と呼ばれたIOCTL_STORAGE_MEDIA_REMOVAL
そしてPREVENT_MEDIA_REMOVAL
に設定されたメンバーFALSE
(MSKB および Explorer メソッド。このステップはアンドレアスの答えにはありません)。DeviceIoControl
と呼ばれたIOCTL_STORAGE_EJECT_MEDIA
(アンドレアスと MSKB の記事) またはIOCTL_DISK_EJECT_MEDIA
(冒険者;この IOCTL は廃止され、STORAGE IOCTL に置き換えられたことに注意してください。なぜ Explorer がまだ古いものを使用しているのかはわかりません)。
結論として、MSKB 記事で説明されている手順に従うことにしました。これは、MSKB 記事に裏付けられた最も徹底した完全な手順であると思われました。
ニルコマンド は、CD トレイの開閉など、さまざまなオプションを備えた非常に便利なフリーウェア コマンド ライン ユーティリティです。
ドライブ トレイを閉じるには、説明に従ってください。 ここ ただし、IOCTL_STORAGE_EJECT_MEDIA で DeviceIoControl を使用する代わりに、IOCTL_STORAGE_LOAD_MEDIA で DeviceIoControl を呼び出す必要があります。