【问题标题】:Enable & disable devices启用和禁用设备
【发布时间】:2010-09-30 14:03:23
【问题描述】:

我正在尝试禁用然后启用 USB 设备 - 就像您可以在设备管理器中执行的操作一样。 我已经尝试使用 devcon.exe 并且它运行良好,除了设备已经或正在使用时。 在这种情况下,它会告诉我重新启动系统后设备将被禁用。 我不想重启系统!! 随后我的问题是:是否可以强制禁用 USB 设备或伪造重启(可能通过重启一些服务)。

感谢您的帮助 约翰

【问题讨论】:

    标签: windows wmi


    【解决方案1】:

    这里有一些代码可以根据您的需要进行修改。

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Management;
    
    namespace DeviceMonitor.Event
    {
     /// <summary>Media watcher delegate.</summary>
     /// <param name="sender"></param>
     /// <param name="driveStatus"></param>
     public delegate void MediaWatcherEventHandler( object sender, DeviceMonitor.Event.MediaEvent.DriveStatus driveStatus );
     /// <summary>Class to monitor devices.</summary>
     public class MediaEvent
     {
      #region Variables
    
      /*------------------------------------------------------------------------*/
      private string m_logicalDrive;
      private ManagementEventWatcher m_managementEventWatcher = null;
      /*------------------------------------------------------------------------*/
      #endregion
    
      #region Events
      /*------------------------------------------------------------------------*/
      public event MediaWatcherEventHandler MediaWatcher;
      /*------------------------------------------------------------------------*/
      #endregion
    
    
      #region Enums
      /*------------------------------------------------------------------------*/
      /// <summary>The drive types.</summary>
      public enum DriveType
      {
       Unknown = 0,
       NoRootDirectory = 1,
       RemoveableDisk  = 2,
       LocalDisk       = 3,
       NetworkDrive    = 4,
       CompactDisk     = 5,
       RamDisk         = 6
      }
    
      /// <summary>The drive status.</summary>
      public enum DriveStatus
      {
       Unknown  = -1,
       Ejected  = 0,
       Inserted = 1,
      }
      /*-----------------------------------------------------------------------*/
      #endregion
    
    
      #region Monitoring
      /*-----------------------------------------------------------------------*/
      /// <summary>Starts the monitoring of device.</summary>
      /// <param name="path"></param>
      /// <param name="mediaEvent"></param>
      public void Monitor( string path, MediaEvent mediaEvent ) {
       if( null == mediaEvent ) {
        throw new ArgumentException( "Media event cannot be null!" );
       }
    
       //In case same class was called make sure only one instance is running
       /////////////////////////////////////////////////////////////
       this.Exit();
    
       //Keep logica drive to check
       /////////////////////////////////////////////////////////////
       this.m_logicalDrive = this.GetLogicalDrive( path );
    
       WqlEventQuery wql;
       ManagementOperationObserver observer = new
           ManagementOperationObserver();
    
       //Bind to local machine
       /////////////////////////////////////////////////////////////
       ConnectionOptions opt = new ConnectionOptions();
    
       //Sets required privilege
       /////////////////////////////////////////////////////////////
       opt.EnablePrivileges = true;
       ManagementScope scope = new ManagementScope( "root\\CIMV2", opt );
    
       try {
        wql = new WqlEventQuery();
        wql.EventClassName = "__InstanceModificationEvent";
        wql.WithinInterval = new TimeSpan( 0, 0, 1 );
    
        wql.Condition = String.Format( @"TargetInstance ISA 'Win32_LogicalDisk' and TargetInstance.DeviceId = '{0}'", this.m_logicalDrive );
        this.m_managementEventWatcher = new ManagementEventWatcher( scope, wql );
    
        //Register async. event handler
        /////////////////////////////////////////////////////////////
        this.m_managementEventWatcher.EventArrived += new EventArrivedEventHandler( mediaEvent.MediaEventArrived );
        this.m_managementEventWatcher.Start();
       } catch( Exception e ) {
        this.Exit();
        throw new Exception( "Media Check: "  + e.Message );
       }
      }
    
      /// <summary>Stops the monitoring of device.</summary>
      public void Exit( ) {
       //In case same class was called make sure only one instance is running
       /////////////////////////////////////////////////////////////
       if( null != this.m_managementEventWatcher ) {
        try {
         this.m_managementEventWatcher.Stop();
         this.m_managementEventWatcher = null;
        } catch {
        }
       }
      }
      /*-----------------------------------------------------------------------*/
      #endregion
    
    
      #region Helpers
      /*-----------------------------------------------------------------------*/
    
      private DriveStatus m_driveStatus = DriveStatus.Unknown;
      /// <summary>Triggers the event when change on device occured.</summary>
      /// <param name="sender"></param>
      /// <param name="e"></param>
      private void MediaEventArrived( object sender, EventArrivedEventArgs e ) {
       // Get the Event object and display it
       PropertyData pd = e.NewEvent.Properties["TargetInstance"];
       DriveStatus driveStatus = this.m_driveStatus;
       if( pd != null ) {
        ManagementBaseObject mbo = pd.Value as ManagementBaseObject;
        System.IO.DriveInfo info = new System.IO.DriveInfo( (string)mbo.Properties["DeviceID"].Value );
        driveStatus = info.IsReady ? DriveStatus.Inserted : DriveStatus.Ejected;
       }
    
       if( driveStatus != this.m_driveStatus ){
        this.m_driveStatus = driveStatus;
        if( null != MediaWatcher ) {
         MediaWatcher( sender, driveStatus );
        }
       }
      }
    
    
      /// <summary>Gets the logical drive of a given path.</summary>
      /// <param name="path"></param>
      /// <returns></returns>
      private string GetLogicalDrive( string path ) {
       System.IO.DirectoryInfo dirInfo = new System.IO.DirectoryInfo( path );
       string root = dirInfo.Root.FullName;
       string logicalDrive = root.Remove( root.IndexOf( System.IO.Path.DirectorySeparatorChar ) );
       return logicalDrive;
      }
      /*-----------------------------------------------------------------------*/
      #endregion
     }
    }
    

    我在 MSDN 上找到了这个:

    http://social.msdn.microsoft.com/forums/en-US/csharpgeneral/thread/09912cee-4d2d-4efd-82a0-da20024b868b/

    【讨论】:

      【解决方案2】:

      设备管理器和devcon.exe使用的函数是SetupDiChangeState

      但您的问题似乎与正在使用的设备有关,而不是与禁用它的细节有关。有像oh.exe(列出打开的句柄)这样的工具可以帮助找出需要关闭的应用程序,它们是通过将未记录的标志传递给NtQueryInformationProcess来实现的。

      【讨论】:

        【解决方案3】:

        您可能想尝试更简单的解决方法:设备管理 Powershell cmdlet。 微软在这里有一个很好的描述:https://gallery.technet.microsoft.com/Device-Management-7fad2388 易于设置模块并使用公开的 cmdlet。

        Get-Device cmdlet 告诉您有关设备状态的信息。 Enable-Device 和 Disable-Device 是一个用于启用/禁用任何 (USB) 设备的线性 cmdlet。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-12-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多