2015-10-02 10 views
2

Глядя на некоторые советы о том, как я могу добиться следующего:Детектирование если конкретный USB подключен

Я в настоящее время строит # приложения WPF C и я хочу добавить, где приложение при запуске проверки, если конкретный usb прилагается к любому порту USB , и если приложение не может взаимодействовать до тех пор, пока указанный USB не будет подключен?

любые идеи о том, как это можно сделать?

+2

Попробуйте взглянуть на это сообщение http://stackoverflow.com/questions/3685615/usb-device-connected – bgura

ответ

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.

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

     } 
    } 

Мы также устанавливаем DataContext из MainWindow к экземпляру модели представления демонстрационной определенному впоследствии:

namespace TestPopWpfWindow 
{ 

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

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

    } 
} 

Затем мы определяем модель представления и используем System.Manag ement.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

Смежные вопросы