C# 通过C弹出USB设备#

C# 通过C弹出USB设备#,c#,usb,C#,Usb,我正在寻找一种通过C代码弹出USB设备的短方法,所以我自己编写了一个小类,但它根本不起作用。由于没有显示“锁定成功”的弹出窗口,我假设问题发生在“LockVolume”函数中,但我不知道在哪里 有人看到我犯的错误了吗 class USBEject { [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] private static extern IntPtr CreateFile(

我正在寻找一种通过C代码弹出USB设备的短方法,所以我自己编写了一个小类,但它根本不起作用。由于没有显示“锁定成功”的弹出窗口,我假设问题发生在“LockVolume”函数中,但我不知道在哪里

有人看到我犯的错误了吗

class USBEject
{
    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    private static extern IntPtr CreateFile(
         string lpFileName,
         uint dwDesiredAccess,
         uint dwShareMode,
         IntPtr SecurityAttributes,
         uint dwCreationDisposition,
         uint dwFlagsAndAttributes,
         IntPtr hTemplateFile
    );

    [DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)]
    private static extern bool DeviceIoControl(
        IntPtr hDevice, 
        uint dwIoControlCode,
        IntPtr lpInBuffer, 
        uint nInBufferSize,
        IntPtr lpOutBuffer, 
        uint nOutBufferSize,
        out uint lpBytesReturned, 
        IntPtr lpOverlapped
    );

    [DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)]
    private static extern bool DeviceIoControl(
        IntPtr hDevice, 
        uint dwIoControlCode,
        byte[] lpInBuffer, 
        uint nInBufferSize,
        IntPtr lpOutBuffer, 
        uint nOutBufferSize,
        out uint lpBytesReturned, 
        IntPtr lpOverlapped
    );

    [DllImport("kernel32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool CloseHandle(IntPtr hObject);

    private IntPtr handle = IntPtr.Zero;

    const int GENERIC_READ = 0x80000000;
    const int GENERIC_WRITE = 0x40000000;
    const int FILE_SHARE_READ = 0x1;
    const int FILE_SHARE_WRITE = 0x2;
    const int FSCTL_LOCK_VOLUME = 0x00090018;
    const int FSCTL_DISMOUNT_VOLUME = 0x00090020;
    const int IOCTL_STORAGE_EJECT_MEDIA = 0x2D4808;
    const int IOCTL_STORAGE_MEDIA_REMOVAL = 0x002D4804;

    /// <summary>
    /// Constructor for the USBEject class
    /// </summary>
    /// <param name="driveLetter">This should be the drive letter. Format: F:/, C:/..</param>

    public USBEject(string driveLetter)
    {
        string filename = @"\\.\" + driveLetter[0] + ":";
        handle = CreateFile(filename, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, 0x3, 0, IntPtr.Zero);
    }

    public bool Eject()
    {
        if (LockVolume(handle) && DismountVolume(handle))
        {
            PreventRemovalOfVolume(handle, false);
            return AutoEjectVolume(handle);
        }

        return false;
    }

    private bool LockVolume(IntPtr handle)
    {
        uint byteReturned;

        for (int i = 0; i < 10; i++)
        {
            if (DeviceIoControl(handle, FSCTL_LOCK_VOLUME, IntPtr.Zero, 0, IntPtr.Zero, 0, out byteReturned, IntPtr.Zero))
            {
                System.Windows.Forms.MessageBox.Show("Lock success!");
                return true;
            }
            Thread.Sleep(500);
        }
        return false;
    }

    private bool PreventRemovalOfVolume(IntPtr handle, bool prevent)
    {
        byte[] buf = new byte[1];
        uint retVal;

        buf[0] = (prevent) ? (byte)1 : (byte)0;
        return DeviceIoControl(handle, IOCTL_STORAGE_MEDIA_REMOVAL, buf, 1, IntPtr.Zero, 0, out retVal, IntPtr.Zero);
    }

    private bool DismountVolume(IntPtr handle)
    {
        uint byteReturned;
        return DeviceIoControl(handle, FSCTL_DISMOUNT_VOLUME, IntPtr.Zero, 0, IntPtr.Zero, 0, out byteReturned, IntPtr.Zero);
    }

    private bool AutoEjectVolume(IntPtr handle)
    {
        uint byteReturned;
        return DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, IntPtr.Zero, 0, IntPtr.Zero, 0, out byteReturned, IntPtr.Zero);
    }

    private bool CloseVolume(IntPtr handle)
    {
        return CloseHandle(handle);
    }
}
类USBEject
{
[DllImport(“kernel32.dll”,SetLastError=true,CharSet=CharSet.Auto)]
私有静态外部IntPtr创建文件(
字符串lpFileName,
uint DWD期望访问,
uint dwShareMode,
IntPtr安全属性,
uint dwCreationDisposition,
uint dwFlagsAndAttributes,
IntPtr-hTemplateFile
);
[DllImport(“kernel32.dll”,ExactSpelling=true,SetLastError=true,CharSet=CharSet.Auto)]
专用静态外部布尔设备控制(
IntPtr hDevice,
uint dwIoControlCode,
IntPtr lpInBuffer,
单位尺寸,
IntPtr LPEXBUFFER,
单位无缓冲尺寸,
out uint LPBYTES返回,
IntPtr LPR重叠
);
[DllImport(“kernel32.dll”,ExactSpelling=true,SetLastError=true,CharSet=CharSet.Auto)]
专用静态外部布尔设备控制(
IntPtr hDevice,
uint dwIoControlCode,
字节[]lpInBuffer,
单位尺寸,
IntPtr LPEXBUFFER,
单位无缓冲尺寸,
out uint LPBYTES返回,
IntPtr LPR重叠
);
[DllImport(“kernel32.dll”,SetLastError=true)]
[返回:Marshallas(UnmanagedType.Bool)]
专用静态外部布尔闭合手柄(IntPtr hObject);
私有IntPtr句柄=IntPtr.Zero;
const int GENERIC_READ=0x8000000;
const int GENERIC_WRITE=0x40000000;
const int FILE_SHARE_READ=0x1;
const int FILE_SHARE_WRITE=0x2;
const int FSCTL_LOCK_VOLUME=0x00090018;
const int FSCTL_DISMOUNT_VOLUME=0x00090020;
const int IOCTL_STORAGE_EJECT_MEDIA=0x2D4808;
const int IOCTL_STORAGE_MEDIA_removation=0x002D4804;
/// 
///USBEject类的构造函数
/// 
///这应该是驱动器号。格式:F:/,C:/。。
公共USBEject(字符串驱动器号)
{
字符串文件名=@“\\.\”+驱动器号[0]+“:”;
handle=CreateFile(文件名,通用读写,文件共享读写,文件共享写,IntPtr.Zero,0x3,0,IntPtr.Zero);
}
公共bool弹出()
{
if(锁定卷(手柄)和卸载卷(手柄))
{
防止卷的删除(句柄,false);
返回自动弹出卷(句柄);
}
返回false;
}
专用布尔锁卷(IntPtr句柄)
{
乌因特·拜特伦;
对于(int i=0;i<10;i++)
{
if(设备控制(句柄、FSCTL_锁_卷、IntPtr.Zero、0、IntPtr.Zero、0、out byteReturned、IntPtr.Zero))
{
System.Windows.Forms.MessageBox.Show(“锁定成功!”);
返回true;
}
睡眠(500);
}
返回false;
}
私有bool-prevent删除卷(IntPtr句柄,bool-prevent)
{
字节[]buf=新字节[1];
uint-retVal;
buf[0]=(防止)?(字节)1:(字节)0;
返回设备控制(句柄、IOCTL存储介质删除、buf、1、IntPtr.Zero、0、out retVal、IntPtr.Zero);
}
私有卷卸载(IntPtr句柄)
{
乌因特·拜特伦;
返回设备控制(句柄、FSCTL\u卸载\u卷、IntPtr.Zero、0、IntPtr.Zero、0、out byteReturned、IntPtr.Zero);
}
私有bool自动弹出卷(IntPtr句柄)
{
乌因特·拜特伦;
返回设备控制(句柄、IOCTL\存储\弹出\介质、IntPtr.Zero、0、IntPtr.Zero、0、out BYTERETRETURN、IntPtr.Zero);
}
专用布尔关闭卷(IntPtr句柄)
{
返回闭合手柄(手柄);
}
}

只对您的代码做了一点更改,如下所示:

    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    private static extern IntPtr CreateFile(
     string lpFileName,
     uint dwDesiredAccess,
     uint dwShareMode,
     IntPtr SecurityAttributes,
     uint dwCreationDisposition,
     uint dwFlagsAndAttributes,
     IntPtr hTemplateFile
);

    [DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)]
    private static extern bool DeviceIoControl(
        IntPtr hDevice,
        uint dwIoControlCode,
        IntPtr lpInBuffer,
        uint nInBufferSize,
        IntPtr lpOutBuffer,
        uint nOutBufferSize,
        out uint lpBytesReturned,
        IntPtr lpOverlapped
    );

    [DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)]
    private static extern bool DeviceIoControl(
        IntPtr hDevice,
        uint dwIoControlCode,
        byte[] lpInBuffer,
        uint nInBufferSize,
        IntPtr lpOutBuffer,
        uint nOutBufferSize,
        out uint lpBytesReturned,
        IntPtr lpOverlapped
    );

    [DllImport("kernel32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool CloseHandle(IntPtr hObject);

    private IntPtr handle = IntPtr.Zero;

    const uint GENERIC_READ = 0x80000000;
    const uint GENERIC_WRITE = 0x40000000;
    const int FILE_SHARE_READ = 0x1;
    const int FILE_SHARE_WRITE = 0x2;
    const int FSCTL_LOCK_VOLUME = 0x00090018;
    const int FSCTL_DISMOUNT_VOLUME = 0x00090020;
    const int IOCTL_STORAGE_EJECT_MEDIA = 0x2D4808;
    const int IOCTL_STORAGE_MEDIA_REMOVAL = 0x002D4804;

    /// <summary>
    /// Constructor for the USBEject class
    /// </summary>
    /// <param name="driveLetter">This should be the drive letter. Format: F:/, C:/..</param>

    public IntPtr USBEject(string driveLetter)
    {
        string filename = @"\\.\" + driveLetter[0] + ":";
        return CreateFile(filename, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, 0x3, 0, IntPtr.Zero);
    }

    public bool Eject(IntPtr handle)
    {
        bool result = false;

        if (LockVolume(handle) && DismountVolume(handle))
        {
            PreventRemovalOfVolume(handle, false);
            result = AutoEjectVolume(handle);
        }
        CloseHandle(handle);
        return result;
    }

    private bool LockVolume(IntPtr handle)
    {
        uint byteReturned;

        for (int i = 0; i < 10; i++)
        {
            if (DeviceIoControl(handle, FSCTL_LOCK_VOLUME, IntPtr.Zero, 0, IntPtr.Zero, 0, out byteReturned, IntPtr.Zero))
            {
                System.Windows.Forms.MessageBox.Show("Lock success!");
                return true;
            }
            Thread.Sleep(500);
        }
        return false;
    }

    private bool PreventRemovalOfVolume(IntPtr handle, bool prevent)
    {
        byte[] buf = new byte[1];
        uint retVal;

        buf[0] = (prevent) ? (byte)1 : (byte)0;
        return DeviceIoControl(handle, IOCTL_STORAGE_MEDIA_REMOVAL, buf, 1, IntPtr.Zero, 0, out retVal, IntPtr.Zero);
    }

    private bool DismountVolume(IntPtr handle)
    {
        uint byteReturned;
        return DeviceIoControl(handle, FSCTL_DISMOUNT_VOLUME, IntPtr.Zero, 0, IntPtr.Zero, 0, out byteReturned, IntPtr.Zero);
    }

    private bool AutoEjectVolume(IntPtr handle)
    {
        uint byteReturned;
        return DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, IntPtr.Zero, 0, IntPtr.Zero, 0, out byteReturned, IntPtr.Zero);
    }

    private bool CloseVolume(IntPtr handle)
    {
        return CloseHandle(handle);
    }
或直接:

        Eject(USBEject("D:"));

它适用于我的Windows 10计算机(预览版14291)

通过使用Roger Deep的一些代码调用
CreateFile
找到了我的问题的答案

删除WPF窗口内USB驱动器的我的代码:
下面是我从powershell脚本转换的一些代码。您需要以管理员权限运行,它可以“卸载”USB驱动器。但是,当您尝试拔下USB驱动器并再次插入时,它不会显示为驱动器号。(若要解决此问题,您需要键入“WindowsKey-X”并选择磁盘管理器,以将驱动器重新分配给USB设备。(如果有人知道如何解决此问题,请发送到提交。)以下是代码:

// Right click Project and Add Reference to System.Management.dll
using System.Management;

string mq = "SELECT * FROM Win32_Volume Where Name = 'E:\\'"; 
ManagementObjectSearcher ms = new ManagementObjectSearcher(mq);
foreach (ManagementObject mo in ms.Get())
{
    mo["DriveLetter"] = null;
    mo.Put();       
    ManagementBaseObject inParams = mo.GetMethodParameters("Dismount");
    inParams["Force"] = false;  
    inParams["Permanent"] = false;
    mo.InvokeMethod("Dismount", inParams, null);
}
请注意,powershell脚本在弹出后重新连接USB设备时也存在同样的问题。以下是powershell脚本供您参考:

$vol = get-wmiobject -Class Win32_Volume | 
    where{$_.Name -eq 'E:\'}         
$vol.DriveLetter = $null  
$vol.Put()  
$vol.Dismount($false, $false)
下面是我刚刚编写的一个类,用于使用WMI管理可移动USB驱动器的安装和卸载:

using System;
using System.IO;
using System.Text;
using System.Windows;
using System.Management; //<-- right-click on project and add reference
using System.Collections.Generic;
using System.Text.RegularExpressions;

// This Class implements Mount/Unmount for USB Removable Drives
//  in a way similar to "Disk Manager" in the Control Panel.
//
//  Currently, It doesn't implement "Eject" like when you right
//    right-click on the USB icon on lower right of screen.
//    The "Unmount" is similar to "Eject" except it dosn't
//    cleanup the registry so that the USB drive can be automatically
//    recognized again without manually mounting it from "Disk Manager"
//    If somebody knows how to fix this class to gain this function...
//       please post it to their thread.  Thanks.
namespace WPM {

    public struct UsbDriveItem_t {
        public int    Index;
        public string DeviceId;
        public char   DriveLetter;
        public string Label;

        public override string ToString() {
            if (Index < 0)
                return "<none>";
            else 
                return String.Format("{0}: {1}", DriveLetter, Label);
        }               
    };

    delegate void UsbEvent();

    class UsbDriveRemovable {

        public static int Unmount(char DriveLetter) {
            bool success = ValidateAdmin("UsbDriveRemovable.Unmount()");
            if (!success) return -1;

            string Name = "'" + DriveLetter + ":\\\\'";

            string mq   = "SELECT * FROM Win32_Volume Where Name = " + Name;
            ManagementObjectSearcher ms = new ManagementObjectSearcher(mq);
            ManagementObjectCollection mc = ms.Get();
            foreach (ManagementObject mo in mc) {
                var DriveLetterI  = mo["DriveLetter"].ToString();
                mo["DriveLetter"] = null;
                mo.Put();
                ManagementBaseObject inParams = mo.GetMethodParameters("Dismount");
                inParams["Force"] = false;
                inParams["Permanent"] = false;
                ManagementBaseObject outParams = mo.InvokeMethod("Dismount", inParams, null);
                string rc = outParams["ReturnValue"].ToString();
                mo.Dispose();
            }
            mc.Dispose();
            ms.Dispose();
            return 0;
        }

        public static int Mount(string DeviceId, char Letter = '?') {
            bool success = ValidateAdmin("UsbDriveRemovable.Mount()");
            if (!success) return -1;

            if (Letter == '?' || Letter == '#') {
                GetFirstUnsedLetter(out Letter);
            }

            string FixDeviceId = Regex.Replace(DeviceId, @"\\", @"\\");

            string mq = "SELECT * FROM Win32_Volume WHERE DeviceId = '"
                + FixDeviceId
                + "'";

            ManagementObjectSearcher ms = new ManagementObjectSearcher(mq);
            ManagementObjectCollection mc = ms.Get();
            foreach (ManagementObject mo in mc) {
                ManagementBaseObject inParams = mo.GetMethodParameters("AddMountPoint");
                inParams["Directory"] = Letter + ":\\";
                ManagementBaseObject outParams = mo.InvokeMethod("AddMountPoint", inParams, null);
                string rc = outParams["ReturnValue"].ToString();
                mo.Dispose();
            }
            mc.Dispose();
            ms.Dispose();
            return 0;
        }

        /*List<UsbDriveItem_t>*/ 
        public static int ListDrives(ref List<UsbDriveItem_t> DriveList) {
            DriveList.Clear();
            string mq = "SELECT * FROM Win32_Volume Where DriveType = '2'";
            ManagementObjectSearcher ms   = new ManagementObjectSearcher(mq);
            ManagementObjectCollection mc = ms.Get();
            int count = 0;
            foreach (ManagementObject mo in mc) {
                UsbDriveItem_t item = new UsbDriveItem_t();
                item.Index       = count;
                item.Label       = (mo["Label"] == null)       ? "<none>" : mo["Label"].ToString();
                item.DriveLetter = (mo["DriveLetter"] == null) ? '#' : mo["DriveLetter"].ToString()[0];
                item.DeviceId    = (mo["DeviceId"] == null)    ? "<none>" : mo["DeviceId"].ToString();
                DriveList.Add(item);
                mo.Dispose();
            }
            count++;
            mc.Dispose();
            ms.Dispose();

            return 0;
        }

        public static void MountItem(UsbDriveItem_t DriveItem) {            
            char   DriveLetter = DriveItem.DriveLetter;
            string DriveLabel  = DriveItem.Label;
            string DeviceId    = DriveItem.DeviceId;

            // Mount Drive if its not already Mounted
            if (DriveLetter == '#') {
                UsbDriveRemovable.GetFirstUnsedLetter(out DriveLetter);
                UsbDriveRemovable.Mount(DeviceId, DriveLetter);
            }
            return; 
        }

        public static void UnmountItem(UsbDriveItem_t DriveItem) {      
            char   DriveLetter = DriveItem.DriveLetter;         
            UsbDriveRemovable.Unmount(DriveLetter);
            return;
        }

        public static int GetFirstUnsedLetter(out char Letter) {
            bool[] alphabet = new bool[26];

            for (int i=0; i < 26; i++) {
                alphabet[i] = false;
            }

            string mq = "SELECT * FROM Win32_Volume";
            ManagementObjectSearcher ms   = new ManagementObjectSearcher(mq);
            ManagementObjectCollection mc = ms.Get();
            foreach (ManagementObject mo in mc) {
                if (mo["DriveLetter"] != null) {
                    char cc      = mo["DriveLetter"].ToString()[0];
                    int  ci      = char.ToUpper(cc) - 65;
                    alphabet[ci] = true;
                }
                mo.Dispose();
            }
            mc.Dispose();
            ms.Dispose();

            int found = -1;
            for (int i=3; i < 26; i++) {
                if (alphabet[i] == false) {
                    found = i;
                    break;
                }
            }

            if (found >= 0) {
                Letter = (char)(found + 65);
                return 0;
            }
            else {
                Letter = '?';
                return -1;
            }
        }


        public static object
            RegisterInsertEvent(UsbEvent InsertEvent) {
            var insertQuery = new WqlEventQuery("SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 2");
            var insertWatcher = new ManagementEventWatcher(insertQuery);            
            insertWatcher.EventArrived += delegate(object sender, EventArrivedEventArgs e) {
                // string driveName = e.NewEvent.Properties["DriveName"].Value.ToString();              
                Action action = delegate {
                    InsertEvent();
                };
                Application.Current.Dispatcher.BeginInvoke(action);
            };
            insertWatcher.Start();
            return (object)insertWatcher;
        }

        public static object RegisterRemoveEvent(UsbEvent RemoveEvent) {
            var removeQuery = new WqlEventQuery("SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 3");
            var removeWatcher = new ManagementEventWatcher(removeQuery);
            removeWatcher.EventArrived += delegate(object sender, EventArrivedEventArgs e) {
                // string driveName = e.NewEvent.Properties["DriveName"].Value.ToString();              
                Action action = delegate {                  
                    RemoveEvent();
                };
                Application.Current.Dispatcher.BeginInvoke(action);
            };
            removeWatcher.Start();
            return (object)removeWatcher;
        }

        // Mount all UsbRemovable Drives that are not currently mounted
        public static int MountAll() {
            List<UsbDriveItem_t> DriveList = new List<UsbDriveItem_t>();
            ListDrives(ref DriveList);

            foreach (UsbDriveItem_t item in DriveList) {
                if (item.DriveLetter == '?') {
                    Mount(item.DeviceId);
                }
            }
            return 0;
        }

        // Unmount all UsbRemovable Drives
        public static int UnmountAll() {
            List<UsbDriveItem_t> DriveList = new List<UsbDriveItem_t>();
            ListDrives(ref DriveList);

            foreach (UsbDriveItem_t item in DriveList) {
                if (item.DriveLetter != '?') {
                    Unmount(item.DriveLetter);
                }
            }
            return 0;
        }

        public static bool IsAdministrator()
        {
            var id   = System.Security.Principal.WindowsIdentity.GetCurrent();
            var prin = new System.Security.Principal.WindowsPrincipal(id);
            return prin.IsInRole(
                System.Security.Principal.WindowsBuiltInRole.Administrator);
        }

        public static bool ValidateAdmin(string CalledFrom = null) {
            if (CalledFrom == null) {
                CalledFrom = "";
            }
            if (!IsAdministrator()) {
                string msg = "Please rerun this application with admin privileges.\r\n\r\n"
                + "Access denied to call " + CalledFrom + "\r\n\r\n";
                MessageBox.Show(msg, "ERROR");
                return false;
            }
            return true;
        }

        public static void StartExplorer(char DriveLetter) 
        {
            var proc1 = new System.Diagnostics.Process();
            proc1.StartInfo.FileName               = @"C:\\Windows\\System32\\explorer.exe";
            proc1.StartInfo.Arguments              = DriveLetter.ToString();
            proc1.StartInfo.CreateNoWindow         = true;
            proc1.StartInfo.UseShellExecute        = false;
            proc1.StartInfo.RedirectStandardOutput = true;
            proc1.StartInfo.RedirectStandardError  = true;
            proc1.Start();
            proc1.WaitForExit();
            string proc1out = proc1.StandardOutput.ReadToEnd();
            string proc1err = proc1.StandardError.ReadToEnd();
            //if (proc1.ExitCode != 0) {
            //  string msg = proc1out + "\r\n\r\n" + proc1err;
            //  MessageBox.Show(msg, "Error: Mountvol /R");
            //}
            proc1.Close();                  
        }       

    } //class
} //namespace



/*  DOESN'T WORK WELL...

        // Kludge to get USB Drive to be recognized again
        void UsbCleanup() {
            var proc1 = new System.Diagnostics.Process();
            proc1.StartInfo.FileName               = @"C:\\Windows\\System32\\mountvol.exe";
            proc1.StartInfo.Arguments              = @"/R";
            proc1.StartInfo.CreateNoWindow         = true;
            proc1.StartInfo.UseShellExecute        = false;
            proc1.StartInfo.RedirectStandardOutput = true;
            proc1.StartInfo.RedirectStandardError  = true;
            proc1.Start();
            proc1.WaitForExit();
            string proc1out = proc1.StandardOutput.ReadToEnd();
            string proc1err = proc1.StandardError.ReadToEnd();
            if (proc1.ExitCode != 0) {
                string msg = proc1out + "\r\n\r\n" + proc1err;
                MessageBox.Show(msg, "Error: Mountvol /R");
            }
            proc1.Close();

            var proc2 = new System.Diagnostics.Process();
            proc2.StartInfo.FileName               = @"C:\\Windows\\System32\\mountvol.exe";
            proc2.StartInfo.Arguments              = @"/E";
            proc2.StartInfo.CreateNoWindow         = true;
            proc2.StartInfo.UseShellExecute        = false;
            proc2.StartInfo.RedirectStandardOutput = true;
            proc2.StartInfo.RedirectStandardError  = true;
            proc2.Start();
            proc2.WaitForExit();
            string proc2out = proc2.StandardOutput.ReadToEnd();
            string proc2err = proc2.StandardError.ReadToEnd();
            if (proc2.ExitCode != 0) {
                string msg = proc1out + "\r\n\r\n" + proc1err;
                MessageBox.Show(msg, "Error: Mountvol /E");
            }
            proc2.Close();
            return;
        }
*/
使用系统;
使用System.IO;
使用系统文本;
使用System.Windows;
使用System.Management;//=0){
字母=(字符)(发现+65);
返回0;
}
否则{
字母='?';
返回-1;
}
}
公共静态对象
RegisterInsertEvent(UsbEvent InsertEvent){
var insertQuery=new WqlEventQuery(“从Win32_DeviceChangeEvent中选择*,其中EventType=2”);
var insertWatcher=新的ManagementEventWatcher(insertQuery);
insertWatcher.EventArrived+=委托(对象发送方,EventArrivedEventArgs e){
//string driveName=e.NewEvent.Properties[“driveName”].Value.ToString();
动作=委托{
InsertEvent();
};
Application.Current.Dispatcher.BeginInvoke(操作);
};
insertWatcher.Start();
返回(对象)insertWatcher;
$vol = get-wmiobject -Class Win32_Volume | 
    where{$_.Name -eq 'E:\'}         
$vol.DriveLetter = $null  
$vol.Put()  
$vol.Dismount($false, $false)
using System;
using System.IO;
using System.Text;
using System.Windows;
using System.Management; //<-- right-click on project and add reference
using System.Collections.Generic;
using System.Text.RegularExpressions;

// This Class implements Mount/Unmount for USB Removable Drives
//  in a way similar to "Disk Manager" in the Control Panel.
//
//  Currently, It doesn't implement "Eject" like when you right
//    right-click on the USB icon on lower right of screen.
//    The "Unmount" is similar to "Eject" except it dosn't
//    cleanup the registry so that the USB drive can be automatically
//    recognized again without manually mounting it from "Disk Manager"
//    If somebody knows how to fix this class to gain this function...
//       please post it to their thread.  Thanks.
namespace WPM {

    public struct UsbDriveItem_t {
        public int    Index;
        public string DeviceId;
        public char   DriveLetter;
        public string Label;

        public override string ToString() {
            if (Index < 0)
                return "<none>";
            else 
                return String.Format("{0}: {1}", DriveLetter, Label);
        }               
    };

    delegate void UsbEvent();

    class UsbDriveRemovable {

        public static int Unmount(char DriveLetter) {
            bool success = ValidateAdmin("UsbDriveRemovable.Unmount()");
            if (!success) return -1;

            string Name = "'" + DriveLetter + ":\\\\'";

            string mq   = "SELECT * FROM Win32_Volume Where Name = " + Name;
            ManagementObjectSearcher ms = new ManagementObjectSearcher(mq);
            ManagementObjectCollection mc = ms.Get();
            foreach (ManagementObject mo in mc) {
                var DriveLetterI  = mo["DriveLetter"].ToString();
                mo["DriveLetter"] = null;
                mo.Put();
                ManagementBaseObject inParams = mo.GetMethodParameters("Dismount");
                inParams["Force"] = false;
                inParams["Permanent"] = false;
                ManagementBaseObject outParams = mo.InvokeMethod("Dismount", inParams, null);
                string rc = outParams["ReturnValue"].ToString();
                mo.Dispose();
            }
            mc.Dispose();
            ms.Dispose();
            return 0;
        }

        public static int Mount(string DeviceId, char Letter = '?') {
            bool success = ValidateAdmin("UsbDriveRemovable.Mount()");
            if (!success) return -1;

            if (Letter == '?' || Letter == '#') {
                GetFirstUnsedLetter(out Letter);
            }

            string FixDeviceId = Regex.Replace(DeviceId, @"\\", @"\\");

            string mq = "SELECT * FROM Win32_Volume WHERE DeviceId = '"
                + FixDeviceId
                + "'";

            ManagementObjectSearcher ms = new ManagementObjectSearcher(mq);
            ManagementObjectCollection mc = ms.Get();
            foreach (ManagementObject mo in mc) {
                ManagementBaseObject inParams = mo.GetMethodParameters("AddMountPoint");
                inParams["Directory"] = Letter + ":\\";
                ManagementBaseObject outParams = mo.InvokeMethod("AddMountPoint", inParams, null);
                string rc = outParams["ReturnValue"].ToString();
                mo.Dispose();
            }
            mc.Dispose();
            ms.Dispose();
            return 0;
        }

        /*List<UsbDriveItem_t>*/ 
        public static int ListDrives(ref List<UsbDriveItem_t> DriveList) {
            DriveList.Clear();
            string mq = "SELECT * FROM Win32_Volume Where DriveType = '2'";
            ManagementObjectSearcher ms   = new ManagementObjectSearcher(mq);
            ManagementObjectCollection mc = ms.Get();
            int count = 0;
            foreach (ManagementObject mo in mc) {
                UsbDriveItem_t item = new UsbDriveItem_t();
                item.Index       = count;
                item.Label       = (mo["Label"] == null)       ? "<none>" : mo["Label"].ToString();
                item.DriveLetter = (mo["DriveLetter"] == null) ? '#' : mo["DriveLetter"].ToString()[0];
                item.DeviceId    = (mo["DeviceId"] == null)    ? "<none>" : mo["DeviceId"].ToString();
                DriveList.Add(item);
                mo.Dispose();
            }
            count++;
            mc.Dispose();
            ms.Dispose();

            return 0;
        }

        public static void MountItem(UsbDriveItem_t DriveItem) {            
            char   DriveLetter = DriveItem.DriveLetter;
            string DriveLabel  = DriveItem.Label;
            string DeviceId    = DriveItem.DeviceId;

            // Mount Drive if its not already Mounted
            if (DriveLetter == '#') {
                UsbDriveRemovable.GetFirstUnsedLetter(out DriveLetter);
                UsbDriveRemovable.Mount(DeviceId, DriveLetter);
            }
            return; 
        }

        public static void UnmountItem(UsbDriveItem_t DriveItem) {      
            char   DriveLetter = DriveItem.DriveLetter;         
            UsbDriveRemovable.Unmount(DriveLetter);
            return;
        }

        public static int GetFirstUnsedLetter(out char Letter) {
            bool[] alphabet = new bool[26];

            for (int i=0; i < 26; i++) {
                alphabet[i] = false;
            }

            string mq = "SELECT * FROM Win32_Volume";
            ManagementObjectSearcher ms   = new ManagementObjectSearcher(mq);
            ManagementObjectCollection mc = ms.Get();
            foreach (ManagementObject mo in mc) {
                if (mo["DriveLetter"] != null) {
                    char cc      = mo["DriveLetter"].ToString()[0];
                    int  ci      = char.ToUpper(cc) - 65;
                    alphabet[ci] = true;
                }
                mo.Dispose();
            }
            mc.Dispose();
            ms.Dispose();

            int found = -1;
            for (int i=3; i < 26; i++) {
                if (alphabet[i] == false) {
                    found = i;
                    break;
                }
            }

            if (found >= 0) {
                Letter = (char)(found + 65);
                return 0;
            }
            else {
                Letter = '?';
                return -1;
            }
        }


        public static object
            RegisterInsertEvent(UsbEvent InsertEvent) {
            var insertQuery = new WqlEventQuery("SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 2");
            var insertWatcher = new ManagementEventWatcher(insertQuery);            
            insertWatcher.EventArrived += delegate(object sender, EventArrivedEventArgs e) {
                // string driveName = e.NewEvent.Properties["DriveName"].Value.ToString();              
                Action action = delegate {
                    InsertEvent();
                };
                Application.Current.Dispatcher.BeginInvoke(action);
            };
            insertWatcher.Start();
            return (object)insertWatcher;
        }

        public static object RegisterRemoveEvent(UsbEvent RemoveEvent) {
            var removeQuery = new WqlEventQuery("SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 3");
            var removeWatcher = new ManagementEventWatcher(removeQuery);
            removeWatcher.EventArrived += delegate(object sender, EventArrivedEventArgs e) {
                // string driveName = e.NewEvent.Properties["DriveName"].Value.ToString();              
                Action action = delegate {                  
                    RemoveEvent();
                };
                Application.Current.Dispatcher.BeginInvoke(action);
            };
            removeWatcher.Start();
            return (object)removeWatcher;
        }

        // Mount all UsbRemovable Drives that are not currently mounted
        public static int MountAll() {
            List<UsbDriveItem_t> DriveList = new List<UsbDriveItem_t>();
            ListDrives(ref DriveList);

            foreach (UsbDriveItem_t item in DriveList) {
                if (item.DriveLetter == '?') {
                    Mount(item.DeviceId);
                }
            }
            return 0;
        }

        // Unmount all UsbRemovable Drives
        public static int UnmountAll() {
            List<UsbDriveItem_t> DriveList = new List<UsbDriveItem_t>();
            ListDrives(ref DriveList);

            foreach (UsbDriveItem_t item in DriveList) {
                if (item.DriveLetter != '?') {
                    Unmount(item.DriveLetter);
                }
            }
            return 0;
        }

        public static bool IsAdministrator()
        {
            var id   = System.Security.Principal.WindowsIdentity.GetCurrent();
            var prin = new System.Security.Principal.WindowsPrincipal(id);
            return prin.IsInRole(
                System.Security.Principal.WindowsBuiltInRole.Administrator);
        }

        public static bool ValidateAdmin(string CalledFrom = null) {
            if (CalledFrom == null) {
                CalledFrom = "";
            }
            if (!IsAdministrator()) {
                string msg = "Please rerun this application with admin privileges.\r\n\r\n"
                + "Access denied to call " + CalledFrom + "\r\n\r\n";
                MessageBox.Show(msg, "ERROR");
                return false;
            }
            return true;
        }

        public static void StartExplorer(char DriveLetter) 
        {
            var proc1 = new System.Diagnostics.Process();
            proc1.StartInfo.FileName               = @"C:\\Windows\\System32\\explorer.exe";
            proc1.StartInfo.Arguments              = DriveLetter.ToString();
            proc1.StartInfo.CreateNoWindow         = true;
            proc1.StartInfo.UseShellExecute        = false;
            proc1.StartInfo.RedirectStandardOutput = true;
            proc1.StartInfo.RedirectStandardError  = true;
            proc1.Start();
            proc1.WaitForExit();
            string proc1out = proc1.StandardOutput.ReadToEnd();
            string proc1err = proc1.StandardError.ReadToEnd();
            //if (proc1.ExitCode != 0) {
            //  string msg = proc1out + "\r\n\r\n" + proc1err;
            //  MessageBox.Show(msg, "Error: Mountvol /R");
            //}
            proc1.Close();                  
        }       

    } //class
} //namespace



/*  DOESN'T WORK WELL...

        // Kludge to get USB Drive to be recognized again
        void UsbCleanup() {
            var proc1 = new System.Diagnostics.Process();
            proc1.StartInfo.FileName               = @"C:\\Windows\\System32\\mountvol.exe";
            proc1.StartInfo.Arguments              = @"/R";
            proc1.StartInfo.CreateNoWindow         = true;
            proc1.StartInfo.UseShellExecute        = false;
            proc1.StartInfo.RedirectStandardOutput = true;
            proc1.StartInfo.RedirectStandardError  = true;
            proc1.Start();
            proc1.WaitForExit();
            string proc1out = proc1.StandardOutput.ReadToEnd();
            string proc1err = proc1.StandardError.ReadToEnd();
            if (proc1.ExitCode != 0) {
                string msg = proc1out + "\r\n\r\n" + proc1err;
                MessageBox.Show(msg, "Error: Mountvol /R");
            }
            proc1.Close();

            var proc2 = new System.Diagnostics.Process();
            proc2.StartInfo.FileName               = @"C:\\Windows\\System32\\mountvol.exe";
            proc2.StartInfo.Arguments              = @"/E";
            proc2.StartInfo.CreateNoWindow         = true;
            proc2.StartInfo.UseShellExecute        = false;
            proc2.StartInfo.RedirectStandardOutput = true;
            proc2.StartInfo.RedirectStandardError  = true;
            proc2.Start();
            proc2.WaitForExit();
            string proc2out = proc2.StandardOutput.ReadToEnd();
            string proc2err = proc2.StandardError.ReadToEnd();
            if (proc2.ExitCode != 0) {
                string msg = proc1out + "\r\n\r\n" + proc1err;
                MessageBox.Show(msg, "Error: Mountvol /E");
            }
            proc2.Close();
            return;
        }
*/
$Eject = New-Object -comObject Shell.Application
$Eject.NameSpace(17).ParseName($usbDrvLetter+“:”).InvokeVerb(“Eject”)