Para los aficionados al desarrollo de aplicaciones con .NET y C#, aquí voy a dejar un trozo de código muy interesante.
Básicamente consiste en un método para notificar a una aplicación de que se ha insertado un nuevo disco en el sistema (un CD, DVD, llave USB, tarjeta de memoria SD/MMC/etc, Disco duro externo, …), un método para identificar la letra de la nueva unidad, y a partir de ellos construir las aplicaciones que se nos ocurran que puedan aprovecharse de esta funcionalidad.
//Incluir esto es obligatorio
using System.Runtime.InteropServices;
/*
* Escribe aquí el código de tu programa (¡O donde prefieras!)…
*/
//Estructura de datos que almacena la gestión de conexiones
[StructLayout(LayoutKind.Sequential)]
public struct DEV_BROADCAST_VOLUME
{
public int dbcv_size;
public int dbcv_devicetype;
public int dbcv_reserved;
public int dbcv_unitmask;
}
//Método a sobreescribir para gestionar la llegada de nuevas unidades de disco
protected override void WndProc(ref Message m)
{
//Estas definiciones están en dbt.h y winuser.h
//Se ha producido un cambio en los dispositivos
const int WM_DEVICECHANGE = 0×0219;
// El sistema detecta un nuevo dispositivo
const int DBT_DEVICEARRIVAL = 0×8000;
//Solicita retirada del dispositivo
const int DBT_DEVICEQUERYREMOVE = 0×8001;
//Ha fallado la retirada del dispositivo
const int DBT_DEVICEQUERYREMOVEFAILED = 0×8002;
//Pendiente extracción del dispositivo
const int DBT_DEVICEREMOVEPENDING = 0×8003;
//Dispositivo extraído del sistema
const int DBT_DEVICEREMOVECOMPLETE = 0×8004;
// Volumen lógico (Se ha insertado un disco)
const int DBT_DEVTYP_VOLUME = 0×00000002;
switch (m.Msg)
{
//Cambian los dispositivos del sistema
case WM_DEVICECHANGE:
switch (m.WParam.ToInt32())
{
//Llegada de un dispositivo
case DBT_DEVICEARRIVAL:
{
int devType = Marshal.ReadInt32(m.LParam, 4);
//Si es un volumen lógico..(unidad de disco)
if (devType == DBT_DEVTYP_VOLUME)
{
DEV_BROADCAST_VOLUME vol;
vol = (DEV_BROADCAST_VOLUME)Marshal.PtrToStructure(
m.LParam, typeof(DEV_BROADCAST_VOLUME));
MessageBox.Show(
”Insertada unida de disco, unidad: ” +
LetraUnidad(vol.dbcv_unitmask));
}
}
break;
case DBT_DEVICEREMOVECOMPLETE:
MessageBox.Show(”Dispositivo retirado.”);
break;
}
break;
}
//Ahora usar el manejador predeterminado
base.WndProc(ref m);
}
//Método para detectar la letra de unidad
char LetraUnidad(int unitmask)
{
char[] units ={ ‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’, ‘G’,
’H', ‘I’, ‘J’, ‘K’, ‘L’, ‘M’, ‘N’, ‘O’, ‘P’,
’Q', ‘R’, ‘S’, ‘T’, ‘U’, ‘V’, ‘W’, ‘X’, ‘Y’, ‘Z’ };
int i = 0;
//Convetimos la máscara en un array primario y buscamos
//el índice de la primera ocurrencia (la letra de unidad)
System.Collections.BitArray ba = new
System.Collections.BitArray(System.BitConverter.GetBytes(unitmask));
foreach (bool var in ba)
{
if (var == true)
break;
i++;
}
return units[i];
}
Aquí os dejo (correctamente formateada) la aportación de Carolina, el código en Visual Basic para la detección de unidades:
‘Estructura de datos que almacena la gestión de conexiones
Public Structure dispositivo
Public dispTamaño As Integer
Public dispTipo As Integer
Public dispReserv As Integer
Public dispMask As Integer
End Structure
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
‘Se ha producido un cambio en los dispositivos
Const deviceChange As Integer = &H219
‘El sistema detecta un nuevo dispositivo
Const deviceArrival As Integer = &H8000
‘Solicita retirada del dispositivo
Const deviceQueryRemove As Integer = &H8001
‘Ha fallado la retirada del dispositivo
Const devideQueryRemoveFailed As Integer = &H8002
‘Pendiente extracción del dispositivo
Const deviceRemovePending As Integer = &H8003
‘Dispositivo extraído del sistema
Const deviceRemoveComplete As Integer = &H8004
‘ Volumen lógico (Se ha insertado un disco)
Const deviceTypeVolume As Integer = &H2
Select Case m.Msg
‘Cambian los dispositivos del sistema
Case deviceChange
Select Case m.WParam.ToInt32
‘Llegada de un dispositivo
Case deviceArrival
Dim devType As Integer = Marshal.ReadInt32(m.LParam, 4)
‘Si es un volumen lógico..(unidad de disco)
If devType = deviceTypeVolume Then
Dim vol As dispositivo
vol = CType(Marshal.PtrToStructure(m.LParam, GetType(dispositivo)), dispositivo)
MessageBox.Show(”Se insertó un dispositivo en la unidad ” & LetraUnidad(vol.dispMask) & “.”)
‘ACA HAGO EL TRATAMIENTO DEL DISPOSITIVO INSERTADO
End If
Case deviceRemoveComplete
MessageBox.Show(”Se retiró el dispositivo.”)
End Select
End Select
‘Ahora se usa el manejador predeterminado
MyBase.WndProc(m)
End Sub
Private Function LetraUnidad(ByVal unitmask As Integer) As Char
Dim units() As Char = {”A”, “B”, “C”, “D”, “E”, “F”, “G”,
“H”, “I”, “J”, “K”, “L”, “M”, “N”, “O”, “P”,
“Q”, “R”, “S”, “T”, “U”, “V”, “W”, “X”, “Y”, “Z”}
Dim i As Integer = 0
‘Convetimos la máscara en un array primario y buscamos
‘el índice de la primera ocurrencia (la letra de unidad)
Dim ba As System.Collections.BitArray
ba = New System.Collections.BitArray(System.BitConverter.GetBytes(unitmask))
For i = 0 To ba.Length
If ba(i) = True Then
Exit For
End If
Next
Return units(i)
End Function


