启用&禁用设备

发布于 2024-09-26 05:10:22 字数 186 浏览 1 评论 0原文

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

感谢您的帮助 约翰

I am trying to disable then enable a usb device - like you can do in device manager.
I have tried using devcon.exe and it works perfectly, apart from when the device has been or is being used.
Under these circumstances it will tell me that the device will be disabled after restarting the system.
I don’t want the system to be restarted!!
Subsequently my question is: is it possible to force the disabling of a usb device or fake the reboot (maybe by restarting a number of services).

Thanks for your help
John

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

〗斷ホ乔殘χμё〖 2024-10-03 05:10:22

以下是一些可以修改以满足您的需求的代码。

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/

Here is some code that can be modified to accommodate your needs.

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

I found this on MSDN at:

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

为你鎻心 2024-10-03 05:10:22

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

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

The function used by device manager and devcon.exe is SetupDiChangeState.

But it seems like your problem is related to the device being in-use more than the details of disabling it. There are tools like oh.exe (List Open Handles) that could help find out what applications need to be closed, they are implemented by passing undocumented flags to NtQueryInformationProcess.

街角迷惘 2024-10-03 05:10:22

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

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

You might want to try an easier work around : Device Management Powershell cmdlets.
Microsoft has an excellent description here : https://gallery.technet.microsoft.com/Device-Management-7fad2388
Easy to setup the module and work with the exposed cmdlets.

Get-Device cmdlet tells you about device state.
Enable-Device and Disable-Device are one liner cmdlets to enable/disable any (USB) device.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文