Cerrar y abrir la bandeja del lector con el botón manualmente, y que lo sepa C#

Iniciado por Meta, 15 Marzo 2017, 11:11 AM

0 Miembros y 1 Visitante están viendo este tema.

Meta

Hola:

Quiero cerrar y abrir la bandeja del lector de DVD con el botón manualmente, y que lo sepa C#. Estoy usando Visual Studio Community 2017.

En otro momento hicimos desde C#, controlar la bandeja abrirla y cerrarla pulsando los botones como indica en la interfaz de abajo.



Código fuente sencillo de C#:
Código (csharp) [Seleccionar]
using System;
using System.Runtime.InteropServices; // No olvidar.
using System.Text;
using System.Windows.Forms;

namespace Lector_discos_cs
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        [DllImport("winmm.dll")]
        public static extern Int32 mciSendString(string lpstrCommand, StringBuilder lpstrReturnString,
            int uReturnLength, IntPtr hwndCallback);
       
        StringBuilder rt = new StringBuilder(127);

        private void button_Abrir_Click(object sender, EventArgs e)
        {
            label_Mensaje.Text = "Abriendo...";
            Application.DoEvents();
            mciSendString("set CDAudio door open", rt, 127, IntPtr.Zero);
            label_Mensaje.Text = "Abierto";
        }

        private void button_Cerrar_Click(object sender, EventArgs e)
        {
            label_Mensaje.Text = "Cerrando...";
            Application.DoEvents();
            mciSendString("set CDAudio door closed", rt, 127, IntPtr.Zero);
            label_Mensaje.Text = "Cerrado";
        }
    }
}


Hasta aquí todo bien.

Ahora quiero hacer, saber antes que nada, si es posible que al meter la bandeja con la mano o pulsar el botón físicamente del lector, C# puede saber su estado, cunado está abierto y cuando está cerrado.

En este caso, no hay botones para Windows Form de C#, solo un label que indica el estado "ABIERTO" y "CERRADO".

¿Es posible hacerlo?

Si es así. ¿Cómo se hace?

Lo único que pensé que este enlace valdría la pena o te daba información, pero es otra cosa.

Que tengan buena semana. ;)
Tutoriales Electrónica y PIC: http://electronica-pic.blogspot.com/

Eleкtro

Cita de: Meta en 15 Marzo 2017, 11:11 AMsi es posible que al meter la bandeja con la mano o pulsar el botón físicamente del lector, C# puede saber su estado, cunado está abierto y cuando está cerrado.

Si. Si el sistema operativo puede saberlo, tú desde C# / VB.NET / .NET puedes saberlo también.

Lo más sencillo sería subscribirse a un evento del instrumental de Windows (WMI) para notificar sobre cambios de hardware del tipo CD-ROM.

El otro día me puse a escribirte un código, pero tengo el lector del DVD-ROM jodido así que al final no he podido probarlo.

Lee sobre la clase de evento de WMI __InstanceModificationEvent, y la clase Win32_LogicalDisk:

En fin, la teoría sería esta:

Código (csharp) [Seleccionar]
// ***********************************************************************
// Author   : Elektro
// Modified : 16-March-2017
// ***********************************************************************

using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Management;

#region " Public Members Summary "

#region " Constructors "

// New(String)
// New(String, Single)
// New(String, String, Single)
// New(String, String, String(), UInteger)
// New(SelectQuery)
// New(SelectQuery, Single)
// New(SelectQuery, UInteger)

#endregion

#region " Events "

// EventArrived As EventArrivedEventHandler

#endregion

#region " Methods "

// Start()
// Stop()
// Dispose()

#endregion

#endregion

#region " WMI Event Watcher "

namespace Types {

   /// ----------------------------------------------------------------------------------------------------
   /// <summary>
   /// A WMI event monitor that notifies about event arrivals for the subscribed event class.
   /// </summary>
   /// ----------------------------------------------------------------------------------------------------
   [DesignerCategory("Code")]
   [ImmutableObject(false)]
   public class WMIEventWatcher : ManagementEventWatcher {

       #region " Constructors "

       /// ----------------------------------------------------------------------------------------------------
       /// <summary>
       /// Prevents a default instance of the <see cref="WMIEventWatcher"/> class from being created.
       /// </summary>
       /// ----------------------------------------------------------------------------------------------------
       [DebuggerNonUserCode()]
       private WMIEventWatcher() {}

       /// ----------------------------------------------------------------------------------------------------
       /// <summary>
       /// Initializes a new instance of the <see cref="WMIEventWatcher"/> class.
       /// </summary>
       /// ----------------------------------------------------------------------------------------------------
       /// <param name="eventClassName">
       /// The name of the WMI event class to subscribe for.
       /// </param>
       /// ----------------------------------------------------------------------------------------------------
       [DebuggerStepThrough()]
       public WMIEventWatcher(string eventClassName) :
           this(eventClassName, string.Empty, withinInterval: 1f) {}

       /// ----------------------------------------------------------------------------------------------------
       /// <summary>
       /// Initializes a new instance of the <see cref="WMIEventWatcher"/> class.
       /// </summary>
       /// ----------------------------------------------------------------------------------------------------
       /// <param name="eventClassName">
       /// The name of the WMI event class to subscribe for.
       /// </param>
       ///
       /// <param name="withinInterval">
       /// The interval, in seconds, that WMI will check for changes that occur to instances of the events of the
       /// specified class in the <paramref name="eventClassName"/> parameter.
       /// </param>
       /// ----------------------------------------------------------------------------------------------------
       [DebuggerStepThrough()]
       public WMIEventWatcher(string eventClassName, float withinInterval) :
           this(eventClassName, condition: string.Empty, withinInterval: withinInterval) {}

       /// ----------------------------------------------------------------------------------------------------
       /// <summary>
       /// Initializes a new instance of the <see cref="WMIEventWatcher"/> class.
       /// </summary>
       /// ----------------------------------------------------------------------------------------------------
       /// <param name="eventClassName">
       /// The name of the WMI event class to subscribe for.
       /// </param>
       ///
       /// <param name="condition">
       /// The condition to be applied to events of the specified class in the
       /// <paramref name="eventClassName"/> parameter.
       /// </param>
       ///
       /// <param name="withinInterval">
       /// The interval, in seconds, that WMI will check for changes that occur to instances of the events of the
       /// specified class in the <paramref name="eventClassName"/> parameter.
       /// </param>
       /// ----------------------------------------------------------------------------------------------------
       [DebuggerStepThrough()]
       public WMIEventWatcher(string eventClassName, string condition, float withinInterval) {
           base.Query = new WqlEventQuery(eventClassName: eventClassName,
                                          condition: condition,
                                          withinInterval: TimeSpan.FromSeconds(withinInterval));
       }

       /// ----------------------------------------------------------------------------------------------------
       /// <summary>
       /// Initializes a new instance of the <see cref="WMIEventWatcher"/> class.
       /// </summary>
       /// ----------------------------------------------------------------------------------------------------
       /// <param name="eventClassName">
       /// The name of the WMI event class to subscribe for.
       /// </param>
       ///
       /// <param name="condition">
       /// The condition to be applied to events of the specified class in the
       /// <paramref name="eventClassName"/> parameter.
       /// </param>
       ///
       /// <param name="groupByPropertyList">
       /// The properties in the event class by which the events should be grouped.
       /// </param>
       ///
       /// <param name="groupWithinInterval">
       /// The interval, in seconds, of the specified interval at which WMI sends one aggregate event,
       /// rather than many events.
       /// </param>
       /// ----------------------------------------------------------------------------------------------------
       [DebuggerStepThrough()]
       public WMIEventWatcher(string eventClassName, string condition, string[] groupByPropertyList, uint groupWithinInterval) {
           base.Query = new WqlEventQuery(eventClassName: eventClassName,
                                          condition: condition,
                                          groupWithinInterval: TimeSpan.FromSeconds(groupWithinInterval),
                                          groupByPropertyList: groupByPropertyList);
       }

       /// ----------------------------------------------------------------------------------------------------
       /// <summary>
       /// Initializes a new instance of the <see cref="WMIEventWatcher"/> class.
       /// </summary>
       /// ----------------------------------------------------------------------------------------------------
       /// <param name="query">
       /// The WMI select query of the event class to subscribe for.
       /// </param>
       /// ----------------------------------------------------------------------------------------------------
       [DebuggerStepThrough()]
       public WMIEventWatcher(SelectQuery query) :
           this(query.ClassName, condition: query.Condition, withinInterval: 1f) {}

       /// ----------------------------------------------------------------------------------------------------
       /// <summary>
       /// Initializes a new instance of the <see cref="WMIEventWatcher"/> class.
       /// </summary>
       /// ----------------------------------------------------------------------------------------------------
       /// <param name="query">
       /// The WMI select query of the event class to subscribe for.
       /// </param>
       ///
       /// <param name="withinInterval">
       /// The interval, in seconds, that WMI will check for changes that occur to instances of the events of the
       /// specified class in the <paramref name="query"/> parameter.
       /// </param>
       /// ----------------------------------------------------------------------------------------------------
       [DebuggerStepThrough()]
       public WMIEventWatcher(SelectQuery query, float withinInterval) :
           this(query.ClassName, condition: query.Condition, withinInterval: withinInterval) {}

       /// ----------------------------------------------------------------------------------------------------
       /// <summary>
       /// Initializes a new instance of the <see cref="WMIEventWatcher"/> class.
       /// </summary>
       /// ----------------------------------------------------------------------------------------------------
       /// <param name="query">
       /// The WMI select query of the event class to subscribe for and its selected properties.
       /// </param>
       ///
       /// <param name="groupWithinInterval">
       /// The interval, in seconds, of the specified interval at which WMI sends one aggregate event,
       /// rather than many events.
       /// </param>
       /// ----------------------------------------------------------------------------------------------------
       [DebuggerStepThrough()]
       public WMIEventWatcher(SelectQuery query, uint groupWithinInterval) {
           string[] strArray = new string[query.SelectedProperties.Count];
           query.SelectedProperties.CopyTo(strArray, index: 0);
           base.Query = new WqlEventQuery(eventClassName: query.ClassName,
                                          condition: query.Condition,
                                          groupWithinInterval: TimeSpan.FromSeconds(groupWithinInterval),
                                          groupByPropertyList: strArray);
       }

       #endregion

   }

}

#endregion


Código (csharp) [Seleccionar]
using System;
using System.Data;
using System.IO;
using System.Linq;
using System.Management;
using System.Windows.Forms;
using Types;

namespace WindowsFormsApplication4
{
   public partial class Form1 : Form {

       public Form1() {
           InitializeComponent();
           this.FormClosing += this.Form1_FormClosing;
           this.Load += this.Form1_Load;
       }

       private WMIEventWatcher eventWatcher =  new WMIEventWatcher("__InstanceModificationEvent",
                               @"TargetInstance ISA 'Win32_LogicalDisk' and TargetInstance.DriveType = 5", 1f);

       private void Form1_Load(object sender, EventArgs e) {
           this.eventWatcher.EventArrived += this.EventWatcher_EventArrived;
           this.eventWatcher.Scope = new ManagementScope(@"root\CIMV2", new ConnectionOptions { EnablePrivileges = true });
           this.eventWatcher.Start();
       }

       private void Form1_FormClosing(object sender, FormClosingEventArgs e) {
           this.eventWatcher.Dispose();
       }

       private void EventWatcher_EventArrived(object sender, EventArrivedEventArgs e) {

           PropertyData pd = e.NewEvent.Properties["TargetInstance"];

           if ((pd != null)) {

               using (ManagementBaseObject mo = (ManagementBaseObject)pd.Value) {

                   string name = Convert.ToString(mo.Properties["Name"].Value);
                   // string label = Convert.ToString(mo.Properties["VolumeName"].Value);

                   DriveInfo di = (from item in DriveInfo.GetDrives()
                                   where string.IsNullOrEmpty(item.Name)
                                   select item).Single();

                   if (!string.IsNullOrEmpty(di.VolumeLabel)) {
                       Console.WriteLine(string.Format("CD has been inserted in drive {0}.", di.Name));

                   } else {
                       Console.WriteLine(string.Format("CD has been ejected from drive {0}.", di.Name));

                   }

               }

           }

       }

   }
}


Saludos








Meta

Hola:

He intentado hacer el último código en C# y como que no.


Parece que ese código es muy antiguo y no hay manera de hecharlo a andar.

Gracias de todas formas. Y mira que lo he intentado.
Tutoriales Electrónica y PIC: http://electronica-pic.blogspot.com/

Eleкtro

Cita de: Meta en 23 Marzo 2017, 10:23 AMParece que ese código es muy antiguo y no hay manera de hecharlo a andar.

Pero alma de cántaro, ¿tú lees las respuestas que te doy?:

Cita de: Eleкtro en 21 Marzo 2017, 15:05 PMEl otro día me puse a escribirte un código

Supongo que tampoco te has parado a leer el código:
Citar// Author   : Elektro
// Modified : 16-March-2017




Cita de: Meta en 23 Marzo 2017, 10:23 AMY mira que lo he intentado.

Los errores que has mostrado no tienen nada que ver con un mal funcionamiento del código. Tan solo tienes que añadir una referencia al ensamblado System.Management y el "using" necesario para importar el namespace de la clase que compartí, y ya podrás correr ese código para probarlo en condiciones.

Saludos








Meta

Tutoriales Electrónica y PIC: http://electronica-pic.blogspot.com/