检测特定USB是否已连接

时间:2015-10-02 14:48:52

标签: c# wpf

寻找有关如何实现以下目标的一些建议:

我正在构建一个C#wpf应用程序,我想添加启动时应用程序的位置,检查特定的usb是否连接了任何一个usb端口 如果没有,申请人无法进行互动,直到说出来是否附上了?

关于如何做到这一点的任何想法?

2 个答案:

答案 0 :(得分:3)

enter image description here

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

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

  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;
        }

    }
}

让我们也使用MVVM模式,因此我们定义 ViewModelbase 类,实现 INotifyPropertyChanged

使用System.ComponentModel;

namespace TestPopWpfWindow
{

    public class ViewModelBase : INotifyPropertyChanged
    {

        public event PropertyChangedEventHandler PropertyChanged;

        public void RaisePropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }


    }
}

实现 ICommand 的方法也很方便:

 using System;
    using System.Windows.Input;

    namespace TestPopWpfWindow
    {

        public class RelayCommand : ICommand
        {

            private Predicate<object> _canExecute;

            private Action<object> _execute;  


            public RelayCommand(Predicate<object> canExecute, Action<object> execute)
            {
                _canExecute = canExecute;
                _execute = execute;
            }

            public bool CanExecute(object parameter)
            {
                return _canExecute(parameter); 
            }

            public event EventHandler CanExecuteChanged;

            public void Execute(object parameter)
            {
                _execute(parameter); 
            }

        }
    }

我们还将MainWindow的 DataContext 设置为之后定义的演示视图模型的实例:

namespace TestPopWpfWindow
{

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

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

    }
}

然后我们定义视图模型本身并使用 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;
                }
            }

        }

    }

我们还定义了一个WPF多转换器,然后启用按钮:

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();
        }
    }
}

我们定义了一个用于测试此代码的GUI:

<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>

我现在提供了Visual Studio 2013解决方案,上面的代码可在此处下载:

https://onedrive.live.com/redir?resid=8EF5059044F781FC!40934&authkey=!AAkLBdsXTlMMTy4&ithint=file%2czip

答案 1 :(得分:0)

这是一篇解释如何获取所有当前连接的USB设备列表的帖子。

Get List of connected USB Devices