C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

USBメモリのイジェクト


(過去ログ 159 を表示中)

[トピック内 1 記事 (1 - 1 表示)]  << 0 >>

■92259 / inTopicNo.1)  USBメモリのイジェクト
  
□投稿者/ かつ (1回)-(2019/09/05(Thu) 16:41:51)

分類:[C#] 

2019/09/05(Thu) 16:42:59 編集(投稿者)
Windows10で動作させる前提、開発環境はC#でUSBメモリをイジェクトする必要があり、下記コードで作っております。
いろいろなサンプルを調べながらイジェクト自体はできております。
しかし、エクスプローラでみてみるとドライブの存在は残っており、クリックすると「USBドライブ(X:)にディスクを挿入してください。」
と表示されます。
まるでカードリーダーを差し込んでまだカード自体は差し込んでない状態のようです。

参考にさせていただいたUSBメモリのイジェクト方法はほかにもあったのですが、どの方法でも症状は同じでした。
どうすればシステムトレイからマウス操作で実施したときと同じ挙動にできるのでしょうか?


        public static Boolean Eject(this DriveInfo drive)
        {
            using (var volume = Open(drive, false))
            {

                try
                {

                    const int maxRetry = 10; // デバイスロックの最大試行回数
                    var locked = false;

                    for (var t = 0; t < maxRetry; t++)
                    {
                        if (IOControl.IOCtl(volume.DangerousGetHandle(), IOControl.FSCTL_LOCK_VOLUME))
                        {
                            locked = true;
                            break;
                        }
                        else
                        {
                            System.Threading.Thread.Sleep(100); // ロックできなければ1秒後に再試行
                        }
                    }

                    if (!locked)
                        throw new IOException("デバイスがビジー状態です");

                    if (!IOControl.IOCtl(volume.DangerousGetHandle(), IOControl.FSCTL_DISMOUNT_VOLUME))
                        throw new Win32Exception(Marshal.GetLastWin32Error());

                    unsafe
                    {
                        uint bytesReturned;
                        PREVENT_MEDIA_REMOVAL* inBuffer = stackalloc PREVENT_MEDIA_REMOVAL[1];

                        inBuffer[0].PreventMediaRemoval = 0; // FALSE

                        if (!IOControl.DeviceIoControl(volume.DangerousGetHandle(), IOControl.IOCTL_STORAGE_MEDIA_REMOVAL, (void*)inBuffer, (uint)Marshal.SizeOf(typeof(PREVENT_MEDIA_REMOVAL)), (void*)IntPtr.Zero, 0, out bytesReturned, IntPtr.Zero))
                            throw new Win32Exception(Marshal.GetLastWin32Error());
                    }


                 
                    if (!IOControl.IOCtl(volume.DangerousGetHandle(), IOControl.IOCTL_STORAGE_EJECT_MEDIA))
                        throw new Win32Exception(Marshal.GetLastWin32Error());

                    return true;
                }
                catch
                {
                    return false;

                }
            }
        }

        /// <summary>ドライブを開いてSafeFileHandleを取得する</summary>
        private static SafeFileHandle Open(DriveInfo drive, bool accessWrite)
        {
            uint accessFlags;

            if (drive.DriveType == DriveType.CDRom)
                accessFlags = GENERIC_READ;
            else if (drive.DriveType == DriveType.Removable)
                accessFlags = GENERIC_READ | GENERIC_WRITE;
            else if (drive.DriveType == DriveType.Fixed)
                accessFlags = GENERIC_READ | GENERIC_WRITE;
            else
                throw new NotSupportedException("リムーバブルドライブではありません");

            if (accessWrite)
                accessFlags |= GENERIC_WRITE;

            var handle = CreateFile(string.Format(@"\\.\{0}:", drive.Name[0]),
                                    accessFlags,
                                    FILE_SHARE_READ | FILE_SHARE_WRITE,
                                    IntPtr.Zero,
                                    OPEN_EXISTING,
                                    0,
                                    IntPtr.Zero);

            if (handle == INVALID_HANDLE_VALUE)
                throw new Win32Exception(Marshal.GetLastWin32Error());

            return new SafeFileHandle(handle, true);
        }

引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -