そのため、ドライブを検索し、特定の USB デバイスを識別しようとするプロジェクトに取り組んでおり、見つかった場合は、このデバイスへのエクスポートを実行します。これが完了すると、デバイスへのエクスポートの完了を通知するポップアップ ダイアログが表示され、USB デバイスを取り出すかどうかをユーザーに尋ねます。
USB デバイスを処理するコードの一部を次に示します。
public class USBController
{
const int OPEN_EXISTING = 3;
const uint GENERIC_READ = 0x80000000;
const uint GENERIC_WRITE = 0x40000000;
const uint IOCTL_STORAGE_EJECT_MEDIA = 0x2D4808;
[DllImport("kernel32", SetLastError = true)]
private static extern int CloseHandle(IntPtr handle);
[DllImport("kernel32", SetLastError = true)]
private static extern int DeviceIoControl
(IntPtr deviceHandle, uint ioControlCode,
IntPtr inBuffer, int inBufferSize,
IntPtr outBuffer, int outBufferSize,
ref int bytesReturned, IntPtr overlapped);
[DllImport("kernel32", SetLastError = true)]
private static extern IntPtr CreateFile
(string filename, uint desiredAccess,
uint shareMode, IntPtr securityAttributes,
int creationDisposition, int flagsAndAttributes,
IntPtr templateFile);
public static bool EjectDrive(char driveLetter, bool displayMessages)
{
string path = "\\\\.\\" + driveLetter + ":";
IntPtr handle = CreateFile(path, GENERIC_READ | GENERIC_WRITE, 0,
IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
if ((long)handle == -1)
{
int error = Marshal.GetLastWin32Error();
if (displayMessages)
MessageBox.Show("Drive may still be in use. Unable to eject drive " + driveLetter + ":\\ \n\nError Code = " + error);
return false;
}
int dummy = 0;
DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, IntPtr.Zero, 0,
IntPtr.Zero, 0, ref dummy, IntPtr.Zero);
int returnValue = DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, IntPtr.Zero, 0,
IntPtr.Zero, 0, ref dummy, IntPtr.Zero);
if (returnValue == 0)
{
int error = Marshal.GetLastWin32Error();
if (displayMessages)
MessageBox.Show("DeviceIoControl encountered an error. \n\nError Code: " + error);
return false;
}
CloseHandle(handle);
if (displayMessages)
MessageBox.Show("OK to remove drive.");
return true;
}
public static bool IsReady(char driveLetter)
{
DriveInfo[] drives = DriveInfo.GetDrives();
foreach (DriveInfo drv in drives)
{
if (Convert.ToChar(drv.RootDirectory.ToString()[0]) == driveLetter && drv.IsReady)
{
return true;
}
}
return false;
}
}
したがって、すべてが機能し、コードは実際に USB デバイスを取り出します。問題は、エクスポートされるファイルが非常に小さく、多くの場合 100kb 未満であるということです。ファイルを書き込んだ後、コードまたはWindowsによって提供されるシステムトレイのツールでUSBドライブを取り出すことができないため、ファイルはファイルキャッシュシステムに座っているようです。デバイスはまだビジー状態です。
キャッシュを強制的にフラッシュする方法、またはこの問題を回避する別の方法はありますか? 私の IsReady メソッドは、デバイスがアクセス可能であることをより確認しているように見えますが、必ずしも取り出す準備ができているとは限りません。
ありがとう