2009-09-19 54 views
4

これを実行する方法はありますか?プログラムでCDドライブをイジェクト/リトラクトできることはわかっています。何か、Roxioはディスクを挿入するように促すときにそれを行います。プログラムで取り出し、vb.netまたはcでCDドライブを取り戻す#

いずれかのc#またはvb.netが推奨されますが、cおよびC++も最後の手段として大丈夫です。

私はほとんどこれを行うにはいくつかの方法があります、私はちょうど呼び出す方法を知らないです。私は方法を探したときに、Googleは絶対に何も得られなかったとして、私は...、これはやや珍しい要求である

答えて

10
using System.Runtime.InteropServices; 

[DllImport("winmm.dll")] 
static extern Int32 mciSendString(String command, StringBuilder buffer, Int32 bufferSize, IntPtr hwndCallback); 

// To open the door 
mciSendString("set CDAudio door open", null, 0, IntPtr.Zero); 

// To close the door 
mciSendString("set CDAudio door closed", null, 0, IntPtr.Zero); 

http://www.geekpedia.com/tutorial174_Opening-and-closing-the-CD-tray-in-.NET.html

+0

時々動作します。必ずしもそうではありません。代わりの解決策は私にとってより信頼性が高いです。しかし、コメントを読んで、FILE_SHARE_READとFILE_SHARE_WRITEを必ず使用してください。 – Filimindji

10

を理解してください

はここで変換され、受け入れられた1の代替ソリューションです〜からVB.NET sample

using System; 
using System.IO; 
using System.Runtime.InteropServices; 

class Test 
{ 
    const int OPEN_EXISTING = 3; 
    const uint GENERIC_READ = 0x80000000; 
    const uint GENERIC_WRITE = 0x40000000; 
    const uint IOCTL_STORAGE_EJECT_MEDIA = 2967560; 

    [DllImport("kernel32")] 
    private static extern IntPtr CreateFile 
     (string filename, uint desiredAccess, 
     uint shareMode, IntPtr securityAttributes, 
     int creationDisposition, int flagsAndAttributes, 
     IntPtr templateFile); 

    [DllImport("kernel32")] 
    private static extern int DeviceIoControl 
     (IntPtr deviceHandle, uint ioControlCode, 
     IntPtr inBuffer, int inBufferSize, 
     IntPtr outBuffer, int outBufferSize, 
     ref int bytesReturned, IntPtr overlapped); 

    [DllImport("kernel32")] 
    private static extern int CloseHandle(IntPtr handle); 

    static void EjectMedia(char driveLetter) 
    { 
     string path = "\\\\.\\" + driveLetter + ":"; 
     IntPtr handle = CreateFile(path, GENERIC_READ | GENERIC_WRITE, 0, 
            IntPtr.Zero, OPEN_EXISTING, 0, 
            IntPtr.Zero); 
     if ((long) handle == -1) 
     { 
      throw new IOException("Unable to open drive " + driveLetter); 
     } 
     int dummy = 0; 
     DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, IntPtr.Zero, 0, 
         IntPtr.Zero, 0, ref dummy, IntPtr.Zero); 
     CloseHandle(handle); 
    } 

    static void Main() 
    { 
     EjectMedia('f'); 
    } 
} 
+0

これは最高のアイデアです。それはハードウェア上のものを想定しています。あなたのハードウェアに取り出しのための特別なドライバがある場合はどうなりますか? Shell eject関数を使うほうがよいでしょう。これは、コードを短くて一般的にするでしょう。 –

+1

これは、受け入れられた答えよりも確実に機能します。しかし、ドキュメント(https://msdn.microsoft.com/en-us/library/windows/desktop/aa363216.aspx)によると、 "CreateFileを呼び出すときにFILE_SHARE_READとFILE_SHARE_WRITEアクセスフラグを指定して、デバイスドライバ。"私はそれが私のために働く前にこれを追加しなければなりませんでした。あなたの答えを編集してこれを含めました。 – stusherwin

+0

私はFILE_SHARE_READとFILE_SHARE_WRITEについて同意します。指定されていない場合は、同時にドライブにアクセスしようとする他のプロセスがCreateFileを失敗させます。 – Filimindji

関連する問題