Search Results for

    Show / Hide Table of Contents

    Devices watcher

    Important

    Devices watching API is a platform-specific one so please refer to the Supported OS article to learn more.

    DryWetMIDI allows to track whether a MIDI device is added to or removed from the system. There is the DevicesWatcher class for that purpose. The class is singleton and you can get the instance with Instance property.

    DevicesWatcher provides two events: DeviceAdded and DeviceRemoved. First one will be fired when a MIDI device is added to the system, and second one – when a device is removed from it. You can then cast a device instance from the event's arguments to InputDevice or OutputDevice. See following sample program:

    using System;
    using System.Threading;
    using Melanchall.DryWetMidi.Multimedia;
    
    namespace DwmExamples
    {
        class Program
        {
            static void Main(string[] args)
            {
                DevicesWatcher.Instance.DeviceAdded += OnDeviceAdded;
                DevicesWatcher.Instance.DeviceRemoved += OnDeviceRemoved;
    
                Console.WriteLine("Adding device...");
                var virtualDevice = VirtualDevice.Create("MyDevice");
    
                Thread.Sleep(500); // to get system time to see new device
    
                Console.WriteLine("Removing device...");
                virtualDevice.Dispose();
    
                Console.ReadKey();
            }
    
            private static void OnDeviceRemoved(object sender, DeviceAddedRemovedEventArgs e)
            {
                Console.WriteLine($"Device removed: {e.Device.GetType()}");
            }
    
            private static void OnDeviceAdded(object sender, DeviceAddedRemovedEventArgs e)
            {
                Console.WriteLine($"Device added: {e.Device.GetType()} ({e.Device.Name})");
            }
        }
    }
    

    Running the program we'll see following output:

    Adding device...
    Device added: Melanchall.DryWetMidi.Multimedia.InputDevice (MyDevice)
    Device added: Melanchall.DryWetMidi.Multimedia.OutputDevice (MyDevice)
    Removing device...
    Device removed: Melanchall.DryWetMidi.Multimedia.InputDevice
    Device removed: Melanchall.DryWetMidi.Multimedia.OutputDevice
    

    When a device is added you can immediately interact with it using an instance from the DeviceAdded event's arguments. But an instance from the DeviceRemoved event's arguments is non-interactable, because the device is removed and doesn't exist in the system anymore. Any attempt to call methods or properties on that instance will throw an exception:

    using System;
    using System.Threading;
    using Melanchall.DryWetMidi.Multimedia;
    
    namespace DwmExamples
    {
        class Program
        {
            static void Main(string[] args)
            {
                DevicesWatcher.Instance.DeviceRemoved += OnDeviceRemoved;
    
                var virtualDevice = VirtualDevice.Create("MyDevice");
                Thread.Sleep(500); // to get system time to see new device
    
                Console.WriteLine("Removing device...");
                virtualDevice.Dispose();
    
                Console.ReadKey();
            }
    
            private static void OnDeviceRemoved(object sender, DeviceAddedRemovedEventArgs e)
            {
                Console.WriteLine($"Device removed. Getting its name...");
                var deviceName = e.Device.Name;
            }
        }
    }
    

    The program will be crashed with:

    Removing device...
    Device removed. Getting its name...
    Unhandled exception. System.InvalidOperationException: Operation can't be performed on removed device.
    

    But you can compare device instances via Equals to know whether two instances of MidiDevice are equal or not. Following example shows how you can get the name of a removed device via info about devices stored at the start of the program:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading;
    using Melanchall.DryWetMidi.Multimedia;
    
    namespace DwmExamples
    {
        class Program
        {
            private static Dictionary<MidiDevice, string> _devicesNames;
    
            static void Main(string[] args)
            {
                DevicesWatcher.Instance.DeviceRemoved += OnDeviceRemoved;
    
                var virtualDevice = VirtualDevice.Create("MyDevice");
                Thread.Sleep(500); // to get system time to see new device
    
                _devicesNames = InputDevice.GetAll()
                    .OfType<MidiDevice>()
                    .Concat(OutputDevice.GetAll())
                    .ToDictionary(d => d, d => d.Name);
    
                Console.WriteLine("Removing device...");
                virtualDevice.Dispose();
    
                Console.ReadKey();
            }
    
            private static void OnDeviceRemoved(object sender, DeviceAddedRemovedEventArgs e)
            {
                Console.WriteLine($"Device removed. Getting its name...");
                var deviceName = _devicesNames[e.Device];
                Console.WriteLine($"Name is {deviceName}");
            }
        }
    }
    

    Output is:

    Removing device...
    Device removed. Getting its name...
    Name is MyDevice
    Device removed. Getting its name...
    Name is MyDevice
    

    Device instances comparison can be useful in programs with GUI where you need to update the list of available devices. So when a device is added, you just add it to the list. When some device is removed, you find the corresponding item in the current list via Equals on device instances and remove that item.

    Important

    Checking for devices equality supported for macOS only. On Windows call of Equals will just compare references.

    In this article
    Back to top 2024 / Generated by DocFX