8/31/2010

AjpdSoft - Configurar GRUB en Linux Ubuntu 8.10 con varios sistemas operativos

AjpdSoft - Configurar GRUB en Linux Ubuntu 8.10 con varios sistemas operativos

Os mostramos en este artículo cómo configurar el gestor de arranque múltiple GRUB (GRand Unified Bootloader) en GNU Linux Ubuntu 8.10. Lo haremos modificando directamente el fichero menu.lst, ubicado en /boot/grub. Os explicamos cómo modificarlo manualmente y cómo utilizar el administrador de arranque en modo gráfico StartUp-Manager. También os explicamos cómo añadir una imagen al GRUB.



Definición de GRUB

GRand Unified Bootloader (GRUB) es un gestor de arranque múltiple que se usa para iniciar dos o más sistemas operativos instalados en un mismo ordenador.

Un gestor de multiarranque es aquel que puede cargar cualquier archivo ejecutable y que contiene un archivo de cabecera multiarranque en los primeros 8 KB del archivo. La cabecera consiste en 32 bits de números, 32 de indicadores (flags), otros 32 de números, seguidos de información sobre la imagen ejecutable.

Una de las características más interesantes es que no es necesario instalar una partición nueva o un núcleo nuevo, pudiendo cambiar todos los parámetros en el arranque mediante la Consola de GRUB.

Mientras los gestores de arranque convencionales tienen una tabla de bloques en el disco duro, GRUB es capaz de examinar el sistema de archivos. Actualmente, soporta los siguientes sistemas de archivos:

  • ext2/ext3.
  • ReiserFS.
  • UFS.
  • VFAT, FAT16, FAT32.
  • NTFS.
  • JFS.
  • HFS.

Existen otros cargadores de arranque como LILO, SYSLINUX y los propios de sistemas como Windows, UNIX, etc.

GRUB realiza el siguiente proceso de inicio:

  1. Busca un dispositivo de inicio en la BIOS del equipo (como el disco duro) y pasa el control al registro maestro de inicio (Master Boot Record, MBR, los primeros 512 bytes del disco duro).
  2. El MBR contiene la fase 1 de GRUB, como el MBR solo admite 512 bytes, la fase 1 sólo carga la siguiente fase del GRUB (ubicado físicamente en cualquier parte del disco duro). La fase 1 puede cargar ya sea la fase 1.5 o directamente la 2.
  3. La fase 1.5 de GRUB está ubicada en los siguientes 30 kilobytes del disco duro. La fase 1.5 carga la fase 2.
  4. La fase 2 de GRUB (cargada por las fases 1 o 1.5) recibe el control, y presenta al usuario el menú de inicio de GRUB.
  5. GRUB carga el kernel (opción de arranque de un sistema operativo determinado con las opciones correspondientes) seleccionado por el usuario en la memoria y le pasa el control.

Modificación de las opciones de arranque de GRUB manualmente

Abriremos una ventana de terminal desde "Aplicaciones" - "Accesorios" - "Terminal", accede como superusuario "root" con el comando:

su - root

(para no acceder como root se puede utilizar el comando sudo...)

A continuación escribiremos el siguiente comando para acceder a la carpeta donde se encuentra el fichero menu.lst:

cd /boot/grub

A continuación ejecutaremos el siguiente comando Linux:

gedit menu.lst

AjpdSoft Configurar GRUB en Linux Ubuntu 8.10 con varios sistemas  operativos

En este fichero podremos configurar multitud de opciones del arranque de GRUB, por ejemplo podremos cambiar el texto que GRUB asigna a cada opción de arranque del GRUB de GNU Linux Ubuntu, desde el parámetro "title" de cada opción de arranque. En nuestro caso, para el arranque de Windows hemos modificado "title" poniendo "Windows XP Professional SP3 | Windows Vista Ultimate SP1":

AjpdSoft Configurar GRUB en Linux Ubuntu 8.10 con varios sistemas  operativos

También hemos cambiado "title" de la opción que indica otros sistemas operativos (que no son Linux), esta opción sólo sirve para separar las opciones de arranque de GNU Linux de las de Windows (u otros sistemas no Linux):

AjpdSoft Configurar GRUB en Linux Ubuntu 8.10 con varios sistemas  operativos

En el principio del fichero menu.lst hay un parámetro llamado "timeout" que indica, en segundos, el tiempo que tardará GRUB en cargar la opción de arranque por defecto si no se indica lo contrario:

AjpdSoft Configurar GRUB en Linux Ubuntu 8.10 con varios sistemas  operativos

En el parámetro "default" indicaremos el número de opción de arranque que se cargará por defecto si no se indica otra cosa:

AjpdSoft Configurar GRUB en Linux Ubuntu 8.10 con varios sistemas  operativos

Este número se especifica de la siguiente forma, por cada opción de arranque del fichero menu.lst, GRUB cuenta desde cero hasta la última opción de arranque, por orden. Por ejemplo, para estas opciones de arranque del fichero menu.lst del GRUB:

# --------------- OPCIÓN 0 -----------------
title Ubuntu 8.10, kernel 2.6.27-7-generic
uuid e24fc89f-cb44-407c-a64b-c750be36f4fd
kernel /boot/vmlinuz-2.6.27-7-generic root=UUID=e24fc89f-cb44-407c-a64b-c750be36f4fd ro quiet splash
initrd /boot/initrd.img-2.6.27-7-generic
quiet

# --------------- OPCIÓN 1 -----------------
title Ubuntu 8.10, kernel 2.6.27-7-generic (recovery mode)
uuid e24fc89f-cb44-407c-a64b-c750be36f4fd
kernel /boot/vmlinuz-2.6.27-7-generic root=UUID=e24fc89f-cb44-407c-a64b-c750be36f4fd ro single
initrd /boot/initrd.img-2.6.27-7-generic

# --------------- OPCIÓN 2 -----------------
title Ubuntu 8.10, memtest86+
uuid e24fc89f-cb44-407c-a64b-c750be36f4fd
kernel /boot/memtest86+.bin
quiet

### END DEBIAN AUTOMAGIC KERNELS LIST

# --------------- OPCIÓN 3 -----------------
# This is a divider, added to separate the menu items below from the Debian
# ones.
title Otros sistemas operativos:
root

# --------------- OPCIÓN 4 -----------------
# This entry automatically added by the Debian installer for a non-linux OS
# on /dev/sdb1
title Windows XP Professional SP3 | Windows Vista Ultimate SP1
root (hd1,0)
savedefault
makeactive
map (hd0) (hd1)
map (hd1) (hd0)
chainloader +1

En este ejemplo, si queremos que GRUB marque "Ubuntu 8.10, kernel 2.6.27-7-generic" como opción por defecto, en el parámetro "default", introduciremos "0" (sin las comillas). Para que marque "Windows XP Professional SP3 | Windows Vista Ultimate SP1" por defecto introduciremos "4" en "default".

Cuando hayamos modificado las opciones del fichero menu.lst, lo guardaremos y tras reiniciar GNU Linux Ubuntu podremos comprobar la nueva configuración de GRUB en el arranque del equipo.

Otras opciones de GRUB (menu.lst)

  • hiddenmenu: quitando las almoadillas a este parámetro (##) no aparecerá el menú de arranque de GRUB, sólo se mostrará si pulsamos la tecla Escape.
  • color cyan/blue white/blue: quitando la almoadilla (#) el menú GRUB aparecerá en color.
  • password: con este parámetro podremos indicar una contraseña para el arranque GRUB, por ejemplo "password miperro", también podremos poner el Hash MD5 de una contraseña con "password --md5 MD5_de_una_contraseña".
  • memtest86=true: añade una opción de arranque para testear la memoria RAM del equipo.

Modificación de las opciones de GRUB con StartUp-Manager

En primer lugar instalaremos startupmanager utilizando el comando Linux apt-get, para ello abriremos una ventana de terminal y ejecutaremos el siguiente comando:

sudo apt-get install startupmanager

AjpdSoft Configurar GRUB en Linux Ubuntu 8.10 con varios sistemas  operativos

Ver la salida del comando anterior

Tras la instalación de StartUp-Manager, lo ejecutaremos con el comando:

sudo startupmanager

AjpdSoft Configurar GRUB en Linux Ubuntu 8.10 con varios sistemas  operativos

En la primera pestaña del Administrador de Arranque "Opciones de arranque" podremos configurar lo siguiente:

  • Tiempo de espera: marcando la opción "Usar tiempo de espera en el menú del Cargador de arranque" podremos indicar, en "Tiempo de espera, en segundos" los segundos que tardará el gestor de arranque GRUB en establecer la opción por defecto (si no se especifica otra).
  • Sistema operativo por defecto: en este desplegable podremos indicar qué sistema operativo se arrancará de forma automática si no se especifica lo contrario. En nuestro caso, al tener un arranque múltiple con Windows y Linux, indicaremos a GRUB que por defecto arranque en Windows.
  • Pantalla: podremos indicar la resolución y profundidad del color.
  • Otros: varias opciones como "mostrar menú en el Cargador de arranque", "Mostrar pantalla de inicio en el Arranque" y "Mostrar texto durante el arranque".

AjpdSoft Configurar GRUB en Linux Ubuntu 8.10 con varios sistemas  operativos

En la siguiente pestaña, "Aspecto", podremos indicar:

  • Si queremos que GRUB aparezca en color en "Colores del menú del Cargador de arranque".
  • Tema del Cargador de arranque: en este apartado podremos indicar la imagen que GRUB colocará de fondo.

AjpdSoft Configurar GRUB en Linux Ubuntu 8.10 con varios sistemas  operativos

En la pestaña "Seguridad" podremos configurar los siguientes aspectos de GRUB:

  • Opciones de protección: marcando la opción "Proteger con contraseña el Cargador de arranque" conseguiremos que sólo puedan acceder al equipo los usuarios que sepa la contraseña. También podremos "Proteger con contraseña el modo de rescate" y las opciones antiguas de arranque.
  • Cambiar Contraseña: en este apartado podremos añadir la contraseña que los usuarios deberán saber para poder arrancar un sistema operativo del GRUB.

AjpdSoft Configurar GRUB en Linux Ubuntu 8.10 con varios sistemas  operativos

En la solapa "Avanzado" podremos realizar los siguientes ajustes en el GRUB:

  • Número de kernels: marcando "Limitar el número de kernels en el menú de arranque" e indicando el número máximo en "Número de kernels a mantener" indicaremos a GRUB que sólo muestre el número de kernels (revisiones o actualizaciones del núcleo o kernel) que le indiquemos, mostrará los más recientes primero.
  • Otros: en este apartado podremos "Crear opción de arranque para memtest86+", marcando esta opción nos aparecerá en el GRUB una línea que permitirá realizar un test de memoria del equipo, interesante cuando queramos comprobar el estado de la memoria RAM de nuestro sistema. También podremos "Crear opción de arranque para el modo recuperación", con esta opción marcada en el GRUB aparecerá una opción que permitirá arrancar GNU Linux Ubuntu en modo recuperación. Desde aquí también podremos "Actualizar automáticamente las opciones predeterminadas del arranque", crear un disco de rescate (opción interesante por si debido a alguna neglicencia o mala instalación de algún sistema operativo perdemos el GRUB, arrancando con este disquete podremos tener el GRUB). También podremos restaurar la confiuración original pulsando en "Restaurando la configuración original".

AjpdSoft Configurar GRUB en Linux Ubuntu 8.10 con varios sistemas  operativos

Ver cómo queda el fichero menu.lst

Mostrar una imagen en el GRUB (arranque del equipo) con StartUp-Manager

Utilizaremos como ejemplo el logotipo de AjpdSoft, partiendo de una imangen en jpg pulsaremos con el botón derecho del ratón, en el menú emergente de Linux Ubuntu seleccionaremos "Abrir con" y en el submenú que aparece seleccionaremos "Abrir con "Editor de imágenes GIMP":

AjpdSoft Configurar GRUB en Linux Ubuntu 8.10 con varios sistemas  operativos

A continuación realizaremos varias tareas:

  • Para que la imagen aparezca "bien" en GRUB como máximo debe tener 14 colores, puede superarlos pero tal vez no se vea bien.
  • El tamaño de la imagen no debe superar los 640x480 píxeles, puede superarlos pero tal vez no se vea bien.
  • Convertiremos la imagen a X PixMap (xpm), para ello accederemos al menú "Archivo" - "Guardar como...":

AjpdSoft Configurar GRUB en Linux Ubuntu 8.10 con varios sistemas  operativos

En la parte inferior, en el desplegable seleccionaremos "Imagen X PixMap (*.xpm), en la parte superior, en "Nombre" podremos un nombre para el fichero, por ejemplo "logo-grub.xpm":

AjpdSoft Configurar GRUB en Linux Ubuntu 8.10 con varios sistemas  operativos

Ahora comprimiremos la imagen logo-grup.xpm en GZ, para ello pulsaremos con el botón derecho sobre el fichero logo-grup.xpm, en el menú emergente seleccionaremos "Crear archivador...":

AjpdSoft Configurar GRUB en Linux Ubuntu 8.10 con varios sistemas  operativos

En "Archivador" pondremos el nombre que queramos", en el desplegable de tipos de compresión seleccionaremos GZ, pulsaremos "Crear" para generar el fichero comprimido:

AjpdSoft Configurar GRUB en Linux Ubuntu 8.10 con varios sistemas  operativos

En la pestaña "Aspecto" de StartUp-Manager pulsaremos en "Administrar temas del Cargador de arranque":

AjpdSoft Configurar GRUB en Linux Ubuntu 8.10 con varios sistemas  operativos

Pulsaremos el botón "+ Añadir":

AjpdSoft Configurar GRUB en Linux Ubuntu 8.10 con varios sistemas  operativos

Buscaremos el fichero comprimido anteriormente en GZ, logo-grup.xpm.gz y pulsaremos "Abrir":

AjpdSoft Configurar GRUB en Linux Ubuntu 8.10 con varios sistemas  operativos

En el desplegable de "Imagen de fondo del Grub" seleccionaremos "logo-grub", después marcaremos la opción "Usar una imagen de fondo para el menú del Cargador de arranque":

AjpdSoft Configurar GRUB en Linux Ubuntu 8.10 con varios sistemas  operativos

Ver cómo queda el fichero menu.lst

Anexo

Resultado de la ejecución del comando sudo apt-get install startupmanager

alonso@pcalonso:~$ sudo apt-get install startupmanager
[sudo] password for alonso:
Leyendo lista de paquetes... Hecho
Creando árbol de dependencias
Leyendo la información de estado... Hecho
Se instalaron de forma automática los siguientes paquetes y ya no son necesarios.
linux-headers-2.6.27-7 linux-headers-2.6.27-7-generic
Utilice «apt-get autoremove» para eliminarlos.
Se instalarán los siguientes paquetes extras:
imagemagick menu
Se instalarán los siguientes paquetes NUEVOS:
imagemagick menu startupmanager
0 actualizados, 3 se instalarán, 0 para eliminar y 0 no actualizados.
1 no instalados del todo o eliminados.
Necesito descargar 1953kB de archivos.
Se utilizarán 7647kB de espacio de disco adicional después de desempaquetar.
¿Desea continuar [S/n]? s
Des:1 http://es.archive.ubuntu.com intrepid/main imagemagick 7:6.3.7.9.dfsg1-2ubuntu3 [1424kB]
Des:2 http://es.archive.ubuntu.com intrepid/universe menu 2.1.40ubuntu1 [439kB]
Des:3 http://es.archive.ubuntu.com intrepid/universe startupmanager 1.9.11-1 [90,2kB]
Descargados 1953kB en 2s (858kB/s)
Seleccionando el paquete imagemagick previamente no seleccionado.
(Leyendo la base de datos ...
116042 ficheros y directorios instalados actualmente.)
Desempaquetando imagemagick (de .../imagemagick_7%3a6.3.7.9.dfsg1-2ubuntu3_amd64.deb) ...
Seleccionando el paquete menu previamente no seleccionado.
Desempaquetando menu (de .../menu_2.1.40ubuntu1_amd64.deb) ...
Seleccionando el paquete startupmanager previamente no seleccionado.
Desempaquetando startupmanager (de .../startupmanager_1.9.11-1_all.deb) ...
Procesando activadores para man-db ...
Procesando activadores para doc-base ...
Processing 2 added doc-base file(s)...
Registering documents with scrollkeeper...
Configurando system-tools-backends (2.6.0-1ubuntu1.1) ...
* Starting System Tools Backends system-tools-backends invoke-rc.d: initscript system-tools-backends, action "start" failed.
dpkg: error al procesar system-tools-backends (--configure):
el subproceso post-installation script devolvió el código de salida de error 1
Configurando imagemagick (7:6.3.7.9.dfsg1-2ubuntu3) ...

Configurando menu (2.1.40ubuntu1) ...

Procesando activadores para menu ...
Configurando startupmanager (1.9.11-1) ...

Procesando activadores para menu ...
Se encontraron errores al procesar:
system-tools-backends
E: Sub-process /usr/bin/dpkg returned an error code (1)
alonso@pcalonso:~$

Fichero menu.lst tras configuración con startupmanager

# menu.lst - See: grub(8), info grub, update-grub(8)
# grub-install(8), grub-floppy(8),
# grub-md5-crypt, /usr/share/doc/grub
# and /usr/share/doc/grub-doc/.

## default num
# Set the default entry to the entry number NUM. Numbering starts from 0, and
# the entry number 0 is the default if the command is not used.
#
# You can specify 'saved' instead of a number. In this case, the default entry
# is the entry saved with the command 'savedefault'.
# WARNING: If you are using dmraid do not use 'savedefault' or your
# array will desync and will not let you boot your system.
default 6

## timeout sec
# Set a timeout, in SEC seconds, before automatically booting the default entry
# (normally the first entry defined).
timeout 4

## hiddenmenu
# Hides the menu by default (press ESC to see the menu)
#hiddenmenu

# Pretty colours
#color cyan/blue white/blue

#A splash image for the menu
splashimage=/boot/grub/splashimages/logo-grub.xpm.gz

## password ['--md5'] passwd
# If used in the first section of a menu file, disable all interactive editing
# control (menu entry editor and command-line) and entries protected by the
# command 'lock'
# e.g. password topsecret
## password --md5 $1$gLhU0/$aW78kHK1QfV3P2b2znUoe/
#password topsecret

#
# examples
#
# title Windows 95/98/NT/2000
# root (hd0,0)
# makeactive
# chainloader +1
#
# title Linux
# root (hd0,1)
# kernel /vmlinuz root=/dev/hda2 ro
#

#
# Put static boot stanzas before and/or after AUTOMAGIC KERNEL LIST

### BEGIN AUTOMAGIC KERNELS LIST
## lines between the AUTOMAGIC KERNELS LIST markers will be modified
## by the debian update-grub script except for the default options below

## DO NOT UNCOMMENT THEM, Just edit them to your needs

## ## Start Default Options ##
## default kernel options
## default kernel options for automagic boot options
## If you want special options for specific kernels use kopt_x_y_z
## where x.y.z is kernel version. Minor versions can be omitted.
## e.g. kopt=root=/dev/hda1 ro
## kopt_2_6_8=root=/dev/hdc1 ro
## kopt_2_6_8_2_686=root=/dev/hdc2 ro
# kopt=root=UUID=e24fc89f-cb44-407c-a64b-c750be36f4fd ro

## default grub root device
## e.g. groot=(hd0,0)
# groot=e24fc89f-cb44-407c-a64b-c750be36f4fd

## should update-grub create alternative automagic boot options
## e.g. alternative=true
## alternative=false
# alternative=true

## should update-grub lock alternative automagic boot options
## e.g. lockalternative=true
## lockalternative=false
# lockalternative=false

## additional options to use with the default boot option, but not with the
## alternatives
## e.g. defoptions=vga=791 resume=/dev/hda5
# defoptions=quiet splash vga=794

## should update-grub lock old automagic boot options
## e.g. lockold=false
## lockold=true
# lockold=false

## Xen hypervisor options to use with the default Xen boot option
# xenhopt=

## Xen Linux kernel options to use with the default Xen boot option
# xenkopt=console=tty0

## altoption boot targets option
## multiple altoptions lines are allowed
## e.g. altoptions=(extra menu suffix) extra boot options
## altoptions=(recovery) single
# altoptions=(recovery mode) single

## controls how many kernels should be put into the menu.lst
## only counts the first occurence of a kernel, not the
## alternative kernel options
## e.g. howmany=all
## howmany=7
# howmany=all

## should update-grub create memtest86 boot option
## e.g. memtest86=true
## memtest86=false
# memtest86=true

## should update-grub adjust the value of the default booted system
## can be true or false
# updatedefaultentry=false

## should update-grub add savedefault to the default options
## can be true or false
# savedefault=false

## ## End Default Options ##

title Ubuntu 8.10, kernel 2.6.27-9-generic
uuid e24fc89f-cb44-407c-a64b-c750be36f4fd
kernel /boot/vmlinuz-2.6.27-9-generic root=UUID=e24fc89f-cb44-407c-a64b-c750be36f4fd ro quiet splash vga=794
initrd /boot/initrd.img-2.6.27-9-generic
quiet

title Ubuntu 8.10, kernel 2.6.27-9-generic (recovery mode)
uuid e24fc89f-cb44-407c-a64b-c750be36f4fd
kernel /boot/vmlinuz-2.6.27-9-generic root=UUID=e24fc89f-cb44-407c-a64b-c750be36f4fd ro single
initrd /boot/initrd.img-2.6.27-9-generic

title Ubuntu 8.10, kernel 2.6.27-7-generic
uuid e24fc89f-cb44-407c-a64b-c750be36f4fd
kernel /boot/vmlinuz-2.6.27-7-generic root=UUID=e24fc89f-cb44-407c-a64b-c750be36f4fd ro quiet splash vga=794
initrd /boot/initrd.img-2.6.27-7-generic
quiet

title Ubuntu 8.10, kernel 2.6.27-7-generic (recovery mode)
uuid e24fc89f-cb44-407c-a64b-c750be36f4fd
kernel /boot/vmlinuz-2.6.27-7-generic root=UUID=e24fc89f-cb44-407c-a64b-c750be36f4fd ro single
initrd /boot/initrd.img-2.6.27-7-generic

title Ubuntu 8.10, memtest86+
uuid e24fc89f-cb44-407c-a64b-c750be36f4fd
kernel /boot/memtest86+.bin
quiet

### END DEBIAN AUTOMAGIC KERNELS LIST

# This is a divider, added to separate the menu items below from the Debian
# ones.
title Otros sistemas operativos:
root

# This entry automatically added by the Debian installer for a non-linux OS
# on /dev/sdb1
title Windows XP Professional SP3 | Windows Vista Ultimate SP1
root (hd1,0)
savedefault
makeactive
map (hd0) (hd1)
map (hd1) (hd0)
chainloader +1

Tecnología empleada

Artículos relacionados

Créditos

Artículo realizado por Alonsojpd, miembro fundador del proyecto AjpdSoft, con la ayuda inestimable de kronxito.

AjpdSoft - Captura de errores profesional con EurekaLog en Delphi y Visual Studio .Net

AjpdSoft - Captura de errores profesional con EurekaLog en Delphi y Visual Studio .Net

Os explicamos en qué consiste EurekaLog y cómo usarlo para mostrar una captura de errores personalizada y profesional al usuario de nuestras aplicaciones. Todos aquellos errores no capturados por los desarrolladores serán capturados y mostrados de forma profesional por EurekaLog. Esta aplicación está disponible para lenguajes de programación Visual Studio .Net y Delphi.



EurekaLog para captura de errores en lenguajes de programación

Para todos aquellos desarrolladores de software que utilicen como lenguaje de programación alguna versión de Delphi o alguna versión de Visual Studio .Net, tienen disponible la herramienta EurekaLog. Se trata de una utilidad que una vez instalada en Delphi o Visual Studio .Net, realiza una captura de todos aquellos errores que se puedan producir en nuestras aplicaciones y que no hayan sido capturados expresamente por código.

Este sistema es muy versátil y personalizable, permite, entre otras cosas:

  • Enviar el error en formato efl, propio de EurekaLog, consultable por su propio visualizador EurekaLog Viewer. EurekaLog enviará un fichero con información completa sobre el error (módulos, procesos, datos del equipo, excepción, ensamblado, información pila CPU, etc.).
  • Permite enviar la información del error mediante email (cliente, servidor), mediante HTTP, HTTPS, compatible con BugZilla, FogBugz, Mantis).
  • Permite enviar los datos obtenidos del error en fichero comprimido y protegerlo con contraseña.
  • Permite enviar captura de pantalla junto con los datos del error.
  • Guarda en un fichero de log los errores que se van produciendo.
  • Permite personalizar el tipo de error: MS Classic (mostrará una ventana parecida a la de error de Windows), MessageBox (muestra un mensaje normal), EurekaLog (ventana al estilo EurekaLog). Por supuesto permite mostrar u ocultar las distintas opciones de envío de error, dirección web de soporte, adjuntar captura de pantalla, copiar al portapapeles, mostrar botón de detalles, etc.
  • Permite traducir todos los mensajes a cualquier idioma.
  • Permite filtrar por tipo de error, para motrar sólo aquellos errores que nos interese.
  • Permite seleccionar qué información se le mostrará al usuario: DLLs, BPLs, Borland Threads, Windows Threads, Procesos de Windows, Pila de CPU, Módulos del lenguaje de programación donde se produce el error, etc.

Sin duda se trata de la herramienta de captura de errores más detallada y profesional que existe, el único inconveniente es que es de pago. Pero merece la pena mencionarla pues cuesta unos 120 euros para una licencia de un desarrollador.

Instalar EurekaLog para Borland o Codegear Delphi

Descargaremos la versión de prueba (trial) que expirará en 30 días o bien la versión adquirida previo pago de la licencia correspondiente desde la URL:

http://www.eurekalog.com/downloads_delphi.php

Para la versión de prueba, descargaremos el fichero EurekaLog6-Trial.exe de 19MB de tamaño. Una vez descargado, lo ejecutaremos (si tenemos Delphi abierto, lo cerraremos antes de iniciar la instalación). Se iniciará el asistente de instalación de EurekaLog, pulsaremos "Next":

AjpdSoft Instalar y configurar EurekaLog para Borland o Codegear  Delphi

Leeremos los términos de licencia, si estamos de acuerdo marcaremos "I accept the agreement" y pulsaremos "Next":

AjpdSoft Instalar y configurar EurekaLog para Borland o Codegear  Delphi

Seleccionaremos la carpeta de instalación de EurekaLog, pulsaremos "Next":

AjpdSoft Instalar y configurar EurekaLog para Borland o Codegear  Delphi

El asistente de instalación de EurekaLog detectará los lenguajes de programación instalados para los que es compatible, marcaremos los lenguajes en los que deseemos que se instale, en nuestro caso Borland Delphi 6:

AjpdSoft Instalar y configurar EurekaLog para Borland o Codegear  Delphi

A continuación nos mostrará unas ventanas indicando cómo se mostrará EurekaLog en Borland Delphi 6 (en el menú "Proyect" - "EurekaLog Options":

AjpdSoft Instalar y configurar EurekaLog para Borland o Codegear  Delphi

En la paleta de componentes, en la pestaña "EurekaLog":

AjpdSoft Instalar y configurar EurekaLog para Borland o Codegear  Delphi

Por último nos indicará que en la subcarpeta Demos de la carpeta de instalación de EurekaLog existen varios ejemplos de uso de esta herramienta:

AjpdSoft Instalar y configurar EurekaLog para Borland o Codegear  Delphi

Para finalizar nos permitirá ver un video tutorial marcando "See the EurekaLog Video Tutorial". También nos permitirá activar EurekaLog por defecto para todos los proyectos que creemos en Delphi, para ello marcaremos "Activate by default EurekaLog on all projects":

AjpdSoft Instalar y configurar EurekaLog para Borland o Codegear  Delphi

Al abrir Borland Delphi 6 nos mostrará un aviso indicando que la versión es de prueba (si no hemos adquirido el producto):

AjpdSoft Instalar y configurar EurekaLog para Borland o Codegear  Delphi

Y ya podremos usarlo, configurarlo desde "Project" - "EurekaLog Options":

AjpdSoft Instalar y configurar EurekaLog para Borland o Codegear  Delphi

Configuración de EurekaLog en Borland Delphi 6 para la captura de errores profesional

Abriremos Delphi y abriremos la aplicación en la que queramos configurar EurekaLog (se puede configurar para todas las aplicaciones). Desde el menú "Project" seleccionaremos "EurekaLog Options":

AjpdSoft Configuración de EurekaLog en Borland Delphi 6 para la  captura de errores profesional

En "Email & Web send": desde esta pestaña podremos configurar el tipo de envío del error cuando se produzca (Email Client, SMTP Client, SMTP Server), también podremos activar el modo de envío por HTTP, HTTPS, FTP, BugZilla, FogBugz, Mantis, etc. Desde esta ventana configuraremos las opciones necesarias. En nuestro caso hemos probado la opción "SMTP Client", le indicamos el servidor SMTP, el usuario, la contraseña y el Email de destino y funciona perfectamente:

AjpdSoft Configuración de EurekaLog en Borland Delphi 6 para la  captura de errores profesional

Este es el Email que llega, con la capura de pantalla y el fichero zip con los datos del error recopilados por EurekaLog:

AjpdSoft Configuración de EurekaLog en Borland Delphi 6 para la  captura de errores profesional

Desde la pestaña "Send Options" podremos elegir las opciones de envío de los ficheros de información del error recopilados por EurekaLog. Podremos personalizar las siguientes opciones:

  • Show the send dialog: ocultar o mostrar el mensaje de envío de los datos del error.
  • Show success/failure msg.: mostrar al usuario el resultado del envío del mensaje de error.
  • Send entire Log file: enviará todo el fichero de log guardado (histórico).
  • Send an XML Log's copy: enviar también en formato XML.
  • Send a screenshot: permite enviar una captura de pantalla del equipo del usuario en el momento del envío.

También es posible añadir seguridad al fichero zip enviado protegiéndolo con una contraseña:

AjpdSoft Configuración de EurekaLog en Borland Delphi 6 para la  captura de errores profesional

Desde "Log File" podremos configurar y personalizar el contenido del fichero de log, la ubicación, el número máximo de errores que se guardará, no guardar errores duplicados, guardar el nombre del equipo, guardar el ensamblado y la pila de CPU, guardar los módulos y los procesos, etc.:

AjpdSoft Configuración de EurekaLog en Borland Delphi 6 para la  captura de errores profesional

Desde "Exception Dialogs" podremos indicar el tipo de mensaje que se mostrará al producirse un error:

AjpdSoft Configuración de EurekaLog en Borland Delphi 6 para la  captura de errores profesional

En la ventana anterior, en "Dialog Type", podremos seleccionar y configurar las opciones:

  • MS Classic: se mostrará un mensaje de error como el siguiente, muy parecido al de Windows XP:

AjpdSoft Configuración de EurekaLog en Borland Delphi 6 para la  captura de errores profesional

  • MessageBox: mostrará un mensaje normal (el que se mostraría sin EurekaLog), aunque si hemos indicado que se envíen los datos del error, una vez que se pulse "Aceptar" se enviarán estos datos por el método elegido:

AjpdSoft Configuración de EurekaLog en Borland Delphi 6 para la  captura de errores profesional

  • EurekaLog: es el más completo y más configurable, mostrará un mensaje como el siguiente:

AjpdSoft Configuración de EurekaLog en Borland Delphi 6 para la  captura de errores profesional

Pulsando en "Detalles" podremos ver todos los detalles del error: General (datos de la aplicación, datos del equipo, datos del error, etc.), Pila de llamadas (proceso, módulo, unidad, clase, procedimiento/método, línea, etc. Esta pestaña tal vez sea la más importante para el desarrollador pues muestra toda la información del error, la unidad y la línea de código donde se produce), Módulos y Procesos. Desde la ventana de "Detalles", si así lo hemos configurado, podremos enviar el informe del error, ir a la página web de soporte, adjuntar la captura de pantalla, copiarlo al portapapeles, etc.:

AjpdSoft Configuración de EurekaLog en Borland Delphi 6 para la  captura de errores profesional

Desde "Messages Texts" podremos traducir todos los textos que aparecen en la ventana de captura del error de EurekaLog al idioma que queramos:

AjpdSoft Configuración de EurekaLog en Borland Delphi 6 para la  captura de errores profesional

Desde "Exception Filters" podremos añadir qué acción personalizada realizar según el tipo de excepción que se produzca, esta pestaña es muy interesante para configurar si queremos que la aplicación muestre un tipo de ventana u otro o incluso que no haga nada según el tipo de excepción. Para ello pulsaremos en "Add":

AjpdSoft Configuración de EurekaLog en Borland Delphi 6 para la  captura de errores profesional

Introduciremos las siguientes opciones:

  • Class: la clase para la que mostraremos o no el tipo de ventana personalizado.
  • Handler: tipo de manejador (RTL ó EurekaLog).
  • Type: podremos seleccionar All, Handled, Unhandled.
  • Message: si lo dejamos en blanco mostrará el mensaje original del error seleccionado, sino mostrará el que introduzcamos.
  • Dialog: el tipo de diálogo que se mostrará: MS Classic, Unchanged, MessageBox, EurekaLog.
  • Action: Terminate o Restart.

AjpdSoft Configuración de EurekaLog en Borland Delphi 6 para la  captura de errores profesional

Desde "Advanced Options" podremos elegir y personalizar multitud de opciones: comprimir con zip el fichero a enviar, mostrar funciones DLL, mostrar funciones BPL, no guardar el nombre de las clases/procedimientos, activar Anti-Freeze, encriptar con contraseña, etc.:

AjpdSoft Configuración de EurekaLog en Borland Delphi 6 para la  captura de errores profesional

Desde "Build Options": desde aquí podremos indicar qué comando se ejecutará antes de compilar, cuando se ha compilado y si se produce un error de compilación):

AjpdSoft Configuración de EurekaLog en Borland Delphi 6 para la  captura de errores profesional

Además, EurekaLog permite añadir un componente no visual a las aplicaciones (no es obligatorio), desde la pestaña "EurekaLog" que permitirá al desarrollador realizar tareas específicas según los eventos que se produzcan:

  • OnAttachedFilesRequest.
  • OnCustomButtonClickNotify.
  • OnCustomDataRequest.
  • OnCustomWebFieldsRequest.
  • OnExceptionActionNotify.
  • OnExceptionNotify.
  • OnHandleExceptionNotify.
  • OnPasswordRequest.

AjpdSoft Configuración de EurekaLog en Borland Delphi 6 para la  captura de errores profesional

Desactivar el uso de EurekaLog para un proyecto Delphi

En el caso de que no queramos activar EurekaLog para algún proyecto, será suficiente con acceder a "Project" - "EurekaLog Options":

AjpdSoft Configuración de EurekaLog en Borland Delphi 6 para la  captura de errores profesional

Conclusiones sobre EurekaLog

Sin duda, como podemos observar, se trata del sistema de captura de errores más avanzado y personalizable del mercado para Delphi y Visual Studio .Net. Es compatible con las versiones de los lenguajes de programación Visual Studio .Net y Delphi.

Si bien es de pago, es recomendable probarlo para decidir si merece la pena adquirir una licencia, pues sus ventajas son muchas de cara a la captura, mucha más elegante, de esos errores típicos de Delphi de "Violación de acceso..." o "Error abstracto..." u otros.

Según nuestra experiencia desarrollando aplicaciones con Delphi, este sistema de captura de errores no controlados por los desarrolladores es muy útil de cara a ofrecer una buena imagen para el cliente (el usuario final). Podremos filtrar errores "extraños y desagradables" del tipo "Violación de acceso..." o "Error abstracto..." para que no aparezcan y en cambio nos llegue un email con todos los datos del error para su posterior depuración o mostrarlos al usuario de forma más agradable mostrando otro mensaje.

El inconveniente lógico es que es de pago, una pena. El otro inconveniente que hay que tener en cuenta es que cuando activamos EurekaLog para un proyecto Delphi, puede incrementar el tamaño del ejecutable en unos 340 kb, según las pruebas realizadas en nuestro laboratorio.

Artículos relacionados

Créditos

Artículo realizado íntegramente por Alonsojpd miembro fundador del proyecto AjpdSoft.

AjpdSoft - Cómo capturar errores genéricos ó excepciones en Borland ó Codegear Delphi

AjpdSoft - Cómo capturar errores genéricos ó excepciones en Borland ó Codegear Delphi

Este artículo muestra cómo capturar errores genéricos (de todo tipo), tratamiento de excepciones, en Delphi y mostrar (o no) mensajes a medida, personalizados al usuario final. Explica la diferencia entre las cláusulas "except" y "finally". También muestra un listado de las clases de excepción (class exception) y la descripción de cada una de ellas.



Estructuras básicas para la captura de errores o excepciones en Delphi

En primer lugar explicamos las dos estructuras básicas para la captura de errores en el lenguaje de programación Borland o Codegear Delphi:

  • Except: en la estructura que mostramos a continuación sólo se ejecutará el código que va entre el "except" y el "end" si se produce un error. Si no se produce un error se continuará con la ejecución lógica del programa, si se produce un error se ejecutará el código entre el "except" y el "end" y se detendrá la ejecución lógica de la aplicación:
    ...

    begin
    ... //código que estará fuera de la captura de errores, normalmente
    //se colocará fuera el código que sepamos que no puede dar errror

    try

    // Aquí irá el código susceptible de provocar errores

    except

    //colocaremos aquí el código que se ejecutará si se produce un error,
    //sólo se ejecutará si se produce un error

    end;
    end;

  • Finally: en la siguiente estructura el código que va entre el "finally" y el "end" se ejecutará siempre (tanto si se produce un error como si no). Este tipo de captura de errores suele ser usado para finalizar o liberar determinadas variables o estructuras que nos interese que siempre queden liberadas (tanto si se producen errores como si no):
    ...

    begin
    ... //código que estará fuera de la captura de errores, normalmente
    //se colocará fuera el código que sepamos que no puede dar errror

    try

    // Aquí irá el código susceptible de provocar errores

    finally

    //colocaremos aquí el código que se ejecutará tanto si
    //se produce un error como si no

    end;
    end;

Ejemplos de capturas de errores en Delphi con Except ó Finally

Ejemplos con try...except...end

Por ejemplo, podemos acotar un código susceptible de que se produzca una división por cero con un "try" y un "except" de la siguiente forma, además, podemos personalizar el mensaje de error que se producirá:

... 
var
numero1, numero2, numero3 : integer;
begin
numero1 := 0;
numero2 := 1;
try
numero3 := numero1 div numero2;
ShowMessage ('Esta línea no se ejecutará pues se producirá el error.');
except
on e : exception do
begin
ShowMessage ('Clase de error: ' + e.ClassName + chr(13) + chr(13) +
'Mensaje del error: ' + e.Message);
end;
end;
end;

Nota: si cambiamos el código dentro del Except por:

  except
raise;
end;

Mostrará el mensaje de error propio generado por Delphi, sin personalizar.

En el ejemplo anterior hemos utilizado el objeto "exception" que es la clase padre. Si queremos mostrar un mensaje aún más personalizado por cada tipo de error que se pueda prodicir utilizaremos el siguiente código:

... 
var
numero1, numero2, numero3 : integer;
begin
numero1 := 0;
numero2 := 1;
try
numero3 := numero1 div numero2;
ShowMessage ('Esta línea no se ejecutará pues se producirá el error.');
except
on e : EDivByZero do
begin
ShowMessage ('Ha intentado dividir un número por cero.');
end;
else
ShowMessage ('Se ha producido un error: ' + chr(13) + chr(13) +
'Clase de error: ' + e.ClassName + chr(13) + chr(13) +
'Mensaje del error: ' + e.Message);
end;
end;

Ejemplos con Try...Finally...End

Un ejemplo utilizando "finally" (código que siempre se ejecutará tanto si hay error como si no):

procedure TformMenuPrincipal.actCuentasEmailExecute(Sender: TObject);
var
formulario : TformCuentas;
begin
formulario := TformCuentas.Create(Application);
try
formulario.ShowModal;
finally
formulario.Free;
end;
end;

En este caso hemos utilizado un ejemplo que crea un formulario y lo muestra modal, si la línea "formualario.ShowModal" da un error (por cualquier causa) se ejecutará lo que haya en el "finally" y si no da error también, con lo cual, en este caso, nos aseguramos de que el formulario modal se libera siempre tras su ejecución.

Con lo cual utilizaremos "finally" siempre que nos interese que se ejecute código tanto si se produce un error como si no, por ejemplo cuando creamos un objeto y queramos que este se libere sea cual sea el resultado de la creación. Y utilizaremos "except" en los demás casos, cuando queramos que el código de error sólo se ejecute cuando éste se produzca.

Cómo guardar log de errores en una tabla con Delphi

Si queremos guardar los errores para poder consultarlos posteriormente en una tabla de una base de datos, podemos usar el siguiente código en la cláusula "except ... End":

  try
//Código susceptible de provocar un error
md.tcSpam.Open;
except
on e : exception do
begin
//ejecutamos procedure para insertar el mensaje de error en una tabla
insertarLog (now, 'Error', E.Classname + ' : ' + E.Message);
//mostramos el error al usuario
raise;
//realizamos otras tareas, como cerrar una tabla
md.tcSpam.Close;
end;
end;

En este caso "md.tcSpam.Open" es un TQuery con una consulta SQL asociada, si se produce algún error se ejecutará lo que haya dentro del "except", se ejecutará un procedimiento llamado "insertarLog" que, a su vez, inserta un registro en una base de datos para guardar los posibles errores de la aplicación. A continuación os mostramos el código del procedimiento "insertarLog":

procedure insertarLog (fecha : TDateTime; tipo : string; mensaje : string);
begin
md.tLog.Open;
md.tLog.Insert;
md.tLogFECHA.Value := fecha;
md.tLogTIPO.Value := tipo;
md.tLogTEXTO.Value := mensaje;
md.tLog.Post;
md.tLog.Close;
end;

Donde md es el nombre del módulo de datos (TDataModule) en el que está el TTable "tLog" que apunta a una tabla de la base de datos con la siguiente estructura (MySQL):

CREATE TABLE `log` (
`ID` int(10) NOT NULL auto_increment,
`FECHA` datetime default NULL,
`TEXTO` varchar(255) default NULL,
`TIPO` varchar(20) default NULL,
PRIMARY KEY (`ID`)
)

Aunque hemos de reconocer que no es conveniente utilizar funciones o procedimientos que puedan, a su vez, generar errores dentro de las cláusulas "except" ó "finally". Podríamos cambiar el código anterior por guardar el error en un fichero de texto plano, procedimiento que sería menos susceptible de generar errores que el de guardar en una base de datos.




Clases de excepciones en Delphi

A continuación os mostramos un listado de clases de excepciones de Borland Delphi 6:

Exception             Base class
EAbort Abort without dialog
EAbstractError Abstract method error
AssertionFailed Assert call failed
EBitsError Boolean array error
ECommonCalendarError Calendar calc error
EDateTimeError DateTime calc error
EMonthCalError Month calc error
EConversionError Raised by Convert
EConvertError Object convert error
EDatabaseError Database error
EExternal Hardware/Windows error
EAccessViolation Access violation
EControlC User abort occured
EExternalException Other Internal error
EIntError Integer calc error
EDivByZero Integer Divide by zero
EIntOverflow Integer overflow
ERangeError Out of value range
EMathError Floating point error
EInvalidArgument Bad argument value
EInvalidOp Inappropriate operation
EOverflow Value too large
EUnderflow Value too small
EZeroDivide Floating Divide by zero
EStackOverflow Severe Delphi problem
EHeapException Dynamic memory problem
EInvalidPointer Bad memory pointer
EOutOfMemory Cannot allocate memory
EInOutError IO error
EInvalidCast Object casting error
EInvalidOperation Bad component op
EMenuError Menu item error
EOSError Operating system error
EParserError Parsing error
EPrinter Printer error
EPropertyError Class property error#
EPropReadOnly Invalid property access
EPropWriteOnly Invalid property access
EThread Thread error
EVariantError Variant problem

EurekaLog para captura profesional de errores o excepciones en Delphi

En el siguiente artículo os mostramos qué es EurekaLog y cómo instalarlo y configurarlo para ser usado por los desarrolladores de Delphi, permitiendo mostrar una ventana cuando se produzca un error no capturado personalizada y con información avanzada:

Capura de errores profesional con EurekaLog en Delphi y Visual Studio .Net

Artículos relacionados

Créditos

Artículo realizado íntegramente por Alonsojpd miembro fundador del proyecto AjpdSoft.

8/28/2010

AjpdSoft - Uso de CAPICOM y Delphi para acceso a los certificados digitales

AjpdSoft - Uso de CAPICOM y Delphi para acceso a los certificados digitales

Explicamos en este artículo cómo usar la utilidad de Microsoft llamada CAPICOM, que se puede utilizar para firmar datos y código digitalmente, comprobar firmas digitales, proteger la privacidad de datos, hacer hash de datos, cifrar y descifrar datos, obtener datos de los certificados digitales instalados, etc. En el artículo explicamos cómo usar el SDK de CAPICOM con Borland (ahora Codegear) Delphi. Mostramos paso a paso cómo realizar una aplicación que encripte y desencripte datos y que obtenga los certificados digitales instalados mediante CAPICOM.



Qué es CAPICOM, para qué sirve

CAPICOM es un control ActiveX o una librería (según el caso) de Microsoft que proporciona una interfaz COM para Microsoft CryptoAPI (también llamada Cryptographic Application Programming Interface, Microsoft Cryptography API, ó CAPI). CAPICOM permite usar un conjunto de funciones de CryptoAPI para permitir a los desarrolladores de aplicaciones incorporar de forma sencilla la funcionalidad de firma digital y encriptación en sus aplicaciones. Debido a que utiliza COM, los desarrolladores de aplicaciones pueden acceder a esta funcionalidad en una serie de entornos de programación tales como Microsoft Visual Basic, Visual Basic Script, Active Server Pages (ASP), Microsoft JScript, C + +, Delphi, Java, PHP y otros.

CAPICOM se puede empaquetar como un control ActiveX, para ser instalado en los navegadores y permitir a los desarrolladores Web utilizarla en aplicaciones basadas en Web (ASP, PHP, etc.). Además, CAPICOM cuenta con un SDK (kit de desarrollo de software o Software Development Kit) con las librerías necesarias para que sea usado por lenguajes de programación para desarrollar aplicaciones de escritorio (Delphi, Visual Basic .Net, Visual Basic, etc.).

De esta forma, con CAPICOM podremos implementar la utilidad de uso de certificados digitales en nuestras aplicaciones casi sin esfuerzo, pues todas las funciones necerias para el acceso a estos certificados ya están implementadas y listas para ser usadas.

Descarga e instalación de Microsoft CAPICOM SDK

En primer lugar deberemos descargar e instalar el SDK de CAPICOM (Platform SDK Redistributable: CAPICOM), disponible gratuitamente en:

http://www.microsoft.com/downloads/details.aspx?FamilyID=860ee43a-a843-462f-abb5-ff88ea5896f6&DisplayLang=es

Instalaremos CAPICOM SDK ejecutando el fichero descargado capicom_dc_sdk.msi, se iniciará el asistente de instalación de CAPICOM 2.1.0.2 SDK, pulsaremos "Next":

AjpdSoft Cómo usar CAPICOM en Delphi para obtener los certificados  digitales instalados en un equipo

Leeremos los términos de licencia, si estamos de acuerdo marcaremos "I accept the terms in the License Agreement" y pulsaremos "Next":

AjpdSoft Cómo usar CAPICOM en Delphi para obtener los certificados  digitales instalados en un equipo

Indicaremos en "Location" la carpeta de destino de CAPICOM SDK (pulsando "Browse" podremos cambiarla), pulsaremos "Next" para continuar:

AjpdSoft Cómo usar CAPICOM en Delphi para obtener los certificados  digitales instalados en un equipo

Pulsaremos "Install" para iniciar la instalación definitiva de CAPICOM SDK:

AjpdSoft Cómo usar CAPICOM en Delphi para obtener los certificados  digitales instalados en un equipo

Una vez finalizada la instalación, pulsaremos "Finish":

AjpdSoft Cómo usar CAPICOM en Delphi para obtener los certificados  digitales instalados en un equipo

En realidad, la instalación de CAPICOM 2.1.0.2 SDK lo único que hace es descomprimir una carpeta en la carpeta de destino con los siguientes ficheros y subcarpetas:

AjpdSoft Cómo usar CAPICOM en Delphi para obtener los certificados  digitales instalados en un equipo

La carpeta que más nos interesa es "Lib" que contiene la librería "capicom.dll" necesaria para el funcionamiento de nuestra aplicación. Esta librería deberá estar en la carpeta del sistema, en C:WindowsSystem32 y correctamente registrada con "regsvr32.exe" o AjpdSoft Registro de OCX y DLL como explicamos aquí.

AjpdSoft Cómo usar CAPICOM en Delphi para obtener los certificados  digitales instalados en un equipo

Registro de la librería capicom.dll en Windows 7

Una vez descargado e instalado el software CAPICOM SDK copiaremos el fichero "capicom.dll" ubicado en la carpeta de instalación de CAPICOM, en la subcarpeta "LibX86":

AjpdSoft Registro de la librería capicom.dll en Windows 7

Lo pegaremos en la carpeta del sistema (system32):

AjpdSoft Registro de la librería capicom.dll en Windows 7

A continuación registraremos la librería capicom.dll o bien usando regsvr32.exe o bien utilizando AjpdSoft Registro de OCX y DLL, abriremos AjpdSoft Registro de OCX y DLL ejecutando el fichero "registroOCX.exe" en modo administrador, pulsando con el botón derecho sobre el fichero descargado y seleccionando "Ejecutar como administrador":

AjpdSoft Registro de la librería capicom.dll en Windows 7

Pulsaremos el botón "<<" para seleccionar el fichero capicom.dll:

AjpdSoft Registro de la librería capicom.dll en Windows 7

En "Tipo" seleccionaremos "DLL (*.dll)", buscaremos el fichero "capicom.dll" en la carpeta System32 de Windows y pulsaremos "Abrir":

AjpdSoft Registro de la librería capicom.dll en Windows 7

Pulsaremos en "Registrar":

AjpdSoft Registro de la librería capicom.dll en Windows 7

Si todo es correcto mostrará un mensaje como este:

AjpdSoft Registro de la librería capicom.dll en Windows 7

Con el texto:

El proceso de registro ha finalizado con el siguiente resultado:
Registrados: 1.
No registrados: 0

Nota: si tenemos activado el control de cuentas de usuario (UAC) de Windows 7, es posible que nos muestre algún mensaje de confirmación al que tendremos que respondier "Sí".

Cómo usar CAPICOM en Delphi para obtener los certificados digitales instalados en un equipo

Para el acceso a los certificados digitales desde Delphi y CAPICOM necesitaremos la librería capicom.dll correctamente registrada y el fichero CAPICOM_TLB.pas que podremos descargar del ejemplo de este artículo:

AjpdSoft Obtener datos certificados digitales

Abriremos Delphi, crearemos un nuevo proyecto, añadiremos algunos compentes al formulario principal: un TLisbBox (donde mostraremos los certificados digitales instalados en el equipo y los datos de los mismos), algunos TButton para realizar las acciones de obtener certificados, obtener certificados y sus datos, guardar información de certificados y salir de la aplicación. El formulario quedará de la siguiente forma:

AjpdSoft Cómo usar CAPICOM en Delphi para obtener los certificados  digitales instalados en un equipo

Añadiremos el siguiente código:

  • Para el botón "Obtener certificados" (que sólo obtendrá el nombre del certificado):
procedure TformCertificados.btObtenerCertificadosClick(Sender: TObject);
const
CAPICOM_CA_STORE = 'ca';
CAPICOM_MY_STORE = 'my';
CAPICOM_ADDRESS_BOOK_STORE = 'AddressBook';
CAPICOM_OTHER_STORE = 'other';
CAPICOM_ROOT_STORE = 'root';
var
carpetaAlmacen : IStore;
certificadosAlmacen : ICertificates;
certificadoActual : ICertificate2;
i, j: integer;
begin
lsCertificados.Clear;
carpetaAlmacen := CoStore.Create;
carpetaAlmacen.Open(CAPICOM_CURRENT_USER_STORE,
CAPICOM_MY_STORE, CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED or
CAPICOM_STORE_OPEN_INCLUDE_ARCHIVED or
CAPICOM_STORE_OPEN_EXISTING_ONLY);
certificadosAlmacen := carpetaAlmacen.Certificates as ICertificates2;
for i := 1 to certificadosAlmacen.Count do
begin
certificadoActual :=
IInterface(certificadosAlmacen.Item[i]) as ICertificate2;
lsCertificados.Items.Add (obtenerNombreNIFCertificado(
certificadoActual.GetInfo (CAPICOM_CERT_INFO_SUBJECT_SIMPLE_NAME)));
end;
end;
  • Para el botón "Obtener datos para exportación":
procedure TformCertificados.btObtenerDatosCertificadosClick(
Sender: TObject);
const
CAPICOM_CA_STORE = 'ca';
CAPICOM_MY_STORE = 'my';
CAPICOM_ADDRESS_BOOK_STORE = 'AddressBook';
CAPICOM_OTHER_STORE = 'other';
CAPICOM_ROOT_STORE = 'root';
var
carpetaAlmacen : IStore;
certificadosAlmacen : ICertificates;
certificadoActual : ICertificate2;
i, j: integer;
begin
lsCertificados.Clear;

carpetaAlmacen := CoStore.Create;
carpetaAlmacen.Open(CAPICOM_CURRENT_USER_STORE,
CAPICOM_MY_STORE, CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED or
CAPICOM_STORE_OPEN_INCLUDE_ARCHIVED or
CAPICOM_STORE_OPEN_EXISTING_ONLY);
certificadosAlmacen := carpetaAlmacen.Certificates as ICertificates2;
for i := 1 to certificadosAlmacen.Count do
begin
certificadoActual :=
IInterface(certificadosAlmacen.Item[i]) as ICertificate2;

lsCertificados.Items.Add('--------------------------------------');
lsCertificados.Items.Add (obtenerNombreNIFCertificado(
certificadoActual.GetInfo (CAPICOM_CERT_INFO_SUBJECT_SIMPLE_NAME)));
lsCertificados.Items.Add('--------------------------------------');

lsCertificados.Items.Add (' NOMBRE: ' +
certificadoActual.GetInfo (CAPICOM_CERT_INFO_SUBJECT_SIMPLE_NAME));

lsCertificados.Items.Add (' EMITIDO POR: ' +
certificadoActual.GetInfo (CAPICOM_CERT_INFO_ISSUER_SIMPLE_NAME));

lsCertificados.Items.Add (' EMAIL: ' +
certificadoActual.GetInfo (CAPICOM_CERT_INFO_SUBJECT_EMAIL_NAME));

lsCertificados.Items.Add (' FECHA EMISIÓN: ' +
DateTimeToStr(certificadoActual.ValidFromDate));

lsCertificados.Items.Add (' FECHA EXPIRACIÓN: ' +
DateTimeToStr(certificadoActual.ValidToDate));

lsCertificados.Items.Add (' NÚMERO DE SERIE: ' +
certificadoActual.SerialNumber);

lsCertificados.Items.Add (' SHA1 HASH: ' +
certificadoActual.Thumbprint);

lsCertificados.Items.Add (' NOMBRE DNS: ' +
certificadoActual.GetInfo (CAPICOM_CERT_INFO_SUBJECT_DNS_NAME));

lsCertificados.Items.Add (' NOMBRE UPN: ' +
certificadoActual.GetInfo (CAPICOM_CERT_INFO_SUBJECT_UPN));

if certificadoActual.Archived then
lsCertificados.Items.Add (' ARCHIVADO: SÍ')
else
lsCertificados.Items.Add (' ARCHIVADO: NO');

if certificadoActual.BasicConstraints.IsPresent then
begin
if certificadoActual.BasicConstraints.IsCritical then
lsCertificados.Items.Add (' CRÍTICO: SÍ')
else
lsCertificados.Items.Add (' CRÍTICO: NO');
if certificadoActual.BasicConstraints.IsCertificateAuthority then
lsCertificados.Items.Add (' AUTORIDAD DE CERTIFICACIÓN: SÍ')
else
lsCertificados.Items.Add (' AUTORIDAD DE CERTIFICACIÓN: NO');

if certificadoActual.BasicConstraints.IsPathLenConstraintPresent then
lsCertificados.Items.Add (
inttostr(certificadoActual.BasicConstraints.PathLenConstraint))
else
lsCertificados.Items.Add (' RESTRICCIÓN PATHLENCONSTRAINT NO PRESENTE');
end
else
lsCertificados.Items.Add (' RESTRICCIONES BÁSICAS NO PRESENTES');

if certificadoActual.KeyUsage.IsPresent then
begin
lsCertificados.Items.Add (' USO DE CLAVES:');
lsCertificados.Items.Add (' Critical = ' +
SiNo (certificadoActual.KeyUsage.IsCritical));
lsCertificados.Items.Add (' IsDigitalSignatureEnabled = ' +
SiNo (certificadoActual.KeyUsage.IsDigitalSignatureEnabled));
lsCertificados.Items.Add (' IsNonRepudiationEnabled = ' +
SiNo (certificadoActual.KeyUsage.IsNonRepudiationEnabled));
lsCertificados.Items.Add (' IsKeyEnciphermentEnabled = ' +
SiNo (certificadoActual.KeyUsage.IsKeyEnciphermentEnabled));
lsCertificados.Items.Add (' IsDataEnciphermentEnabled = ' +
SiNo (certificadoActual.KeyUsage.IsDataEnciphermentEnabled));
lsCertificados.Items.Add (' IsKeyAgreementEnabled = ' +
SiNo (certificadoActual.KeyUsage.IsKeyAgreementEnabled));
lsCertificados.Items.Add (' IsKeyCertSignEnabled = ' +
SiNo (certificadoActual.KeyUsage.IsKeyCertSignEnabled));
lsCertificados.Items.Add (' IsCRLSignEnabled = ' +
SiNo (certificadoActual.KeyUsage.IsCRLSignEnabled));
lsCertificados.Items.Add (' IsEncipherOnlyEnabled = ' +
SiNo (certificadoActual.KeyUsage.IsEncipherOnlyEnabled));
lsCertificados.Items.Add (' IsDecipherOnlyEnabled = ' +
SiNo (certificadoActual.KeyUsage.IsDecipherOnlyEnabled));
end
else
lsCertificados.Items.Add (' USO DE CLAVES: NO PRESENTE');

if certificadoActual.ExtendedKeyUsage.IsPresent then
lsCertificados.Items.Add (' USO DE CLAVE EXTENDIDO: PRESENTE')
else
lsCertificados.Items.Add (' USO DE CLAVE EXTENDIDO: NO PRESENTE');


if certificadoActual.Template.IsPresent Then
begin
lsCertificados.Items.Add (' PLANTILLA:');
lsCertificados.Items.Add (' Critical = ' +
BoolToStr (certificadoActual.Template.IsCritical));
lsCertificados.Items.Add (' Nombre = ' +
certificadoActual.Template.Name);
lsCertificados.Items.Add (' OID = ' +
certificadoActual.Template.OID.FriendlyName + ' (' +
certificadoActual.Template.OID.Value + ')');
lsCertificados.Items.Add (' Mayor = ' +
IntToStr(certificadoActual.Template.MajorVersion));
lsCertificados.Items.Add (' Menor = ' +
IntToStr(certificadoActual.Template.MinorVersion));
end
else
lsCertificados.Items.Add (' TEMPLATE: NO PRESENTE');


lsCertificados.Items.Add (' CLAVE PÚBLICA:');
lsCertificados.Items.Add (' Algoritmo = ' +
certificadoActual.PublicKey.Algorithm.FriendlyName + ' (' +
certificadoActual.PublicKey.Algorithm.Value + ')');
lsCertificados.Items.Add (' Tamaño = ' +
IntToStr (certificadoActual.PublicKey.Length) + ' bits');

if certificadoActual.HasPrivateKey then
begin
lsCertificados.Items.Add (' CLAVE PRIVADA:');
lsCertificados.Items.Add (' Nombre del contenedor = ' +
certificadoActual.PrivateKey.ContainerName);
lsCertificados.Items.Add (' Nombre único = ' +
certificadoActual.PrivateKey.UniqueContainerName);
lsCertificados.Items.Add (' Nombre del proveedor = ' +
certificadoActual.PrivateKey.ProviderName);
lsCertificados.Items.Add (' Accessible = ' +
SiNo (certificadoActual.PrivateKey.IsAccessible));
lsCertificados.Items.Add (' Protegida = ' +
SiNo (certificadoActual.PrivateKey.IsProtected));
lsCertificados.Items.Add (' Exportable = ' +
SiNo (certificadoActual.PrivateKey.IsExportable));
lsCertificados.Items.Add (' Eliminable = ' +
SiNo (certificadoActual.PrivateKey.IsRemovable));
lsCertificados.Items.Add (' Keyset equipo = ' +
SiNo (certificadoActual.PrivateKey.IsMachineKeyset));
lsCertificados.Items.Add (' Almacén Hardware = ' +
SiNo (certificadoActual.PrivateKey.IsHardwareDevice));
end
else
lsCertificados.Items.Add (' CLAVE PRIVADA NO ENCONTRADA');

if i < certificadosAlmacen.Count then
begin
lsCertificados.Items.Add('');
lsCertificados.Items.Add('');
end;
end;
end;
  • Botón para guardar los datos en fichero de texto "Guardar en fichero":
procedure TformCertificados.btGuardarDatosClick(Sender: TObject);
begin
dlGuardar.Title :=
'Guardar datos de certificados digitales en fichero';
dlGuardar.Filter :=
'Ficheros de texto (*.txt)|*.txt|Todos los ficheros (*.*)|*.*';
dlGuardar.FileName := 'certificados';
dlGuardar.DefaultExt := 'txt';
if dlGuardar.Execute then
lsCertificados.Items.SaveToFile(dlGuardar.FileName);
end;
Aquí se puede ver todo el código fuente de la aplicación AjpdSoft Obtener datos certificados digitales.

La aplicación AjpdSoft Obtener datos certificados digitales en funcionamiento

Ejecutaremos el fichero obtenerCertificados.exe (no necesita instalación pero sí necesita la DLL capicom.dll en el sistema correctamente registrada como explicamos aquí). Para obtener los certificados instalados pulsaremos el botón "Obtener certificados":

AjpdSoft La aplicación AjpdSoft Obtener datos certificados  digitales en funcionamiento

Nos mostrará el SUBJECT_SIMPLE_NAME de cada certificado instalado en el equipo:

AjpdSoft La aplicación AjpdSoft Obtener datos certificados  digitales en funcionamiento

Para obtener todos los datos de cada certificado digital instalado en el equipo pulsaremos el botón "Obtener datos para exportación":

AjpdSoft La aplicación AjpdSoft Obtener datos certificados  digitales en funcionamiento

Obtendrá los siguientes datos de cada certificado digital instalado en el equipo:

  • Nombre del certificado.
  • Entidad emisora.
  • Email del certificado.
  • Fecha de emisión.
  • Fecha de validez (caducidad o expiración).
  • Número de serie.
  • SHA 1 Hash.
  • Nombre DNS.
  • Nombre UPN.
  • Archivado.
  • Crítico.
  • Autoridad de certificación.
  • Restricción PathLenConstraint.
  • Restricciones básicas.
  • Uso de claves:
    • IsDigitalSignatureEnabled.
    • IsDigitalSignatureEnabled.
    • IsNonRepudiationEnabled.
    • IsNonRepudiationEnabled.
    • IsKeyEnciphermentEnabled.
    • IsKeyEnciphermentEnabled.
    • IsDataEnciphermentEnabled.
    • IsDataEnciphermentEnabled.
    • IsKeyAgreementEnabled.
    • IsKeyAgreementEnabled.
    • IsKeyCertSignEnabled.
    • IsKeyCertSignEnabled.
    • IsCRLSignEnabled.
    • IsCRLSignEnabled.
    • IsEncipherOnlyEnabled.
    • IsEncipherOnlyEnabled.
    • IsDecipherOnlyEnabled.
    • IsDecipherOnlyEnabled.
  • Uso de claves extendido.
  • Plantilla (Template):
    • Critical.
    • Nombre.
    • Mayor.
    • Menor.
  • Clave pública:
    • Algoritmo.
    • Tamaño.
  • Clave privada:
    • Nombre del contenedor.
    • Nombre único.
    • Nombre del proveedor.
    • Accessible.
    • Protegida.
    • Exportable.
    • Eliminable.
    • Keyset equipo.
    • Almacén Hardware.

Si queremos guardar el resultado de los datos obtenidos de los certificados digitales pulsaremos "Guardar en fichero":

AjpdSoft La aplicación AjpdSoft Obtener datos certificados  digitales en funcionamiento

Seleccionaremos la carpeta de destino y el nombre de fichero resultante con los datos de los certificados digitales instalados en el equipo, pulsaremos "Guardar":

AjpdSoft La aplicación AjpdSoft Obtener datos certificados  digitales en funcionamiento

Anexo

Código fuente source code aplicación AjpdSoft Obtener datos certificados digitales

A continuación os mostramos el código fuente (source code) completo en Borland Delphi 6 de la aplicación AjpdSoft Obtener datos certificados digitales:

unit UnidadMenuPrincipal;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, shellapi, StrUtils, Buttons, ComCtrls, CAPICOM_TLB;

type
TformCertificados = class(TForm)
lsCertificados: TListBox;
LWEB: TLabel;
Label1: TLabel;
bSalir: TButton;
btObtenerDatosCertificados: TBitBtn;
btGuardarDatos: TBitBtn;
dlGuardar: TSaveDialog;
btObtenerCertificados: TBitBtn;
StatusBar1: TStatusBar;
procedure LWEBClick(Sender: TObject);
procedure bSalirClick(Sender: TObject);
procedure btObtenerDatosCertificadosClick(Sender: TObject);
procedure btGuardarDatosClick(Sender: TObject);
procedure btObtenerCertificadosClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
formCertificados: TformCertificados;

implementation

{$R *.dfm}

function SiNo (valor : Boolean) : string;
begin
if valor then
Result := 'Sí'
else
Result := 'No';
end;

function obtenerNombreCertificado (nombre : string) : string;
var
nombreR : string;
begin
nombreR := AnsiReplaceStr(nombre, 'CN=NOMBRE', '');
nombreR := AnsiReplaceStr(nombre, 'NOMBRE', '');
nombreR := Trim (copy(nombreR, 1, pos(' - NIF', nombreR) - 1));
Result := nombreR;
end;

function obtenerNombreNIFCertificado (nombre : string) : string;
var
nombreR : string;
begin
nombreR := AnsiReplaceStr(nombre, 'CN=NOMBRE', '');
nombreR := AnsiReplaceStr(nombre, 'NOMBRE', '');
Result := nombreR;
end;


procedure TformCertificados.LWEBClick(Sender: TObject);
begin
ShellExecute(Handle, Nil, PChar('http://www.ajpdsoft.com'),
Nil, Nil, SW_SHOWNORMAL);
end;

procedure TformCertificados.bSalirClick(Sender: TObject);
begin
close;
end;

procedure TformCertificados.btObtenerDatosCertificadosClick(Sender: TObject);
const
CAPICOM_CA_STORE = 'ca';
CAPICOM_MY_STORE = 'my';
CAPICOM_ADDRESS_BOOK_STORE = 'AddressBook';
CAPICOM_OTHER_STORE = 'other';
CAPICOM_ROOT_STORE = 'root';
var
carpetaAlmacen : IStore;
certificadosAlmacen : ICertificates;
certificadoActual : ICertificate2;
i, j: integer;
begin
lsCertificados.Clear;

carpetaAlmacen := CoStore.Create;
carpetaAlmacen.Open(CAPICOM_CURRENT_USER_STORE,
CAPICOM_MY_STORE, CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED or
CAPICOM_STORE_OPEN_INCLUDE_ARCHIVED or
CAPICOM_STORE_OPEN_EXISTING_ONLY);
certificadosAlmacen := carpetaAlmacen.Certificates as ICertificates2;
for i := 1 to certificadosAlmacen.Count do
begin
certificadoActual :=
IInterface(certificadosAlmacen.Item[i]) as ICertificate2;

lsCertificados.Items.Add('--------------------------------------');
lsCertificados.Items.Add (obtenerNombreNIFCertificado(
certificadoActual.GetInfo (CAPICOM_CERT_INFO_SUBJECT_SIMPLE_NAME)));
lsCertificados.Items.Add('--------------------------------------');

lsCertificados.Items.Add (' NOMBRE: ' +
certificadoActual.GetInfo (CAPICOM_CERT_INFO_SUBJECT_SIMPLE_NAME));

lsCertificados.Items.Add (' EMITIDO POR: ' +
certificadoActual.GetInfo (CAPICOM_CERT_INFO_ISSUER_SIMPLE_NAME));

lsCertificados.Items.Add (' EMAIL: ' +
certificadoActual.GetInfo (CAPICOM_CERT_INFO_SUBJECT_EMAIL_NAME));

lsCertificados.Items.Add (' FECHA EMISIÓN: ' +
DateTimeToStr(certificadoActual.ValidFromDate));

lsCertificados.Items.Add (' FECHA EXPIRACIÓN: ' +
DateTimeToStr(certificadoActual.ValidToDate));

lsCertificados.Items.Add (' NÚMERO DE SERIE: ' +
certificadoActual.SerialNumber);

lsCertificados.Items.Add (' SHA1 HASH: ' +
certificadoActual.Thumbprint);

lsCertificados.Items.Add (' NOMBRE DNS: ' +
certificadoActual.GetInfo (CAPICOM_CERT_INFO_SUBJECT_DNS_NAME));

lsCertificados.Items.Add (' NOMBRE UPN: ' +
certificadoActual.GetInfo (CAPICOM_CERT_INFO_SUBJECT_UPN));

if certificadoActual.Archived then
lsCertificados.Items.Add (' ARCHIVADO: SÍ')
else
lsCertificados.Items.Add (' ARCHIVADO: NO');

if certificadoActual.BasicConstraints.IsPresent then
begin
if certificadoActual.BasicConstraints.IsCritical then
lsCertificados.Items.Add (' CRÍTICO: SÍ')
else
lsCertificados.Items.Add (' CRÍTICO: NO');
if certificadoActual.BasicConstraints.IsCertificateAuthority then
lsCertificados.Items.Add (' AUTORIDAD DE CERTIFICACIÓN: SÍ')
else
lsCertificados.Items.Add (' AUTORIDAD DE CERTIFICACIÓN: NO');

if certificadoActual.BasicConstraints.IsPathLenConstraintPresent then
lsCertificados.Items.Add (
inttostr(certificadoActual.BasicConstraints.PathLenConstraint))
else
lsCertificados.Items.Add (' RESTRICCIÓN PATHLENCONSTRAINT NO PRESENTE');
end
else
lsCertificados.Items.Add (' RESTRICCIONES BÁSICAS NO PRESENTES');

if certificadoActual.KeyUsage.IsPresent then
begin
lsCertificados.Items.Add (' USO DE CLAVES:');
lsCertificados.Items.Add (' Critical = ' +
SiNo (certificadoActual.KeyUsage.IsCritical));
lsCertificados.Items.Add (' IsDigitalSignatureEnabled = ' +
SiNo (certificadoActual.KeyUsage.IsDigitalSignatureEnabled));
lsCertificados.Items.Add (' IsNonRepudiationEnabled = ' +
SiNo (certificadoActual.KeyUsage.IsNonRepudiationEnabled));
lsCertificados.Items.Add (' IsKeyEnciphermentEnabled = ' +
SiNo (certificadoActual.KeyUsage.IsKeyEnciphermentEnabled));
lsCertificados.Items.Add (' IsDataEnciphermentEnabled = ' +
SiNo (certificadoActual.KeyUsage.IsDataEnciphermentEnabled));
lsCertificados.Items.Add (' IsKeyAgreementEnabled = ' +
SiNo (certificadoActual.KeyUsage.IsKeyAgreementEnabled));
lsCertificados.Items.Add (' IsKeyCertSignEnabled = ' +
SiNo (certificadoActual.KeyUsage.IsKeyCertSignEnabled));
lsCertificados.Items.Add (' IsCRLSignEnabled = ' +
SiNo (certificadoActual.KeyUsage.IsCRLSignEnabled));
lsCertificados.Items.Add (' IsEncipherOnlyEnabled = ' +
SiNo (certificadoActual.KeyUsage.IsEncipherOnlyEnabled));
lsCertificados.Items.Add (' IsDecipherOnlyEnabled = ' +
SiNo (certificadoActual.KeyUsage.IsDecipherOnlyEnabled));
end
else
lsCertificados.Items.Add (' USO DE CLAVES: NO PRESENTE');

if certificadoActual.ExtendedKeyUsage.IsPresent then
lsCertificados.Items.Add (' USO DE CLAVE EXTENDIDO: PRESENTE')
else
lsCertificados.Items.Add (' USO DE CLAVE EXTENDIDO: NO PRESENTE');


if certificadoActual.Template.IsPresent Then
begin
lsCertificados.Items.Add (' PLANTILLA:');
lsCertificados.Items.Add (' Critical = ' +
BoolToStr (certificadoActual.Template.IsCritical));
lsCertificados.Items.Add (' Nombre = ' +
certificadoActual.Template.Name);
lsCertificados.Items.Add (' OID = ' +
certificadoActual.Template.OID.FriendlyName + ' (' +
certificadoActual.Template.OID.Value + ')');
lsCertificados.Items.Add (' Mayor = ' +
IntToStr(certificadoActual.Template.MajorVersion));
lsCertificados.Items.Add (' Menor = ' +
IntToStr(certificadoActual.Template.MinorVersion));
end
else
lsCertificados.Items.Add (' TEMPLATE: NO PRESENTE');


lsCertificados.Items.Add (' CLAVE PÚBLICA:');
lsCertificados.Items.Add (' Algoritmo = ' +
certificadoActual.PublicKey.Algorithm.FriendlyName + ' (' +
certificadoActual.PublicKey.Algorithm.Value + ')');
lsCertificados.Items.Add (' Tamaño = ' +
IntToStr (certificadoActual.PublicKey.Length) + ' bits');

if certificadoActual.HasPrivateKey then
begin
lsCertificados.Items.Add (' CLAVE PRIVADA:');
lsCertificados.Items.Add (' Nombre del contenedor = ' +
certificadoActual.PrivateKey.ContainerName);
lsCertificados.Items.Add (' Nombre único = ' +
certificadoActual.PrivateKey.UniqueContainerName);
lsCertificados.Items.Add (' Nombre del proveedor = ' +
certificadoActual.PrivateKey.ProviderName);
lsCertificados.Items.Add (' Accessible = ' +
SiNo (certificadoActual.PrivateKey.IsAccessible));
lsCertificados.Items.Add (' Protegida = ' +
SiNo (certificadoActual.PrivateKey.IsProtected));
lsCertificados.Items.Add (' Exportable = ' +
SiNo (certificadoActual.PrivateKey.IsExportable));
lsCertificados.Items.Add (' Eliminable = ' +
SiNo (certificadoActual.PrivateKey.IsRemovable));
lsCertificados.Items.Add (' Keyset equipo = ' +
SiNo (certificadoActual.PrivateKey.IsMachineKeyset));
lsCertificados.Items.Add (' Almacén Hardware = ' +
SiNo (certificadoActual.PrivateKey.IsHardwareDevice));
end
else
lsCertificados.Items.Add (' CLAVE PRIVADA NO ENCONTRADA');

if i < certificadosAlmacen.Count then
begin
lsCertificados.Items.Add('');
lsCertificados.Items.Add('');
end;
end;
end;

procedure TformCertificados.btGuardarDatosClick(Sender: TObject);
begin
dlGuardar.Title :=
'Guardar datos de certificados digitales en fichero';
dlGuardar.Filter :=
'Ficheros de texto (*.txt)|*.txt|Todos los ficheros (*.*)|*.*';
dlGuardar.FileName := 'certificados';
dlGuardar.DefaultExt := 'txt';
if dlGuardar.Execute then
lsCertificados.Items.SaveToFile(dlGuardar.FileName);
end;

procedure TformCertificados.btObtenerCertificadosClick(Sender: TObject);
const
CAPICOM_CA_STORE = 'ca';
CAPICOM_MY_STORE = 'my';
CAPICOM_ADDRESS_BOOK_STORE = 'AddressBook';
CAPICOM_OTHER_STORE = 'other';
CAPICOM_ROOT_STORE = 'root';
var
carpetaAlmacen : IStore;
certificadosAlmacen : ICertificates;
certificadoActual : ICertificate2;
i, j: integer;
begin
lsCertificados.Clear;
carpetaAlmacen := CoStore.Create;
carpetaAlmacen.Open(CAPICOM_CURRENT_USER_STORE,
CAPICOM_MY_STORE, CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED or
CAPICOM_STORE_OPEN_INCLUDE_ARCHIVED or
CAPICOM_STORE_OPEN_EXISTING_ONLY);
certificadosAlmacen := carpetaAlmacen.Certificates as ICertificates2;
for i := 1 to certificadosAlmacen.Count do
begin
certificadoActual :=
IInterface(certificadosAlmacen.Item[i]) as ICertificate2;
lsCertificados.Items.Add (obtenerNombreNIFCertificado(
certificadoActual.GetInfo (CAPICOM_CERT_INFO_SUBJECT_SIMPLE_NAME)));
end;
end;

end.

Algunos errores típicos y su solución

  • Código de error: 0x80070005:

[Window Title]
RegSvr32

[Content]
Se cargó el módulo "C:WindowsSystem32capicom.dll", pero se produjo un error en la llamada a DllRegisterServer (código de error: 0x80070005).

Para obtener más información acerca de este problema, realice una búsqueda en Internet con el código de error como término de búsqueda.

[Aceptar]

Este error se suele producir en equipos con Windows Vista y Windows 7 (con UAC activado) o cuando el usuario actual no tiene permisos suficientes para escribir en el registro. Cuando intentamos registrar una DLL o un OCX, Windows debe escribir en el Registro de Configuraciones por lo que el usuario con el que intentamos realizar el registro debe tener permisos suficientes. En el caso de sistemas operativos con Windows Vista o Windows 7, si tenemos activo UAC (User Account Control) puede que nos impida escribir en el registro, por lo que tendremos que desactivarlo previamente, desde el botón "Iniciar", seleccionando "Ejecutar" (o bien pulsando la tecla de Windows + R), en la ventana de ejecutar escribiremos "msconfig" y pulsaremos "Aceptar":

AjpdSoft Desactivar UAC (Control de cuentas de Usuario)

En la pestaña "Herramientas" de la ventana "Configuración del sistema" haremos doble clic sobre "Cambiar configuración de UAC":

AjpdSoft Desactivar UAC (Control de cuentas de Usuario)

En la ventana de "Configuración de Control de cuentas de usuario" seleccionaremos "No notificarme nunca":

    No notificarme nunca cuando:

    • Un programa intente instalar software o realizar cambios en el equipo.
    • Realice cambios en la configuración de Windows.

Pulsaremos "Aceptar" (deberemos reiniciar el equipo para que los cambios se apliquen):

AjpdSoft Desactivar UAC (Control de cuentas de Usuario)

Nota importante: tras el registro del fichero capicom.dll (o de cualquier otro) es muy recomendable volver a activar UAC, de la misma forma que hemos explicado para desactivarlo.

Artículos relacionados

Créditos

Artículo realizado íntegramente por Alonsojpd miembro fundador del proyecto AjpdSoft.