前提・実現したいこと
WPFを用いてUSBメモリの取り外しを行いたいと思っています。
取り外しはできているようなのですが、下記のコードで確認するとドライブが残っています。
C#
1Directory.GetLogicalDrives()
完全な取り外しはできないでしょうか?
MainWindow.xaml
C#
1 private void Button_Click_1(object sender, RoutedEventArgs e) 2 { 3 USB lusb = new USB(); 4 lusb.Eject("D"); 5 }
USB.cs
C#
1using System; 2 3using System.Runtime.InteropServices; 4using System.Threading; 5using System.Windows; 6 7namespace test1_wpf 8{ 9 class USB 10 { 11 12 [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] 13 private static extern IntPtr CreateFile( 14 string lpFileName, 15 uint dwDesiredAccess, 16 uint dwShareMode, 17 IntPtr SecurityAttributes, 18 uint dwCreationDisposition, 19 uint dwFlagsAndAttributes, 20 IntPtr hTemplateFile 21 ); 22 23 [DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)] 24 private static extern bool DeviceIoControl( 25 IntPtr hDevice, 26 uint dwIoControlCode, 27 IntPtr lpInBuffer, 28 uint nInBufferSize, 29 IntPtr lpOutBuffer, 30 uint nOutBufferSize, 31 out uint lpBytesReturned, 32 IntPtr lpOverlapped 33 ); 34 35 [DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)] 36 private static extern bool DeviceIoControl( 37 IntPtr hDevice, 38 uint dwIoControlCode, 39 byte[] lpInBuffer, 40 uint nInBufferSize, 41 IntPtr lpOutBuffer, 42 uint nOutBufferSize, 43 out uint lpBytesReturned, 44 IntPtr lpOverlapped 45 ); 46 47 [DllImport("kernel32.dll", SetLastError = true)] 48 [return: MarshalAs(UnmanagedType.Bool)] 49 private static extern bool CloseHandle(IntPtr hObject); 50 51 private IntPtr handle = IntPtr.Zero; 52 53 const uint GENERIC_READ = 0x80000000; 54 const uint GENERIC_WRITE = 0x40000000; 55 const int FILE_SHARE_READ = 0x1; 56 const int FILE_SHARE_WRITE = 0x2; 57 const int FSCTL_LOCK_VOLUME = 0x00090018; 58 const int FSCTL_DISMOUNT_VOLUME = 0x00090020; 59 const int IOCTL_STORAGE_EJECT_MEDIA = 0x2D4808; 60 const int IOCTL_STORAGE_MEDIA_REMOVAL = 0x002D4804; 61 62 public IntPtr USBEject(string driveLetter) 63 { 64 string filename = @"\.\" + driveLetter[0] + ":"; 65 return CreateFile(filename, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, 0x3, 0, IntPtr.Zero); 66 } 67 68 public bool Eject(IntPtr handle) 69 { 70 bool result = false; 71 72 if (LockVolume(handle) && DismountVolume(handle)) 73 { 74 PreventRemovalOfVolume(handle, false); 75 result = AutoEjectVolume(handle); 76 } 77 CloseHandle(handle); 78 return result; 79 } 80 81 private bool LockVolume(IntPtr handle) 82 { 83 uint byteReturned; 84 85 for (int i = 0; i < 10; i++) 86 { 87 if (DeviceIoControl(handle, FSCTL_LOCK_VOLUME, IntPtr.Zero, 0, IntPtr.Zero, 0, out byteReturned, IntPtr.Zero)) 88 { 89 MessageBox.Show("Lock success!"); 90 return true; 91 } 92 Thread.Sleep(500); 93 } 94 return false; 95 } 96 97 private bool PreventRemovalOfVolume(IntPtr handle, bool prevent) 98 { 99 byte[] buf = new byte[1]; 100 uint retVal; 101 102 buf[0] = (prevent) ? (byte)1 : (byte)0; 103 return DeviceIoControl(handle, IOCTL_STORAGE_MEDIA_REMOVAL, buf, 1, IntPtr.Zero, 0, out retVal, IntPtr.Zero); 104 } 105 106 private bool DismountVolume(IntPtr handle) 107 { 108 uint byteReturned; 109 return DeviceIoControl(handle, FSCTL_DISMOUNT_VOLUME, IntPtr.Zero, 0, IntPtr.Zero, 0, out byteReturned, IntPtr.Zero); 110 } 111 112 private bool AutoEjectVolume(IntPtr handle) 113 { 114 uint byteReturned; 115 return DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, IntPtr.Zero, 0, IntPtr.Zero, 0, out byteReturned, IntPtr.Zero); 116 } 117 118 private bool CloseVolume(IntPtr handle) 119 { 120 return CloseHandle(handle); 121 } 122 123 124 public void EjectDrive(char driveLetter) 125 { 126 string path = @"\.\" + driveLetter + @":"; 127 IntPtr handle = CreateFile(path, GENERIC_READ | GENERIC_WRITE, 128 FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, 0x3, 0, IntPtr.Zero); 129 130 if ((long)handle == -1) 131 { 132 MessageBox.Show("Unable to open drive " + driveLetter); 133 return; 134 } 135 136 uint dummy = 0; 137 138 DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, IntPtr.Zero, 0, 139 IntPtr.Zero, 0, out dummy, IntPtr.Zero); 140 141 CloseHandle(handle); 142 143 MessageBox.Show("OK to remove drive."); 144 } 145 } 146} 147
補足情報(FW/ツールのバージョンなど)
Windows 10 Pro
Visual Studio 2017
.NetFramework 4.0
- 実行前
- 実行後
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2019/09/10 07:25
2019/09/10 08:18
退会済みユーザー
2019/09/11 00:14