Autor
|
Tema: Detectar cuando la bandeja del lector está abierta o cerrada (Leído 6,253 veces)
|
Meta
|
Hola: Aquí hay un código que pulsando A o C abre o cierras la bandeja del lector, a parte de esto, dice Abierto, Abriendo... Cerrado y Cerrando... Todo esto pulsado las teclas A o C. Me he dado cuenta que si cierro la bandeja directamente con la mano, en la ventana o en el CMD de C#, no lo sabe, se queda en Abierto. La idea es que si cierro la bandeja con la mano, en la pantalla muestre el mensaje. ¿Esto es posible de hacer? using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using static System.Net.Mime.MediaTypeNames;
namespace Lector_teclado_consola_cs { class Program { [DllImport("winmm.dll")] public static extern Int32 mciSendString(string lpstrCommand, StringBuilder lpstrReturnString, int uReturnLength, IntPtr hwndCallback);
public static StringBuilder rt = new StringBuilder(127);
public static void DoEvents() { // Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Background, new ThreadStart(delegate { })); Console.SetCursorPosition(0, 6); Console.Write("Abriendo..."); }
public static void DoEvents2() { // Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Background, new ThreadStart(delegate { })); Console.SetCursorPosition(0, 6); Console.Write("Cerrando..."); }
static void Main(string[] args) { // Título de la ventana. Console.Title = "Control lector de bandeja.";
// Tamaño ventana consola. Console.WindowWidth = 55; // X. Ancho. Console.WindowHeight = 18; // Y. Alto.
// Cursor invisible. Console.CursorVisible = false;
// Posición del mansaje en la ventana. Console.SetCursorPosition(0, 0); Console.Write(@"Control bandeja del lector:
A - Abrir bandeja. C - Cerrar bandeja. ===========================");
ConsoleKey key; //Console.CursorVisible = false; do { key = Console.ReadKey(true).Key;
string mensaje = string.Empty;
//Asignamos la tecla presionada por el usuario switch (key) { case ConsoleKey.A: // mensaje = "Abriendo..."; Console.SetCursorPosition(0, 6); DoEvents(); mciSendString("set CDAudio door open", rt, 127, IntPtr.Zero); mensaje = "Abierto."; break;
case ConsoleKey.C: // mensaje = "Cerrando..."; Console.SetCursorPosition(0, 6); DoEvents2(); mciSendString("set CDAudio door closed", rt, 127, IntPtr.Zero); mensaje = "Cerrado."; break; }
Console.SetCursorPosition(0, 6); Console.Write(" "); Console.SetCursorPosition(0, 6); Console.Write(mensaje);
} while (key != ConsoleKey.Escape); } } } Sólo debo modificar o ampliar esa función que falta para dejar el programa más completo. Saludos.
|
|
|
En línea
|
|
|
|
Eleкtro
Ex-Staff
Desconectado
Mensajes: 9.885
|
Aquí hay un código que pulsando A o C abre o cierras la bandeja del lector, a parte de esto, dice Abierto, Abriendo... Cerrado y Cerrando... Todo esto pulsado las teclas A o C.
Me he dado cuenta que si cierro la bandeja directamente con la mano, en la ventana o en el CMD de C#, no lo sabe, se queda en Abierto. La idea es que si cierro la bandeja con la mano, en la pantalla muestre el mensaje.
¿Esto es posible de hacer? Tu mismo estás diciendo que lo de "Abriendo..." y "Cerrando..." lo estás imprimiendo por ti mismo cuando pulsas la tecla A o C en la CMD... en ningún momento estás controlando eventos de inserción o eyección de la bandeja del lector, ¿cómo esperas que sea posible hacerlo controlando el input de la CMD?, no tiene sentido xD. De todas formas MCI solamente sirve para operar con comandos, no es posible detectar/suscribirse a eventos de inserción y eyección de la bandeja del lector de CD-ROM mediante MCI. Pero si con WMI... Te muestro un ejemplo que escribí hace tiempo en VB.NET y que hace exactamente lo que pides: Imports System.ComponentModel Imports System.Management Public NotInheritable Class Form1 : Inherits Form Private WithEvents EventWatcher As ManagementEventWatcher Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load ' https://msdn.microsoft.com/en-us/library/aa394173%28v=vs.85%29.aspx Dim eventQuery As New WqlEventQuery( eventClassName:="__InstanceModificationEvent", condition:="TargetInstance ISA 'Win32_LogicalDisk' AND TargetInstance.DriveType = 5", withinInterval:=TimeSpan.FromSeconds(1)) Dim eventOptions As New EventWatcherOptions With { .BlockSize = 1, .Timeout = TimeSpan.MaxValue } Dim scopePath As New ManagementPath With { .ClassName = "", .NamespacePath = "root\CIMV2", .Path = "\\.\root\CIMV2", .Server = "." } Dim scopeOptions As New ConnectionOptions With { .Authentication = AuthenticationLevel.Default, .EnablePrivileges = True, .Impersonation = ImpersonationLevel.Impersonate, .Timeout = TimeSpan.MaxValue } Dim scope As New ManagementScope(scopePath, scopeOptions) Me.EventWatcher = New ManagementEventWatcher With { .Options = eventOptions, .Query = eventQuery, .Scope = scope } Me.EventWatcher.Scope.Connect() Me.EventWatcher.Start() End Sub Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing Me.EventWatcher.Dispose() End Sub Private Sub EventWatcher_EventArrived(sender As Object, e As EventArrivedEventArgs) Handles EventWatcher.EventArrived Using mo As ManagementBaseObject = e.NewEvent Dim letter As String = Convert.ToString(mo.Properties("Name").Value).TrimEnd({":"c, "\"c}) ' Dim volName As String = Convert.ToString(mo.Properties("VolumeName").Value) Dim di As DriveInfo = (From item In DriveInfo.GetDrives() Where item.Name.TrimEnd({":"c, "\"c}) = letter ).Single() If Not String.IsNullOrEmpty(di.VolumeLabel) Then Console.WriteLine(String.Format("CD-ROM tray inserted in drive '{0}'.", di.Name)) Else Console.WriteLine(String.Format("CD-ROM tray ejected in drive '{0}'.", di.Name)) End If End Using End Sub End Class
Traducción a C#: using System; using System.IO; using System.Linq; using System.Management; using System.Windows.Forms; namespace WindowsFormsApp1 { public partial class Form1 : Form { private ManagementEventWatcher EventWatcher; public Form1() { this.InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { // https://msdn.microsoft.com/en-us/library/aa394173%28v=vs.85%29.aspx WqlEventQuery eventQuery = new WqlEventQuery (eventClassName : "__InstanceModificationEvent", condition: "TargetInstance ISA 'Win32_LogicalDisk' AND TargetInstance.DriveType = 5", withinInterval: TimeSpan.FromSeconds(1)); EventWatcherOptions eventOptions = new EventWatcherOptions { BlockSize = 1, Timeout = TimeSpan.MaxValue }; ManagementPath scopePath = new ManagementPath { ClassName = "", NamespacePath = @"root\CIMV2", Path = @"\\.\root\CIMV2", Server = "." }; ConnectionOptions scopeOptions = new ConnectionOptions { Authentication = AuthenticationLevel.Default, EnablePrivileges = true, Impersonation = ImpersonationLevel.Impersonate, Timeout = TimeSpan.MaxValue }; ManagementScope scope = new ManagementScope (scopePath, scopeOptions ); this.EventWatcher = new ManagementEventWatcher { Options = eventOptions, Query = eventQuery, Scope = scope }; this.EventWatcher.Scope.Connect(); this.EventWatcher.EventArrived += this.EventWatcher_EventArrived; this.EventWatcher.Start(); } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { this.EventWatcher.Dispose(); } private void EventWatcher_EventArrived(object sender, EventArrivedEventArgs e) { using (ManagementBaseObject mo = e.NewEvent) { string letter = Convert .ToString(mo .Properties["Name"].Value).TrimEnd(new char[] {':', '\\'}); // string volName = Convert.ToString(mo.Properties("VolumeName").Value); DriveInfo di = (from item in DriveInfo.GetDrives() where item .Name.TrimEnd(new char[] { ':', '\\' }) == letter select item ).Single(); if (!string.IsNullOrEmpty(di.VolumeLabel)) { Console.WriteLine(string.Format("CD-ROM tray inserted in drive '{0}'.", di.Name)); } else { Console.WriteLine(string.Format("CD-ROM tray ejected in drive '{0}'.", di.Name)); } } } } }
PD: No lo he testeado, ahora mismo no tengo lector de CD instalado, pero debe funcionar... por que en el pasado me funcionó xD. PD2: Si en lugar de un Form quieres hacerlo a través de una aplicación de consola, entonces tal vez quieras usar el método bloqueante ManagementEventWatcher.WaitForNextEvent() para que no se cierre la instancia de tu programa antes de recibir el próximo evento... ... this.EventWatcher.Start(); while (true) { this.EventWatcher.WaitForNextEvent(); } ...
Saludos.
|
|
« Última modificación: 12 Noviembre 2017, 13:34 pm por Eleкtro »
|
En línea
|
|
|
|
Meta
|
Hola: Copié tu código. Errores por todas partes, no respondí antes por ser muy lioso estos errores que pasé. Gracias por tu tiempo. MOD: Imagen adaptada a lo permitido. (Ya deberías saber ésto)
|
|
« Última modificación: 16 Noviembre 2017, 21:10 pm por MCKSys Argentina »
|
En línea
|
|
|
|
okik
Desconectado
Mensajes: 462
|
hola buenas Tras leer el comentario de @Elektro en el otro tema( Hacer funcionar el lector de bandeja de discos con este lenguaje .net), decidí entrar aquí a ver el código de @Elektro. Bueno, a mí tampoco me funcionaba el código de @Elektro pero conseguí que funcionara tras algunos cambios, especialmente con TimeSpan y ManagementBaseObject. El caso es que ya me funciona y aquí dejo el código (que es un 99% del de @Elektro pero vamos ) Pero antes algunos detalles, - Desde NET, debe agregarse, desde 'agregar referencia' la librería System.Management- La unidad de CD/DVD ROM debe contener un disco en su interior, de lo contrario este código no hace nada de nada. NOTA: En ambos casos he usado el un proyecto "Aplicación de Windows Forms" C#using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Management; using System.IO; namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private ManagementEventWatcher withEventsField_EventWatcher; private ManagementEventWatcher EventWatcher { get { return withEventsField_EventWatcher; } set { if (withEventsField_EventWatcher != null) { withEventsField_EventWatcher.EventArrived -= EventWatcher_EventArrived; } withEventsField_EventWatcher = value; if (withEventsField_EventWatcher != null) { withEventsField_EventWatcher.EventArrived += EventWatcher_EventArrived; } } } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { this.EventWatcher.Dispose(); } private void Form1_Load(object sender, EventArgs e) { try { WqlEventQuery eventQuery = new WqlEventQuery (); eventQuery.EventClassName = "__InstanceModificationEvent"; eventQuery .WithinInterval = new TimeSpan (0, 0, 1); eventQuery.Condition = "TargetInstance ISA 'Win32_LogicalDisk' and TargetInstance.DriveType = 5"; EventWatcherOptions eventOptions = new EventWatcherOptions { BlockSize = 1, Timeout = TimeSpan.MaxValue }; ManagementPath scopePath = new ManagementPath { ClassName = "", NamespacePath = "root\\CIMV2", Path = "\\\\.\\root\\CIMV2", Server = "." }; ConnectionOptions scopeOptions = new ConnectionOptions { Authentication = AuthenticationLevel.Default, EnablePrivileges = true, Impersonation = ImpersonationLevel.Impersonate, Timeout = TimeSpan.MaxValue }; ManagementScope scope = new ManagementScope ("\\root\\CIMV2", scopeOptions ); this.EventWatcher = new ManagementEventWatcher { Options = eventOptions, Query = eventQuery, Scope = scope }; this.EventWatcher.Scope.Connect(); this.EventWatcher.Start(); } catch (ManagementException ex) { Console.WriteLine(ex.Message); } } private void EventWatcher_EventArrived(object sender, EventArrivedEventArgs e) { ManagementBaseObject wmiDevice = (ManagementBaseObject)e.NewEvent["TargetInstance"]; string VolumeName = null; string driveName = (string)wmiDevice["DeviceID"]; if (wmiDevice.Properties["VolumeName"].Value != null) { VolumeName = wmiDevice.Properties["VolumeName"].Value.ToString(); } string Name = (string)wmiDevice["Name"]; StringBuilder infoMessage = new StringBuilder (); infoMessage.AppendLine(driveName); infoMessage.AppendLine(VolumeName); infoMessage.AppendLine(Name); if (wmiDevice.Properties["VolumeName"].Value != null) { infoMessage.AppendLine("CD has been inserted"); } else { infoMessage.AppendLine("CD has been ejected"); } MessageBox.Show(infoMessage.ToString()); } } }
VB.NET Imports System.Management Imports System.IO Public Class Form1 Private WithEvents EventWatcher As ManagementEventWatcher Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing End Sub Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Try Dim eventQuery As New WqlEventQuery() eventQuery.EventClassName = "__InstanceModificationEvent" eventQuery.WithinInterval = New TimeSpan(0, 0, 1) eventQuery.Condition = "TargetInstance ISA 'Win32_LogicalDisk' and TargetInstance.DriveType = 5" Dim eventOptions As New EventWatcherOptions With { .BlockSize = 1, .Timeout = TimeSpan.MaxValue } Dim scopePath As New ManagementPath With { .ClassName = "", .NamespacePath = "root\CIMV2", .Path = "\\.\root\CIMV2", .Server = "." } Dim scopeOptions As New ConnectionOptions With { .Authentication = AuthenticationLevel.Default, .EnablePrivileges = True, .Impersonation = ImpersonationLevel.Impersonate, .Timeout = TimeSpan.MaxValue } Dim scope As New ManagementScope("\root\CIMV2", scopeOptions) Me.EventWatcher = New ManagementEventWatcher With { .Options = eventOptions, .Query = EventQuery, .Scope = scope } Me.EventWatcher.Scope.Connect() Me.EventWatcher.Start() Catch ex As ManagementException Console.WriteLine(ex.Message) End Try End Sub Private Sub EventWatcher_EventArrived(sender As Object, e As EventArrivedEventArgs) Handles EventWatcher.EventArrived Dim wmiDevice As ManagementBaseObject = DirectCast(e.NewEvent("TargetInstance"), ManagementBaseObject) Dim driveName As String = DirectCast(wmiDevice("DeviceID"), String) Dim VolumeName As String = wmiDevice.Properties("VolumeName").Value Dim Name As String = DirectCast(wmiDevice("Name"), String) Dim infoMessage As New StringBuilder infoMessage.AppendLine(driveName) infoMessage.AppendLine(VolumeName) infoMessage.AppendLine(Name) If wmiDevice.Properties("VolumeName").Value IsNot Nothing Then infoMessage.AppendLine("CD has been inserted") Else infoMessage.AppendLine("CD has been ejected") End If MessageBox.Show(infoMessage.ToString) End Sub Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing Me.EventWatcher.Dispose() End Sub End Class
|
|
« Última modificación: 17 Noviembre 2017, 03:09 am por okik »
|
En línea
|
|
|
|
Meta
|
Hola: Me ejecuta el programa. Como sabrás, no hay botón para abrir y cerrar la bandeja. Así sin más no pasa nada. Puse un botón y este código en el cual no furula. Xdddd. private void button_Abrir_Click(object sender, EventArgs e) { EventWatcher_EventArrived(); }
Saludos.
|
|
|
En línea
|
|
|
|
okik
Desconectado
Mensajes: 462
|
Hola: Me ejecuta el programa. Como sabrás, no hay botón para abrir y cerrar la bandeja. Así sin más no pasa nada. Puse un botón y este código en el cual no furula. Xdddd. private void button_Abrir_Click(object sender, EventArgs e) { EventWatcher_EventArrived(); }
Saludos. Hombre así tal cual... Sería así: this.EventWatcher.Start();
He hecho esta emulación de lo que se podría hacer pero el thread debería ejecutarse con load para cambiar el botón Cerrar, Abrir si el usuario abriera o cerrara desde el "eject" del propio lector, además que detecte si hay disco o no. using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Management; using System.IO; using System.Runtime.InteropServices; namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private ManagementEventWatcher withEventsField_EventWatcher; private ManagementEventWatcher EventWatcher { get { return withEventsField_EventWatcher; } set { if (withEventsField_EventWatcher != null) { withEventsField_EventWatcher.EventArrived -= EventWatcher_EventArrived; } withEventsField_EventWatcher = value; if (withEventsField_EventWatcher != null) { withEventsField_EventWatcher.EventArrived += EventWatcher_EventArrived; } } } [DllImport("winmm.dll")] private static extern uint mciSendString(string sCommand, StringBuilder sReturn, uint cchReturn, IntPtr hwnd); bool bolEject = false; private void Form1_FormClosing(object sender, FormClosingEventArgs e) { this.EventWatcher.Dispose(); } private void Form1_Load(object sender, EventArgs e) { try { btnEject.Text = "Abrir"; WqlEventQuery eventQuery = new WqlEventQuery (); eventQuery.EventClassName = "__InstanceModificationEvent"; eventQuery .WithinInterval = new TimeSpan (0, 0, 1); eventQuery.Condition = "TargetInstance ISA 'Win32_LogicalDisk' and TargetInstance.DriveType = 5"; EventWatcherOptions eventOptions = new EventWatcherOptions { BlockSize = 1, Timeout = TimeSpan.MaxValue }; ManagementPath scopePath = new ManagementPath { ClassName = "", NamespacePath = "root\\CIMV2", Path = "\\\\.\\root\\CIMV2", Server = "." }; ConnectionOptions scopeOptions = new ConnectionOptions { Authentication = AuthenticationLevel.Default, EnablePrivileges = true, Impersonation = ImpersonationLevel.Impersonate, Timeout = TimeSpan.MaxValue }; ManagementScope scope = new ManagementScope ("\\root\\CIMV2", scopeOptions ); this.EventWatcher = new ManagementEventWatcher { Options = eventOptions, Query = eventQuery, Scope = scope }; this.EventWatcher.Scope.Connect(); // this.EventWatcher.Start(); } catch (ManagementException ex) { Console.WriteLine(ex.Message); } } private void EventWatcher_EventArrived(object sender, EventArrivedEventArgs e) { ManagementBaseObject wmiDevice = (ManagementBaseObject)e.NewEvent["TargetInstance"]; string VolumeName = null; string driveName = (string)wmiDevice["DeviceID"]; if (wmiDevice.Properties["VolumeName"].Value != null) { VolumeName = wmiDevice.Properties["VolumeName"].Value.ToString(); } string Name = (string)wmiDevice["Name"]; StringBuilder infoMessage = new StringBuilder (); infoMessage.AppendLine(driveName); infoMessage.AppendLine(VolumeName); infoMessage.AppendLine(Name); this.Invoke(new Action (() => { if (wmiDevice.Properties["VolumeName"].Value != null) { infoMessage.AppendLine("CD has been inserted"); label1.Text = "Cerrado"; btnEject.Text = "Abrir"; bolEject = false; } else { infoMessage.AppendLine("CD has been ejected"); label1.Text = "Abierto"; btnEject.Text = "Cerrar"; bolEject = true; } btnEject.Enabled = true; })); this.EventWatcher.Stop(); MessageBox.Show(infoMessage.ToString()); } private void btnEject_Click(object sender, EventArgs e) { IntPtr ptr = IntPtr.Zero; StringBuilder returnstring = new StringBuilder (); this.EventWatcher.Start(); if (bolEject == false) { this.label1.Text = "Abriendo..."; mciSendString("set CDAudio door open", returnstring, 127, IntPtr.Zero); } else { this.label1.Text = "Cerrando..."; mciSendString("set CDAudio door closed", returnstring, 127, IntPtr.Zero); } btnEject.Enabled = false; } } }
|
|
|
En línea
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
[C#] Identificar cuando una aplicación externa es cerrada.
.NET (C#, VB.NET, ASP)
|
HappyNewYear
|
3
|
5,921
|
3 Mayo 2010, 17:12 pm
por Atrum
|
|
|
Bandeja de Lector XBOX360 con problemas
Electrónica
|
Diabliyo
|
1
|
5,668
|
20 Agosto 2010, 05:00 am
por Ari Slash
|
|
|
Error humano, puerta abierta a los hackers – que puede ser cerrada al cumplir...
Noticias
|
wolfbcn
|
0
|
2,624
|
20 Febrero 2015, 21:37 pm
por wolfbcn
|
|
|
Cerrar y abrir la bandeja del lector con el botón manualmente, y que lo sepa C#
.NET (C#, VB.NET, ASP)
|
Meta
|
5
|
3,161
|
23 Marzo 2017, 14:16 pm
por Eleкtro
|
|
|
[Pregunta]: Detectar cuando javascript esta desactivado en mi WEB
Desarrollo Web
|
Leguim
|
3
|
2,621
|
16 Junio 2019, 01:21 am
por @XSStringManolo
|
|