Colabora .NET |
Control de Acceso Mediante Huellas Digitales[Utilizando el Microsoft FingerPrint Reader]
Fecha: 11/Oct/2006 (05/10/2006)
|
IntroducciónCuando en trabajo me pidieron buscarle solución al chequeo de horarios y control de asistencia del personal para evitar que un empleado marque la entrada de otro tome como mejor opción implementar un sistema que utilizara un lector de Huellas digitales para marar la hora de entrada y salida de los empleados; pero, como alguno de ustedes se abra dado cuenta que la mayoría de estos Lectores vienen si el SDK para Programarlos por lo que me vi en la obligación de encontrar uno que fuera gratuito o bien programarlo desde cero (Situación en la que no me quería ver debido a la fecha de entrega ;) ), entre tanto buscar encontré una librería Gratis para Desarrollar sobre Varios Lectores Entre ellos El Microsoft FingerPrint Reader que es el que yo utilice, publicada por GRIAULE llamado GrFinger FREE 4.1 disponible para descargar
Nota:
Ojo!!! Debes Instalar GrFinger_Free_Installer.exe. y Crear La Base de Datos en SQL Server 2005 para Poder Correr La aplicacionComencemos... Veamos El código:
El Código de la Clase: DBClass.vb Imports System.Data.SqlClient Imports System.Runtime.InteropServices Public Class TTemplate Public tpt(GrFingerXLib.GRConstants.GR_MAX_SIZE_TEMPLATE) As Byte Public Size As Long End Class Public Structure TTemplates Public ID As Integer Public Cedula As Integer Public template As TTemplate End Structure Public Class DBClass Dim connection As New SqlConnection Public Function OpenDB() As Boolean Try connection = New SqlClient.SqlConnection(My.Settings.AccesoConnectionString) Return True Catch Return False End Try End Function Public Sub closeDB() connection.Close() End Sub Public Sub clearEmpleadoDB(ByVal Cedula As Integer) Dim sqlCMD As SqlCommand = New SqlCommand("DELETE FROM Biometrica where Cedula=" & _ Cedula, connection) sqlCMD.Connection.Open() sqlCMD.ExecuteNonQuery() sqlCMD.Connection.Close() End Sub Public Function AddTemplate(ByRef template As TTemplate, _ ByVal Cedula As Integer, ByVal contDed As Integer) As Long Dim da As New SqlDataAdapter("select RowID, Cedula, Template from Biometrica", _ connection) da.InsertCommand = New SqlCommand( _ "INSERT INTO Biometrica (cedula, template) Values(" & _ Cedula & ", @template)", connection) da.InsertCommand.CommandType = CommandType.Text da.InsertCommand.Parameters.Add("@template", SqlDbType.VarBinary, _ template.Size, "template") connection.Open() Dim TBio As DataSet = New DataSet da.Fill(TBio, "Biometrica") Dim newRow As DataRow = TBio.Tables("Biometrica").NewRow() newRow("Cedula") = Cedula newRow("template") = template.tpt TBio.Tables("Biometrica").Rows.Add(newRow) ' ContHuellas += 1 Select Case contDed Case 1 If Principal.ActiveForm.Name = "Wizard" Then Wizard.PBDedos.Image = My.Resources.Indice Else AgregarHuellas.PBDedos.Image = My.Resources.Indice End If da.Update(TBio, "Biometrica") connection.Close() Case 2 If Principal.ActiveForm.Name = "Wizard" Then Wizard.PBDedos.Image = My.Resources.Indice Else AgregarHuellas.PBDedos.Image = My.Resources.Indice End If da.Update(TBio, "Biometrica") connection.Close() Case 3 If Principal.ActiveForm.Name = "Wizard" Then Wizard.PBDedos.Image = My.Resources.Indice Else AgregarHuellas.PBDedos.Image = My.Resources.Indice End If da.Update(TBio, "Biometrica") connection.Close() End Select Return newRow("ID") End Function Private Sub OnRowUpdated(ByVal sender As Object, ByVal args As SqlRowUpdatedEventArgs) End Sub Public Function getTemplates() As TTemplates() Dim ds As New DataSet Dim da As New SqlDataAdapter( _ "select RowID, Cedula, Template from Biometrica order by Cedula Desc", _ connection) Dim ttpts As TTemplates() Dim i As Integer da.Fill(ds) Dim tpts As DataRowCollection = ds.Tables(0).Rows ReDim ttpts(tpts.Count) If tpts.Count = 0 Then Return ttpts For i = 1 To tpts.Count - 1 ttpts(i).template = New TTemplate ttpts(i).ID = tpts.Item(i).Item("RowID") ttpts(i).Cedula = tpts.Item(i).Item("Cedula") ttpts(i).template.tpt = tpts.Item(i).Item("template") ttpts(i).template.Size = ttpts(i).template.tpt.Length Next Return ttpts End Function Public Function getTemplate(ByVal Cedula As Long) As Byte() Dim ds As New DataSet Dim da As New SqlDataAdapter( _ "select ID, Cedula, Template from Biometrica where Cedula = " & _ Cedula, connection) Dim tpt As New TTemplate da.Fill(ds) Dim tpts As DataRowCollection = ds.Tables(0).Rows If tpts.Count <> 1 Then Return Nothing Return tpts.Item(0).Item("template") End Function End Class Comencemos... Veamos El código:
El Código de la Clase: Util.vb Imports GrFingerXLib Imports Microsoft.VisualBasic 'Primero Creamos la estructura don vamos a almacenar la imagen obtenida del Lector de Huellas Public Structure RawImage 'img es donde Guardamos la data de la Imagen Public img As Object ' width es el ancho de la imagen Public width As Long ' width es el alto de la imagen Public height As Long ' width es la Resolucion de la imagen Public res As Long End Structure 'Creamos la Clase Util Public Class Util 'Definimos estas Constantes para hacer mas Limpio el Código Public Const ERR_CANT_OPEN_BD As Integer = -999 Public Const ERR_INVALID_ID As Integer = -998 Public Const ERR_INVALID_TEMPLATE As Integer = -997 ' Importamos las Funciones HDC Necesarias Private Declare Function GetDC Lib "user32" (ByVal hwnd As Int32) As Int32 Private Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Int32, _ ByVal hdc As Int32) As Int32 ' La Ultima Imagen Adquirida Public raw As RawImage ' Los Datos y Coincidencias de la Ultima Imagen Adquirida Public template As New TTemplate ' Hacemos Referencia a la Clase DBClass.vb Public DB As DBClass ' Lista donde se Mostraran Los Mensajes Obtenidos del Lector de HUellas Private _lbLog As ListBox 'PictureBox Donde Mostraremos la Imagen adquirida del Lector Private _pbPic As PictureBox ' Creamos la el Componente de la Libvreria para manejar el Lector de Huellas Private _GrFingerX As AxGrFingerXLib.AxGrFingerXCtrl ' Método Constructor Nulo de la Clase UTIL.vb Sub New() End Sub ' Método Constructor donde le decimos a la clase los controles que utilizaremos en el formulario basandonos en los que declaramos anteriormente Public Sub New(ByRef lbLog As ListBox, ByRef pbPic As PictureBox, _ ByRef GrFingerX As AxGrFingerXLib.AxGrFingerXCtrl) _lbLog = lbLog _pbPic = pbPic _GrFingerX = GrFingerX End Sub ' Método que Maneja Los Mensajes Public Sub WriteLog(ByVal message As String) _lbLog.Items.Add(message) _lbLog.SelectedIndex = _lbLog.Items.Count - 1 _lbLog.ClearSelected() End Sub ' Método que maneja la Errores arrojados por GrFingerX.dll Public Sub WriteError(ByVal errorCode As Integer) Select Case errorCode Case GRConstants.GR_ERROR_INITIALIZE_FAIL WriteLog("Error al Iniciar GrFingerX. (Error:" & errorCode & ")") Case GRConstants.GR_ERROR_NOT_INITIALIZED WriteLog("La Biblioteca de Clases no Ha Sido inicialiuzada. (Error:" & _ errorCode & ")") Case GRConstants.GR_ERROR_FAIL_LICENSE_READ WriteLog("Falla de Licencia. Verifique el manual (Error:" & errorCode & ")") MessageBox.Show("Falla de Licencia. Verifique el manual") Case GRConstants.GR_ERROR_NO_VALID_LICENSE WriteLog("La Licencia no es Válida. Verifique el Manual. (Error:" & _ errorCode & ")") MessageBox.Show("La Licencia no es Válida. Verifique el Manual.") Case GRConstants.GR_ERROR_NULL_ARGUMENT WriteLog("El Parámetro tiene un Valor Nulo. (Error:" & errorCode & ")") Case GRConstants.GR_ERROR_FAIL WriteLog("Error Creando Imagen. (Error:" & errorCode & ")") Case GRConstants.GR_ERROR_ALLOC WriteLog("Error Creando El Contexto. Volcado de Memoria. (Error:" & _ errorCode & ")") Case GRConstants.GR_ERROR_PARAMETERS WriteLog("Uno o Mas Parametros Está fuera de Rango. (Error:" & errorCode & ")") Case GRConstants.GR_ERROR_WRONG_USE WriteLog("No Se Puede Inicializar esta Funcion en este Momento. (Error:" & _ errorCode & ")") Case GRConstants.GR_ERROR_EXTRACT WriteLog("Falló al Obtener Template. (Error:" & errorCode & ")") Case GRConstants.GR_ERROR_SIZE_OFF_RANGE WriteLog("La Imagen Obtenida es Demasiado Grande o Pequeña. (Error:" & _ errorCode & ")") Case GRConstants.GR_ERROR_RES_OFF_RANGE WriteLog("La Imagen Tiene Muy Alta o Muy Baja resolution. (Error:" & _ errorCode & ")") Case GRConstants.GR_ERROR_CONTEXT_NOT_CREATED WriteLog("No se Pudo Crear el Contexto. (Error:" & errorCode & ")") Case GRConstants.GR_ERROR_INVALID_CONTEXT WriteLog("El Contexto No Existe. (Error:" & errorCode & ")") Case GRConstants.GR_ERROR_CONNECT_SENSOR WriteLog("Ocurrio un Error Cuando se Inicializaba el Lector. (Error:" & _ errorCode & ")") Case GRConstants.GR_ERROR_CAPTURING WriteLog("Error de Captura. (Error:" & errorCode & ")") Case GRConstants.GR_ERROR_CANCEL_CAPTURING WriteLog("Error al Finalizar Captura. (Error:" & errorCode & ")") Case GRConstants.GR_ERROR_INVALID_ID_SENSOR WriteLog("El idSensor es Invalido. (Error:" & errorCode & ")") Case GRConstants.GR_ERROR_SENSOR_NOT_CAPTURING WriteLog("El Sensor no está Capturando. (Error:" & errorCode & ")") Case GRConstants.GR_ERROR_INVALID_EXT WriteLog("El archivo Tiene una Extension Desconocida. (Error:" & _ errorCode & ")") Case GRConstants.GR_ERROR_INVALID_FILENAME WriteLog("El Nombre del Archivo es Inválido. (Error:" & errorCode & ")") Case GRConstants.GR_ERROR_INVALID_FILETYPE WriteLog("El Tipo de Archivo es Inválido. (Error:" & errorCode & ")") Case GRConstants.GR_ERROR_SENSOR WriteLog("El Lector Arrojó Un Error. (Error:" & errorCode & ")") Case ERR_INVALID_TEMPLATE WriteLog("Template Invalido. (Error:" & errorCode & ")") Case ERR_INVALID_ID WriteLog("ID Invalido. (Error:" & errorCode & ")") Case ERR_CANT_OPEN_BD WriteLog("Error al Conectar La Base de Datos. (Error:" & errorCode & ")") Case Else WriteLog("Error:" & errorCode) End Select End Sub 'Verificamos si la Data Obtenida de la Imagen es Válida Private Function TemplateIsValid() As Boolean ' Verifica el tamaño del Lector Return template.Size > 0 End Function ' Método que Inicializa el Uso Lector Public Function InitializeGrFinger() As Integer Dim err As Integer DB = New DBClass ' Abre la Base de Datos If DB.OpenDB() = False Then Return ERR_CANT_OPEN_BD ' creamos un nuevo template template.Size = 0 ' Creamos La Imagen raw.img = Nothing raw.width = 0 raw.height = 0 ' Guardamos el Resultado de la Inicializacion del Lector err = _GrFingerX.Initialize() ' Si es menor que 0 es porque ocurrio un error con el lector sea de lectura y/o de conexion If err < 0 Then Return err Return _GrFingerX.CapInitialize() End Function ' Método que Finaliza la Captura y el Uso del Lector de Huellas Public Sub FinalizeGrFinger() _GrFingerX.Finalize() _GrFingerX.CapFinalize() End Sub ' Obtiene la Imagen del Lector y la Muestra en el PictureBox Public Sub PrintBiometricDisplay(ByVal biometricDisplay As Boolean, ByVal context As Integer) ' Maneja la Imagen de Un Dedo Dim handle As System.Drawing.Image = Nothing ' HDC de la Pantalla Dim hdc As Integer = GetDC(0) If biometricDisplay Then ' Obtiene la Imagen con la Informacion Biométrica _GrFingerX.BiometricDisplay(template.tpt, raw.img, raw.width, _ raw.height, raw.res, hdc, _ handle, context) Else _GrFingerX.CapRawImageToHandle(raw.img, raw.width, raw.height, hdc, handle) End If ' Dibuja la Imagen Obtenida en el PictureBox If Not (handle Is Nothing) Then _pbPic.Image = handle _pbPic.Update() End If ' Quitamos de Memoria El HDC de la Pantalla Obtenido ReleaseDC(0, hdc) End Sub ' Guarda la Data de la Huella Digital Obtenida en la Base de Datos Public Function Enroll(ByVal contded As Integer, ByVal Cedula As String) As Integer ' Verifica si la Data de la Huella Obtenida es Valida If TemplateIsValid() Then ' Guarda la Huella digital Obtenida, con la Cedula de la Persona y Genera un ID para la Huella Return DB.AddTemplate(template, Cedula, contded) Else Return -1 End If End Function Function ExtractTemplate() As Integer Dim ret As Integer template.Size = template.tpt.Length ret = _GrFingerX.Extract(raw.img, raw.width, raw.height, raw.res, template.tpt, _ template.Size, GRConstants.GR_DEFAULT_CONTEXT) If ret < 0 Then template.Size = 0 Return ret End Function Public Function Identify(ByRef score As Integer) As Integer Dim ret As Integer Dim i As Integer If Not TemplateIsValid() Then Return ERR_INVALID_TEMPLATE ret = _GrFingerX.IdentifyPrepare(template.tpt, GRConstants.GR_DEFAULT_CONTEXT) If ret < 0 Then Return ret Dim templates As TTemplates() = DB.getTemplates() For i = 1 To templates.Length - 1 If Not (templates(i).template Is Nothing) Then ret = _GrFingerX.Identify(templates(i).template.tpt, score, _ GRConstants.GR_DEFAULT_CONTEXT) End If If ret = GRConstants.GR_MATCH Then Return templates(i).ID End If If ret < 0 Then Return ret Next Return GRConstants.GR_NOT_MATCH End Function Public Function Verify(ByVal id As Integer, ByRef score As Integer) As Integer Dim tptref As Byte() If Not (TemplateIsValid()) Then Return ERR_INVALID_TEMPLATE tptref = DB.getTemplate(id) If tptref Is Nothing Then Return ERR_INVALID_ID Return _GrFingerX.Verify(template.tpt, tptref, score, GRConstants.GR_DEFAULT_CONTEXT) End Function Public Function ObtenerNombre(ByVal Cedula As String) As String Dim NomComp As String Dim cn As New System.Data.SqlClient.SqlConnection(My.Settings.AccesoConnectionString) Dim cmd As New System.Data.SqlClient.SqlCommand( _ "Select Nombre, Apellido From Empleados Where Cedula='" _ & Cedula & "'", cn) cn.Open() Dim rd As System.Data.SqlClient.SqlDataReader = cmd.ExecuteReader() If rd.Read Then NomComp = Trim(rd.Item("Nombre").ToString) & " " & Trim(rd.Item("Apellido").ToString) Return NomComp Else Return "" End If cn.Close() End Function End Class Bueno., espero que sea de su utilidad éste artículo.... Aqui les dejo algunas de las pantallas para que se hagan una idea de lo que les estoy presentando., el sistema es completamente funcianal y de libre distribución: 1.- Pantalla de Bienvenida...
2.- Pantalla de Menu Principal...
3.- Pantalla de Chequeo del Sistema...
4.- Pantalla de registro de Empleados...
5.- Pantalla de Modificacion de Empleados...
6.- Pantalla de Algunos de los Reportes...
7.- Pantalla de Control de Documentos del Personal...
8.- Pantalla de Solicitudes de Permisos...
Anímense a bajar el Código y ayudarme también a mejorar lo que ya tengo. Espacios de nombres usados en el código de este artículo:System.Data
|
Código de ejemplo (ZIP): |
Fichero con el código de ejemplo:
IvanElias_ControlAcceso_VB.zip - 1.45 MB
|