C# 检测是否连接了特定的USB

C# 检测是否连接了特定的USB,c#,wpf,C#,Wpf,寻求有关如何实现以下目标的建议: 我目前正在构建一个C#wpf应用程序,我想添加应用程序在启动时的位置,检查是否连接了特定的usb端口 如果没有,在连接usb之前,应用程序无法交互 关于如何做到这一点有什么想法吗?这里有一篇文章解释了如何获得所有当前连接的USB设备的列表 我们可以使用System.IO.DriveInfo类检索系统上的所有驱动器,并查找驱动器类型可移动的驱动器。此外,可移动驱动器(通常为USB)必须准备就绪,因为该属性已准备就绪,可以访问该驱动器 首先,我们定义一个提供程序来

寻求有关如何实现以下目标的建议:

我目前正在构建一个C#wpf应用程序,我想添加应用程序在启动时的位置,检查是否连接了特定的usb端口 如果没有,在连接usb之前,应用程序无法交互


关于如何做到这一点有什么想法吗?

这里有一篇文章解释了如何获得所有当前连接的USB设备的列表

我们可以使用System.IO.DriveInfo类检索系统上的所有驱动器,并查找驱动器类型可移动的驱动器。此外,可移动驱动器(通常为USB)必须准备就绪,因为该属性已准备就绪,可以访问该驱动器

首先,我们定义一个提供程序来检索可移动驱动器:

  using System.Collections.Generic;
    using System.IO;
    using System.Linq;

    namespace TestPopWpfWindow
    {

    public static class UsbDriveListProvider
    {


        public static IEnumerable<DriveInfo> GetAllRemovableDrives()
        {
            var driveInfos = DriveInfo.GetDrives().AsEnumerable();
            driveInfos = driveInfos.Where(drive => drive.DriveType == DriveType.Removable);
            return driveInfos;
        }

    }
}
实现ICommand也很方便:

使用系统;
使用System.Windows.Input;
命名空间TestPopWpfWindow
{
公共类中继命令:ICommand
{
私有谓词_canExecute;
私人行动——执行;
公共RelayCommand(谓词canExecute、操作execute)
{
_canExecute=canExecute;
_执行=执行;
}
公共布尔CanExecute(对象参数)
{
返回_canExecute(参数);
}
公共事件处理程序CanExecuteChanged;
public void Execute(对象参数)
{
_执行(参数);
}
}
}
我们还将MainWindow的DataContext设置为随后定义的演示视图模型的实例:

namespace TestPopWpfWindow
{

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {

        public MainWindow()
        {
            InitializeComponent();
            DataContext = new UsbDriveInfoDemoViewModel();
        }

    }
}
命名空间TestPopWpfWindow
{
/// 
///MainWindow.xaml的交互逻辑
/// 
公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
DataContext=新的usbdriveinfo demoviewmodel();
}
}
}
然后,我们定义视图模型本身,并使用System.Management.ManagementEventWatcher查找安装到系统上的驱动器中的更改

  using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.IO;
    using System.Management;
    using System.Windows;
    using System.Windows.Input;

    namespace TestPopWpfWindow
    {

        public class UsbDriveInfoDemoViewModel : ViewModelBase, IDisposable
        {

            public UsbDriveInfoDemoViewModel()
            {
                DriveInfos = new List<DriveInfo>();
                ReloadDriveInfos();
                RegisterManagementEventWatching(); 
                TargetUsbDrive = @"E:\"; 
                AccessCommand = new RelayCommand(x => true, x => MessageBox.Show("Functionality executed."));
            }

            public int UsbDriveCount { get; set; }

            private string _targetUsbDrive;

            public string TargetUsbDrive
            {
                get { return _targetUsbDrive; }
                set
                {
                    if (_targetUsbDrive != value)
                    {
                        _targetUsbDrive = value; 
                        RaisePropertyChanged("TargetUsbDrive");
                        RaisePropertyChanged("DriveInfo");
                    }
                }
            }

            public ICommand AccessCommand { get; set; }

            private void ReloadDriveInfos()
            {
                var usbDrives = UsbDriveListProvider.GetAllRemovableDrives();

                Application.Current.Dispatcher.Invoke(() =>
                {
                    DriveInfos.Clear();

                    foreach (var usbDrive in usbDrives)
                    {
                        DriveInfos.Add(usbDrive);
                    }
                    UsbDriveCount = DriveInfos.Count;
                    RaisePropertyChanged("UsbDriveCount");
                    RaisePropertyChanged("DriveInfos");
                }); 
            }

            public List<DriveInfo> DriveInfos { get; set; }

            private ManagementEventWatcher _watcher;

            private void RegisterManagementEventWatching()
            {
                _watcher = new ManagementEventWatcher();
                var query = new WqlEventQuery("SELECT * FROM Win32_VolumeChangeEvent");
                _watcher.EventArrived += watcher_EventArrived;
                _watcher.Query = query;
                _watcher.Start();
            }

            private void watcher_EventArrived(object sender, EventArrivedEventArgs e)
            {
                Debug.WriteLine(e.NewEvent);
                ReloadDriveInfos();
            }



            public void Dispose()
            {
                if (_watcher != null)
                {
                    _watcher.Stop();
                    _watcher.EventArrived -= watcher_EventArrived;
                }
            }

        }

    }
使用系统;
使用System.Collections.Generic;
使用系统诊断;
使用System.IO;
使用制度管理;
使用System.Windows;
使用System.Windows.Input;
命名空间TestPopWpfWindow
{
公共类usbdriveinfo demoviewmodel:ViewModelBase,IDisposable
{
public usbdriveinfo demoviewmodel()
{
DriveInfos=新列表();
重新加载driveinfos();
RegisterManagementEventWatching();
TargetUsbDrive=@“E:\”;
AccessCommand=newrelaycommand(x=>true,x=>MessageBox.Show(“已执行的功能”);
}
public int UsbDriveCount{get;set;}
私有字符串_targetUsbDrive;
公共字符串TargetUsbDrive
{
获取{return\u targetUsbDrive;}
设置
{
如果(_targetUsbDrive!=值)
{
_targetUsbDrive=值;
RaisePropertyChanged(“TargetUsbDrive”);
RaisePropertyChanged(“DriveInfo”);
}
}
}
公共ICommand访问命令{get;set;}
私有void重载driveinfos()
{
var usbDrives=UsbDriveListProvider.GetAllRemovableDrives();
Application.Current.Dispatcher.Invoke(()=>
{
DriveInfos.Clear();
foreach(usbDrives中的var usbDrive)
{
DriveInfos.Add(usbDrive);
}
UsbDriveCount=DriveInfos.Count;
RaisePropertyChanged(“UsbDriveCount”);
RaisePropertyChanged(“DriveInfos”);
}); 
}
公共列表驱动器信息{get;set;}
私人管理EventWatcher\u watcher;
私有无效注册表管理事件监视()
{
_watcher=新的ManagementEventWatcher();
var query=new WqlEventQuery(“从Win32_VolumeChangeEvent中选择*);
_watcher.eventArrized+=watcher\u eventArrized;
_watcher.Query=Query;
_watcher.Start();
}
私有无效观察者\u EventArrived(对象发送者,EventArrivedEventArgs e)
{
Debug.WriteLine(e.NewEvent);
重新加载driveinfos();
}
公共空间处置()
{
如果(_watcher!=null)
{
_watcher.Stop();
_watcher.eventArrized-=watcher\u eventArrized;
}
}
}
}
我们还定义了一个WPF multi converter来启用按钮:

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Windows.Data;

namespace TestPopWpfWindow
{

    public class UsbDriveAvailableEnablerConverter : IMultiValueConverter
    {

        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            if (values == null || values.Count() != 2)
                return false;

            var driveInfos = values[1] as List<DriveInfo>;
            var targetDrive = values[0] as string; 
            if (driveInfos == null || !driveInfos.Any() || string.IsNullOrEmpty(targetDrive))
                return false;
            return driveInfos.Any(d => d.IsReady && d.Name == targetDrive);
        }




        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}
使用系统;
使用System.Collections.Generic;
利用制度全球化;
使用System.IO;
使用System.Linq;
使用System.Windows.Data;
命名空间TestPopWpfWindow
{
公共类UsbDriveAvailableEnablerConverter:IMultiValueConverter
{
公共对象转换(对象[]值,类型targetType,对象参数,CultureInfo区域性)
{
if(values==null | | values.Count()!=2)
返回false;
var driveInfos=列表中的值[1];
var targetDrive=字符串形式的值[0];
if(driveInfos==null | | |!driveInfos.Any()| | | string.IsNullOrEmpty(targetDrive))
返回false;
返回driveInfos.Any(d=>d.IsReady&&d.Name==targetDrive);
}
公共对象[]转换回(对象值,类型[]目标类型,对象参数,CultureInfo区域性)
{
抛出新的NotImplementedException();
}
}
  using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.IO;
    using System.Management;
    using System.Windows;
    using System.Windows.Input;

    namespace TestPopWpfWindow
    {

        public class UsbDriveInfoDemoViewModel : ViewModelBase, IDisposable
        {

            public UsbDriveInfoDemoViewModel()
            {
                DriveInfos = new List<DriveInfo>();
                ReloadDriveInfos();
                RegisterManagementEventWatching(); 
                TargetUsbDrive = @"E:\"; 
                AccessCommand = new RelayCommand(x => true, x => MessageBox.Show("Functionality executed."));
            }

            public int UsbDriveCount { get; set; }

            private string _targetUsbDrive;

            public string TargetUsbDrive
            {
                get { return _targetUsbDrive; }
                set
                {
                    if (_targetUsbDrive != value)
                    {
                        _targetUsbDrive = value; 
                        RaisePropertyChanged("TargetUsbDrive");
                        RaisePropertyChanged("DriveInfo");
                    }
                }
            }

            public ICommand AccessCommand { get; set; }

            private void ReloadDriveInfos()
            {
                var usbDrives = UsbDriveListProvider.GetAllRemovableDrives();

                Application.Current.Dispatcher.Invoke(() =>
                {
                    DriveInfos.Clear();

                    foreach (var usbDrive in usbDrives)
                    {
                        DriveInfos.Add(usbDrive);
                    }
                    UsbDriveCount = DriveInfos.Count;
                    RaisePropertyChanged("UsbDriveCount");
                    RaisePropertyChanged("DriveInfos");
                }); 
            }

            public List<DriveInfo> DriveInfos { get; set; }

            private ManagementEventWatcher _watcher;

            private void RegisterManagementEventWatching()
            {
                _watcher = new ManagementEventWatcher();
                var query = new WqlEventQuery("SELECT * FROM Win32_VolumeChangeEvent");
                _watcher.EventArrived += watcher_EventArrived;
                _watcher.Query = query;
                _watcher.Start();
            }

            private void watcher_EventArrived(object sender, EventArrivedEventArgs e)
            {
                Debug.WriteLine(e.NewEvent);
                ReloadDriveInfos();
            }



            public void Dispose()
            {
                if (_watcher != null)
                {
                    _watcher.Stop();
                    _watcher.EventArrived -= watcher_EventArrived;
                }
            }

        }

    }
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Windows.Data;

namespace TestPopWpfWindow
{

    public class UsbDriveAvailableEnablerConverter : IMultiValueConverter
    {

        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            if (values == null || values.Count() != 2)
                return false;

            var driveInfos = values[1] as List<DriveInfo>;
            var targetDrive = values[0] as string; 
            if (driveInfos == null || !driveInfos.Any() || string.IsNullOrEmpty(targetDrive))
                return false;
            return driveInfos.Any(d => d.IsReady && d.Name == targetDrive);
        }




        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}
<Window x:Class="TestPopWpfWindow.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:TestPopWpfWindow"
        Title="MainWindow" Height="350" Width="525">

    <Window.Resources>

        <Style x:Key="usbLabel" TargetType="Label">
            <Style.Triggers>
                <DataTrigger Binding="{Binding IsReady}" Value="False">
                    <Setter Property="Background" Value="Gray"></Setter>
                </DataTrigger>
                <DataTrigger Binding="{Binding IsReady}" Value="True">
                    <Setter Property="Background" Value="Green"></Setter>
                </DataTrigger>
            </Style.Triggers>
        </Style>

        <local:UsbDriveAvailableEnablerConverter x:Key="usbDriveAvailableEnablerConverter"></local:UsbDriveAvailableEnablerConverter>

    </Window.Resources>


    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>

        </Grid.RowDefinitions>

        <StackPanel Orientation="Vertical">
            <TextBlock Text="USB Drive-detector" FontWeight="DemiBold" HorizontalAlignment="Center" FontSize="14" Margin="2"></TextBlock>
            <TextBlock Text="Removable drives on the system" FontWeight="Normal" HorizontalAlignment="Center" Margin="2"></TextBlock>
            <TextBlock Text="Drives detected:" FontWeight="Normal" HorizontalAlignment="Center" Margin="2"></TextBlock>
            <TextBlock Text="{Binding UsbDriveCount, UpdateSourceTrigger=PropertyChanged}" FontWeight="Normal" HorizontalAlignment="Center" Margin="2"></TextBlock>

            <ItemsControl Grid.Row="0" ItemsSource="{Binding DriveInfos, UpdateSourceTrigger=PropertyChanged}"
                          Width="100" BorderBrush="Black" BorderThickness="1">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Vertical">
                            <Label Style="{StaticResource usbLabel}" Width="32" Height="32" FontSize="18" Foreground="White" Content="{Binding Name}">
                            </Label>
                        </StackPanel>

                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </StackPanel>

        <Button Grid.Row="1" Height="24" Width="130" VerticalAlignment="Top" Margin="10" Content="Access functionality" Command="{Binding AccessCommand}">
            <Button.IsEnabled>
                <MultiBinding Converter="{StaticResource usbDriveAvailableEnablerConverter}">
                    <MultiBinding.Bindings>
                        <Binding Path="TargetUsbDrive"></Binding>
                        <Binding Path="DriveInfos"></Binding>
                    </MultiBinding.Bindings>
                </MultiBinding>
            </Button.IsEnabled>
        </Button>

        <StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Center">
            <TextBlock Margin="2" Text="Target this USB-drive:"></TextBlock>
            <TextBox Margin="2" Text="{Binding TargetUsbDrive, UpdateSourceTrigger=LostFocus}" Width="100"></TextBox>
        </StackPanel>

    </Grid>

</Window>