C# 在vb.net或c中以编程方式弹出和收回CD驱动器#

C# 在vb.net或c中以编程方式弹出和收回CD驱动器#,c#,vb.net,drive,C#,Vb.net,Drive,有什么办法吗?我知道可以通过编程方式以某种方式弹出/收回cd驱动器,因为Roxio在提示我插入磁盘时会这样做 < > C或VB.NET是最好的,但是C和C++也可以作为最后的手段。< /P> 我几乎肯定有办法做到这一点,我只是不知道调用的方法 我理解这是一个有点不寻常的请求,因为当我搜索方法时,谷歌完全没有得到任何结果 using System.Runtime.InteropServices; [DllImport("winmm.dll")] static extern Int32 mciSe

有什么办法吗?我知道可以通过编程方式以某种方式弹出/收回cd驱动器,因为Roxio在提示我插入磁盘时会这样做

< > C或VB.NET是最好的,但是C和C++也可以作为最后的手段。< /P> 我几乎肯定有办法做到这一点,我只是不知道调用的方法

我理解这是一个有点不寻常的请求,因为当我搜索方法时,谷歌完全没有得到任何结果

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

这里有一个替代已接受解决方案的解决方案,它由一个:


这是最好的主意。它在硬件上进行假设。如果您的硬件具有用于弹出的特殊驱动程序,该怎么办?你最好使用Shell弹出功能,这将使你的代码更短更通用。我发现这比公认的答案更可靠。然而,根据docs(),“当调用CreateFile打开设备驱动程序的句柄时,应该指定FILE_SHARE_READ和FILE_SHARE_WRITE访问标志。”我必须在它对我起作用之前添加它。我编辑了你的答案以包括这些。我同意文件共享读取和文件共享写入。如果未指定,则尝试同时访问驱动器的任何其他进程都会导致CreateFile失败。有时需要工作。不是每次。替代方案对我来说更可靠。但一定要阅读评论,并使用FILE\u SHARE\u read和FILE\u SHARE\u WRITE。
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');
    }
}