gpt4 book ai didi

c# - DeviceIoControl 无法弹出非空的 CDROM 驱动器?

转载 作者:行者123 更新时间:2023-11-30 16:22:22 28 4
gpt4 key购买 nike

我尝试使用 DeviceIoControl 函数(Win32 API 函数)弹出我的 CDROM 驱动器,当我的 CDROM 驱动器没有磁盘时它工作正常,但是在插入磁盘后,Marshal .GetLastWin32Error()返回32(ERROR_SHARING_VIOLATION:进程无法访问该文件,因为它正在被另一个进程使用),DeviceIoControl中传递的driveHandle是由 CreateFile() 函数创建。

你能帮帮我吗?我喜欢这种操作 CD ROM 相关东西的方式,我可以使用 winmm.dll 弹出我的 CDROM 但我认为这种方式值得一试。

好的,这是代码:

using System;
using System.ComponentModel;
using System.Text;
using System.Windows.Forms;
using System.IO;

using System.Runtime.InteropServices;

namespace DVD_ejector
{

public partial class Form1 : Form
{
const int OPENEXISTING = 3;
const int IOCTL_STORAGE_EJECT_MEDIA = 2967560;
const uint GENERICREAD = 0x80000000;
const int INVALID_HANDLE = -1;
public Form1()
{
InitializeComponent();
DriveInfo[] drs = DriveInfo.GetDrives();
List<DriveInfo> cdRoms = new List<DriveInfo>();
foreach (DriveInfo dInfo in drs)
{
if (dInfo.DriveType == DriveType.CDRom)
{
cdRoms.Add(dInfo);
}
}
comboBox1.DataSource = cdRoms;
comboBox1.DisplayMember = "Name";

if (comboBox1.Items.Count > 0) comboBox1.SelectedIndex = 0;
button1.Click += (sender, e) =>
{
Eject(@"\\.\" + ((DriveInfo)comboBox1.SelectedItem).Name[0]+":");
};
}
[DllImport("kernel32", SetLastError=true)]
static extern IntPtr CreateFile(string fileName, uint desiredAccess, uint shareMode, IntPtr attributes,uint creationDisposition, uint flagsAndAttribute, IntPtr fileTemplate);
[DllImport("kernel32")]
static extern int CloseHandle(IntPtr fileHandle);
[DllImport("kernel32")]
static extern bool DeviceIoControl(IntPtr driveHandle, int ctrlCode, IntPtr inBuffer, int inBufferSize, IntPtr outBuffer, int outBufferSize, ref int bytesReturned, IntPtr overlapped);
int bytesReturned;
private void Eject(string cdDrive)
{
IntPtr driveHandle = CreateFile(cdDrive, GENERICREAD, 0, IntPtr.Zero, OPENEXISTING, 0, IntPtr.Zero);
try
{
if((int)driveHandle != INVALID_HANDLE)
DeviceIoControl(driveHandle, IOCTL_STORAGE_EJECT_MEDIA, IntPtr.Zero, 0, IntPtr.Zero, 0, ref bytesReturned, IntPtr.Zero);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
CloseHandle(driveHandle);
}
}
}
}

最佳答案

如错误所述,该设备正在被其他东西使用,但它在 CreateFile 调用而不是 DeviceIoControl 上失败,并且您的代码未正确检查对于失败。

您遇到共享冲突的原因是因为您试图以独占方式打开设备,如果有任何东西试图打开它或其中的文件,包括防病毒、资源管理器、搜索索引器等,这将失败。

这个更新的 Eject 函数修复了共享模式和错误处理,现在在正确的地方报告错误。

private void Eject(string cdDrive) {
IntPtr driveHandle = new IntPtr(INVALID_HANDLE);
try {
// Open the device
driveHandle = CreateFile(cdDrive, GENERICREAD, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, IntPtr.Zero, OPENEXISTING, 0, IntPtr.Zero);
if ((int)driveHandle == INVALID_HANDLE) { throw new Win32Exception(); }

// Try and eject
bool ejected = DeviceIoControl(driveHandle, IOCTL_STORAGE_EJECT_MEDIA, IntPtr.Zero, 0, IntPtr.Zero, 0, ref bytesReturned, IntPtr.Zero);
if (!ejected) { throw new Win32Exception(); }

} catch (Exception ex) {
MessageBox.Show(ex.Message);

} finally {
if ((int)driveHandle != INVALID_HANDLE) { CloseHandle(driveHandle); }
}
}

关于c# - DeviceIoControl 无法弹出非空的 CDROM 驱动器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12472770/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com