Estoy pasando un code a VB.net 2005 de Sergio Desanti (Hasseds) del foro VB6 : Seriales
Pen-Drives
http://foro.elhacker.net/programacion_visual_basic/seriales_de_pendrives_conectados_src-t331333.0.html
EL problema es que entra en un bucle interminable, y tampoco estoy seguro si estoy utilizando bien las
funciones del API
Imports System.Runtime.InteropServices
<StructLayout(LayoutKind.Sequential)> _
public structure SP_DEVICE_INTERFACE_DATA
public cbSize as Long
public InterfaceClassGuid as GUID
public flags as Long
public IntPtr as Long
End Structure
<StructLayout(LayoutKind.Sequential)> _
Public Structure SP_DEVINFO_DATA
Public cbSize As UInteger
Public ClassGuid As Guid
Public DevInst As UInteger
Public Reserved As IntPtr
End Structure
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
Public Structure SP_DEVICE_INTERFACE_DETAIL_DATA
Public cbSize As UInt32
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=256)> _
Public strDevicePath As String
End Structure
' SetupDiGetClassDevs: Retorna informacion sobre el dispositivo.
<DllImport("setupapi.dll",EntryPoint:="SetupDiGetClassDevsW", SetLastError:=True, _
CharSet:=CharSet.Unicode, ExactSpelling:=True, PreserveSig:=True, _
CallingConvention:=CallingConvention.Winapi)> _
Private Shared Function SetupDiGetClassDevs( _
ByRef ClassGuid As GUID, _
ByVal Enumerator As Integer, _
ByVal hwndParent As Integer, _
ByVal Flags As Integer) As Integer
End Function
' SetupDiEnumDeviceInterfaces
<DllImport("setupapi.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Public Shared Function SetupDiEnumDeviceInterfaces(ByVal hDevInfo As IntPtr, _
ByRef devInfo As SP_DEVICE_INTERFACE_DATA, _
ByRef interfaceClassGuid As Guid, _
ByVal memberIndex As UInt32, _
ByRef deviceInterfaceData As SP_DEVICE_INTERFACE_DATA) As Boolean
End Function
' SetupDiGetDeviceInterfaceDetail
<DllImport("setupapi.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Public Shared Function SetupDiGetDeviceInterfaceDetail ( _
ByVal DeviceInfoSet As IntPtr, _
ByRef DeviceInterfaceData As SP_DEVICE_INTERFACE_DATA, _
ByRef DeviceInterfaceDetailData As SP_DEVICE_INTERFACE_DETAIL_DATA, _
ByVal DeviceInterfaceDetailDataSize As UInteger, _
ByRef RequiredSize As UInteger, _
ByRef DeviceInfoData As SP_DEVINFO_DATA) As Boolean
end function
' SetupDiDestroyDeviceInfoList
<DllImport("setupapi.dll", _
EntryPoint:="SetupDiDestroyDeviceInfoList", _
SetLastError:=True, _
ExactSpelling:=True, _
PreserveSig:=True, _
CallingConvention:=CallingConvention.Winapi)> _
Private Shared Function SetupDiDestroyDeviceInfoList( _
ByVal DeviceInfoSet As Integer) As Boolean
End Function
'------CharSet:=CharSet.Auto
' <DllImport("ole32.dll", CharSet:=CharSet.Unicode,PreserveSig:=false)> _
' static IIDFromString(lpsz as String)
' Funcion
Public Function FlashSerials() As String
Dim TGUID As GUID
Dim lCount As Long
Dim lSize As Long
Dim DTL As new SP_DEVICE_INTERFACE_DETAIL_DATA
Dim DTA As new SP_DEVICE_INTERFACE_DATA
dim cad as String
Dim strValue As String ="{a5dcbf10-6530-11d2-901f-00c04fb951ed}"
' esto era: Call IIDFromString(StrPtr("{a5dcbf10-6530-11d2-901f-00c04fb951ed}"), TGUID)
' pero no encuentro un equivalente en NET de IIDFromString
' encontre por ahi que se podia crear un Guid asi, estara bien?
TGUID = New Guid(strvalue)
Dim hDev As Long
hDev = SetupDiGetClassDevs(TGUID, &H0, &H0, &H12)
If hDev = -1 Then
return "No hay nada"
Exit Function
End If
DTA.cbSize = Len(DTA)
DTL.cbSize = &H5
Dim dia As SP_DEVICE_INTERFACE_DATA
dia.cbSize = &H0
Dim dd As SP_DEVINFO_DATA
dd.cbSize = &H0
cad = ""
lCount = 0
Dim nulo As new SP_DEVICE_INTERFACE_DETAIL_DATA
' Esto era asi
'do while not (SetupDiEnumDeviceInterfaces(hDev, &H0, TGUID, lCount, DTA) = &H0)
' Entra en un bucle interminable,que estoy haciendo mal?
do While not SetupDiEnumDeviceInterfaces(hDev, dia , TGUID, lCount, DTA)
' Tengo mis dudas si estoy utilizando bien las funciones
'call SetupDiGetDeviceInterfaceDetail(hDev, DTA, ByVal &H0, &H0, lSize, ByVal &H0)
Call SetupDiGetDeviceInterfaceDetail(hDev, dia, nulo , &H0, lSize, dd)
' Call SetupDiGetDeviceInterfaceDetail(hDev, DTA, DTL, ByVal lSize, &H0, ByVal &H0)
call SetupDiGetDeviceInterfaceDetail(hDev, DTA, DTL, lSize, &H0, dd)
If UBound(Split(DTL.strDevicePath, "#")) > 1 Then
cad = cad & Split(UCase(DTL.strDevicePath), "#")(2) & Chr(&HD)
End If
lCount = lCount + 1
loop
Call SetupDiDestroyDeviceInfoList(hDev)
If cad = "" Then cad = "No hay conexiones"
return cad
End Function
Si alguien tiene sugerencias o alguna informacion sobre las funciones de la API que comento, se los
agradeceria.
Saludos.
Cita de: Maurice_Lupin en 10 Noviembre 2011, 17:32 PM
' esto era: Call IIDFromString(StrPtr("{a5dcbf10-6530-11d2-901f-00c04fb951ed}"), TGUID)
' pero no encuentro un equivalente en NET de IIDFromString
' encontre por ahi que se podia crear un Guid asi, estara bien?
TGUID = New Guid(strvalue)
Fijate si esto ayuda
http://bytes.com/topic/visual-basic-net/answers/381152-how-declare-globally-unique-identifier-guid (http://bytes.com/topic/visual-basic-net/answers/381152-how-declare-globally-unique-identifier-guid)
Muchas gracias Hasseds por todo, logre solucionar hoy en la madrugada. Voy a postear el codigo, también encontre como detectar cuando se conecta/desconecta un USB. Lo posteo aqui mismo?
Yo utilizo el IDE http://www.icsharpcode.net/OpenSource/SD/Default.aspx para programar en VB.Net. Casi lo mismo que el VB.net 2005. Sólo que no hay que pagar licencia, eso lei. Corrijanme si estoy equivocado.
Gracias a Hasseds.
En esta pagina encontre buena info para llamar a las funciones de la API en VB.NET
http://pinvoke.net/default.aspx/setupapi.SetupDiEnumDeviceInterfaces
Imports System.Runtime.InteropServices
<StructLayout(LayoutKind.Sequential, Pack := 1)> _
Public Structure DeviceInterfaceData
Public Size As Integer
Public InterfaceClassGuid As Guid
Public Flags As Integer
Public Reserved As Integer
End Structure
<StructLayout(LayoutKind.Sequential, Pack := 1)> _
Public Structure DeviceInterfaceDetailData
Public Size As Integer
<MarshalAs(UnmanagedType.ByValTStr, SizeConst := 256)> _
Public DevicePath As String
End Structure
' SetupDiGetClassDevs: Retorna información sobre el dispositivo
<DllImport("setupapi.dll",EntryPoint:="SetupDiGetClassDevsW", SetLastError:=True, _
CharSet:=CharSet.Unicode, ExactSpelling:=True, PreserveSig:=True, _
CallingConvention:=CallingConvention.Winapi)> _
Private Shared Function SetupDiGetClassDevs( _
ByRef ClassGuid As GUID, _
ByVal Enumerator As Integer, _
ByVal hwndParent As Integer, _
ByVal Flags As Integer) As Integer
End Function
' SetupDiDestroyDeviceInfoList
<DllImport("setupapi.dll", _
EntryPoint:="SetupDiDestroyDeviceInfoList", _
SetLastError:=True, _
ExactSpelling:=True, _
PreserveSig:=True, _
CallingConvention:=CallingConvention.Winapi)> _
Private Shared Function SetupDiDestroyDeviceInfoList( _
ByVal DeviceInfoSet As Integer) As Boolean
End Function
<DllImport("setupapi.dll", SetLastError := True)> _
Public Shared Function SetupDiEnumDeviceInterfaces(ByVal lpDeviceInfoSet As IntPtr, ByVal nDeviceInfoData As UInteger, ByRef gClass As Guid, ByVal nIndex As UInteger, ByRef oInterfaceData As DeviceInterfaceData) As Boolean
End Function
<DllImport("setupapi.dll", SetLastError := True)> _
Public Shared Function SetupDiGetDeviceInterfaceDetail(ByVal lpDeviceInfoSet As IntPtr, ByRef oInterfaceData As DeviceInterfaceData, ByVal lpDeviceInterfaceDetailData As IntPtr, ByVal nDeviceInterfaceDetailDataSize As UInteger, ByRef nRequiredSize As UInteger, ByVal lpDeviceInfoData As IntPtr) As Boolean
End Function
<DllImport("setupapi.dll", SetLastError := True)> _
Public Shared Function SetupDiGetDeviceInterfaceDetail(ByVal lpDeviceInfoSet As IntPtr, ByRef oInterfaceData As DeviceInterfaceData, ByRef oDetailData As DeviceInterfaceDetailData, ByVal nDeviceInterfaceDetailDataSize As UInteger, ByRef nRequiredSize As UInteger, ByVal lpDeviceInfoData As IntPtr) As Boolean
End Function
' Funcion
Public Function FlashSerials() As String
Dim TGUID As GUID
Dim lCount As UInt32
Dim lSize As Integer = &H0
Dim DTL As new DeviceInterfaceDetailData
Dim DTA As new DeviceInterfaceData
Dim cad as String
TGUID = New Guid("{a5dcbf10-6530-11d2-901f-00c04fb951ed}")
Dim hDev As IntPtr = SetupDiGetClassDevs( TGUID, &H0 ,&H0, &H12)
If hDev = -1 Then
return "Nada"
Exit Function
End If
DTA.Size = Marshal.SizeOf(DTA)
DTL.Size = &H5
cad = ""
lCount = 0
While SetupDiEnumDeviceInterfaces(hDev, &H0, TGUID, lCount, DTA)
If Not SetupDiGetDeviceInterfaceDetail(hDev, DTA, IntPtr.Zero , 0, lSize, IntPtr.Zero ) Then
If SetupDiGetDeviceInterfaceDetail(hDev, DTA, DTL , lSize, lSize, IntPtr.Zero) Then
If Ubound(Split(DTL.DevicePath ,"#"))>1 then
cad = cad & Split(Ucase(DTL.DevicePath) ,"#")(2) & chr(10)
End If
End If
End if
lCount = lCount + 1
End while
SetupDiDestroyDeviceInfoList(hDev)
If cad = "" Then cad = "No hay conexiones"
return cad
End Function
Es codigo lo encontre en
http://tempuzfugit.wordpress.com/2007/06/05/deteccion-de-insercion-de-disco/
' Al sobreescribir este Metodo se puede detectar la acción de conectar/desconectar USB
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
'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
msgbox("Se inserto: " & FlashSerials())
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