El parámetro “install” si es pasado a la aplicación se crea una
llave en el registro para garantizar la carga en cada inicio del sistema, lo
contrario con el parámetro “uninstall”
Evento Load del formulario
Genarq es una clase del programa
con métodos de apoyo a la solución del problema.
La definición de la
clase comienza así:
Como se ve, incluye
la declaración de una variable tIntervalo de tipo Timer (clase .NET para ejecutar
métodos a intervalos regulares de tiempo, 1 segundo para nuestro caso).
El método HeadFileCSVRW() y AddLineFileCSV(string namefile,string linea)
public
static string
HeadFileCSVRW()
{
string
namefile = Application.StartupPath + Path.DirectorySeparatorChar.ToString() + "cusb_" + DateTime.Now.Day.ToString()
+ "_" + DateTime.Now.Month.ToString()
+ "_" + DateTime.Now.Year.ToString()
+ ".csv";
if
(!File.Exists(namefile))
{
using
(FileStream fs = new
FileStream(namefile, FileMode.CreateNew, FileAccess.Write, FileShare.ReadWrite))
{
using
(TextWriter fila_csv = new StreamWriter(fs))
{
// LetraUnidad,Nombre+HoraConexion,Tamaño,MBL0,MBOcup,BLtmp,BCopiados
fila_csv.WriteLine("Escrito por: Arquimides R. Ribeaux del Rio"); fila_csv.WriteLine("Letra_Unidad,Etiqueta_Hora,GZ0,MBL_i,MB_o,MBL_Tmp,MBC");
fila_csv.Close();
}
}
}
return
namefile;
}
public static void AddLineFileCSV(string namefile,string linea)
{
using (FileStream fs = new FileStream(namefile, FileMode.Append, FileAccess.Write, FileShare.ReadWrite))
{
using (TextWriter fila_csv = new StreamWriter(fs))
{
// LetraUnidad,Nombre+HoraConexion,Tamaño,MBL0,MBOcup,BLBorrado,BLCopiado
fila_csv.WriteLine(linea);
fila_csv.Close();
}
}
}
El primer método chequea la existencia
del archivo csv, sino existe lo crea con un nombre que incluye la fecha del día
y escribe las 2 primeras líneas del fichero y el segundo agrega cada linea al csv despues de extraido el dispositivo
El procedimiento tProcess1Seg, código del evento
Tick del Timer
public
static void
tProcess1Seg(Object myobj, EventArgs myEA)
{
string
lunidad;
tIntervalo.Stop();
for
(byte i = 0; i <= 25; i++)
{
if (frmMain.usb_conectada[i,
0] != null) //La
letra de unidad NO es Null
{
try
{
// 0 ,1, 2, 3, 4, 5 , 6
// LetraUnidad,Nombre+HoraConexion,Tamaño,BL0,Ocupados,BLtmp,BCopiados
lunidad = frmMain.usb_conectada[i,0];
DriveInfo unidad = new DriveInfo(lunidad);
//BL al iniciar
long lec_anterior = (long)Convert.ToInt64(frmMain.usb_conectada[i,5]);
//Lectura de espacio libre ahora
long lec_now = unidad.AvailableFreeSpace;
// El espacio libre va disminuyendo por tanto estan copiando
if ((lec_anterior - lec_now) > 0 )
{
long lec_tmp = (long)Convert.ToInt64(frmMain.usb_conectada[i,6])+(lec_anterior - lec_now);
frmMain.usb_conectada[i,6] = lec_tmp.ToString();
}
frmMain.usb_conectada[i,5]=lec_now.ToString(); }
catch
{
tIntervalo.Start();
Application.DoEvents();
return;
}
}
}
tIntervalo.Enabled = true;
}
Procedimiento para el evento OnDriveArrived
private
void OnDriveArrived(object
sender, DriveDetectorEventArgs e)
{
// LetraUnidad,Nombre+HoraConexion,Tamaño,BL0,Ocup0,BLBorrado,BLCopiado
// e.Drive is the drive letter for the device which just arrived, e.g.
"E:\\" try
{
flash = new DriveInfo(e.Drive);
NombreVolumen = flash.VolumeLabel.ToString(); // obtener el nombre del volumen
if (NombreVolumen.Length == 0)
{ NombreVolumen = "Sin_Nombre";
}
// Obtener la primera letra de la cadena, la letra de unidad
LetraUnidad = e.Drive[0];
size0 = flash.TotalSize;
Bay0 = flash.AvailableFreeSpace; // Espacio
libre inicial
Ocup0 = size0 - Bay0; // Espacio Ocupado
inicial
// El ascii de letra unidad-65 para obtener la fila de la matriz
fila_matriz = Encoding.ASCII.GetBytes(LetraUnidad.ToString())[0];
Hora_conexion=DateTime.Now.Hour.ToString()+":"+DateTime.Now.Minute.ToString()+":"+ DateTime.Now.Second.ToString();
usb_conectada[fila_matriz - 65, 0] = e.Drive;
usb_conectada[fila_matriz - 65, 1] = NombreVolumen + "_" + Hora_conexion;
usb_conectada[fila_matriz - 65, 2] = size0.ToString();
usb_conectada[fila_matriz - 65, 3] = Bay0.ToString();
usb_conectada[fila_matriz - 65, 4] = Ocup0.ToString();
usb_conectada[fila_matriz - 65, 5] = Bay0.ToString();
usb_conectada[fila_matriz - 65, 6] = "0";
}
catch
{
Genarq.tIntervalo.Start();
Application.DoEvents();
Genarq.tIntervalo.Enabled
= true;
return;
}
Procedimiento para el evento OnDriveRemoved
private void OnDriveRemoved(object sender, DriveDetectorEventArgs e)
{
// Manipular unidad
LetraUnidad = e.Drive[0];
fila_matriz = Encoding.ASCII.GetBytes(LetraUnidad.ToString())[0];
// 0 , 1 , 2 , 3 , 4 , 5 , 6
// LetraUnidad,Nombre+HoraConexion,Tamaño,BL0,Ocup,BLBorrado,BLCopiado
long ar2, ar3, ar4, ar5, ar6;
ar2 = (long)Convert.ToInt64(usb_conectada[fila_matriz - 65, 2]); // Tamaño
ar3 = (long)Convert.ToInt64(usb_conectada[fila_matriz - 65, 3]); //BL al conectar
ar4 = (long)Convert.ToInt64(usb_conectada[fila_matriz - 65, 4]);
ar5 = (long)Convert.ToInt64(usb_conectada[fila_matriz - 65, 5]); //BL Tmp
ar6 = (long)Convert.ToInt64(usb_conectada[fila_matriz - 65, 6]); //B copiados
string letra = usb_conectada[fila_matriz - 65, 0];
string nombre = usb_conectada[fila_matriz - 65, 1];
// Limpiar la fila de la matriz
usb_conectada[fila_matriz - 65, 0] = null;
usb_conectada[fila_matriz - 65, 1] = "Sin_Nombre";
usb_conectada[fila_matriz - 65, 2] = string.Empty;
usb_conectada[fila_matriz - 65, 3] = string.Empty;
usb_conectada[fila_matriz - 65, 4] = string.Empty;
usb_conectada[fila_matriz - 65, 5] = string.Empty;
usb_conectada[fila_matriz - 65, 6] = string.Empty;
double Mb2, Mb3, Mb4, Mb5, Mb6;
Mb2 = ((Convert.ToDouble(ar2) / 1024) / 1024) / 1024; //tamaño
Mb3 = ((Convert.ToDouble(ar3) / 1024) / 1024); //MBL al conectar
Mb4 = ((Convert.ToDouble(ar4) / 1024) / 1024); //MB Ocupados al conectar
Mb5 = ((Convert.ToDouble(ar5) / 1024) / 1024); //BL Temporales
Mb6 = ((Convert.ToDouble(ar6) / 1024) / 1024); //MB copiados
string tam = Math.Round(Mb2, 2).ToString() + " GB";
string mbl0 = Math.Round(Mb3, 2).ToString();
string mbl1 = Math.Round(Mb4, 2).ToString();
string mbl2 = Math.Round(Mb5, 2).ToString();
string mbl3 = Math.Round(Mb6, 2).ToString();
string linea = letra + "," + nombre + "," + tam + "," + mbl0 + "," + mbl1 + "," + mbl2 + "," + mbl3;
// Si pc queda encendida hasta dia sig. el proceso esta cargado de modo q no se //ejecutar el Form_load
// Debemos asegurarnos q escriba en el dia correcto
string nombre_ruta_csv = Genarq.HeadFileCSVRW();
Genarq.AddLineFileCSV(nombre_ruta_csv, linea);
}
En el siguiente enlace de Google Drive se puede descargar un fichero compactado (cusb.rar) que contiene el ejecutable cusb.exe.
https://drive.google.com/file/d/0B1y9zYoMQe86S1djekRtV3RCZ28/view?usp=sharing
Hasta aquí mi solución. Al momento de terminar de redactar este artículo, me informan unos amigos (padre e hijo programadores) con los cuales compartí la idea inicial, que lograron controlar el DBT_DEVICEQUERYREMOVE e implementaron la solución utilizando directamente la función API de Windows que esta encapsulada en la clase .NET FileSystemWatcher; desarrollaran en Delphi/Pascal; para ellos el mejor lenguaje de programación que existe.