Hojas de cálculo en Excel - página principal

Leer el número de serie de los discos

Hoy os presento una utilidad que puede servirle a aquellas personas que tengan una aplicación comercial realizada en excel. Como “aplicación comercial”, me estoy refiriendo a una aplicación desarrollada en excel, y que vendéis ya sea a empresas o a particulares. Si habéis decidido que vuestra aplicación no sea de libre distribución, quizás esto os pueda servir.

Imaginemos que habéis vendido una aplicación financiera que sirve para analizar una compañía, y en la que habéis invertido cientos de horas hasta dejarla, simplemente perfecta. Imaginemos que vendéis esa aplicación a una empresa, por la módica cantidad de 30 euros. ¿Qué os parecería ver que vuestra aplicación acaba en todos los PC’s, de todos los directores financieros, de todas y cada una de las empresas, porque se la han descargado de la red?. No parece muy lógico, si te has decantado por un modelo de negocio basado en la distribución de una aplicación, que requiere una contraprestación económica.

¿Qué podemos hacer, para evitar la libre distribución de esa aplicación?. Por una parte, podemos impedir que a un fichero se le cambie el nombre, y evitar que otra persona o empresa le ponga el nombre que a él se le antoje. Pero eso no es suficiente para evitar que nuestra aplicación circule impunemente por la red, sin haber pagado su correspondiente licencia.

¿Qué más podemos hacer?. Pues podemos controlar las máquinas en las que se ejecuta la aplicación. Quizás te preguntes “¿a qué te refieres con eso de controlar?”. Pues a algo tan sencillo –en principio-, como es leer el disco (o los discos) instalados o conectados en el PC del usuario que ha adquirido tu aplicación, e impedir que la misma se ejecute en otros PC’s que no sean ese. Hombre, siempre podremos darle al usuario un margen, por si su disco duro le ha petado, o si ejecuta la aplicación desde una llave USB. En estos casos, podemos controlar el número de ejecuciones de la aplicación, e impedir por ejemplo que ese libro de excel se abra en más de 2, de 3, de 5, o de X ordenadores.

Para leer el número de serie de los discos (extraíbles o fijos) de un PC, he partido del código que he encontrado en la red, y que permite hacer esto que nos proponemos. Hay varios ejemplos más, unos que utilizan el objeto FileSystemObject, y otros que usan otros métodos, pero el que realmente “lee” el número de serie de los discos, es este que he encontrado en la red:


Sub AveriguarNumeroDeSerieDeDiscos()
Dim oWMI As Object, Discos As Object, Disco As Object
Set oWMI = GetObject("WINMGMTS:")
Set Discos = oWMI.instancesof("Win32_PhysicalMedia")
For Each Disco In Discos
MsgBox "Serie: " & Disco.serialnumber
Next
Set Disco = Nothing
Set Discos = Nothing
Set oWMI = Nothing
End Sub

Me he permitido añadir alguna cosilla a ese macro, para que haga lo siguiente:

1.- En la hoja3 (el nombre interno VBA de la hoja, no el nombre que tiene la pestaña, aunque puede que coincidan) escribiremos todos los números de serie con los que nos encontremos, siempre y cuando no tengamos ya registrado uno de los números de serie de los discos presentes en ese PC. La hoja3 estará oculta (la haremos visible para trabajar con ella, y posteriormente la ocultaremos).

2.- Permitiremos que nuestra aplicación se pueda ejecutar en 5 ordenadores diferentes (podéis cambiar esa cifra). En caso de ejecutarla en un sexto ordenador, el libro de excel se cerraría automáticamente.

Tenemos una limitación, y es que las memorias flash no nos devuelven ningún número de serie, por eso tenemos que controlar todos los discos presentes en el PC. Si distribuimos nuestra aplicación, y ésta se ejecuta desde una llave USB, y no leyéramos el disco duro, entonces estaríamos permitiendo que Pepito le pasase la aplicación a Menganito y a sus 50 amigos, porque no podemos leer el número de serie de la llave USB (al menos este macro que encontré, no lo hace). Leyendo el número de serie de todos los discos, sabremos con toda certeza, si la aplicación se ejecuta en diferentes ordenadores, incluso si ésta se ejecuta desde una llave USB (si la llave USB la pinchamos en más de 5 ordenadores, se bloqueará la aplicación, porque a pesar de estar siempre en la misma USB, el usuario está incumpliendo las condiciones: no se puede ejecutar la aplicación en más de 5 PC’s distintos).

Bueno, aquí os dejo el código completo, y debidamente comentado. Ojo, debéis copiarlo y pegarlo en ThisWorkbook, dentro de Microsoft Excel Objetos. También lo podéis copiar y pegar en un módulo, con el nombre de Sub Auto_open(), en lugar de Private Sub Workbook_Open().

Por supuesto, no hace falta que os diga que si deseáis utilizar este código en vuestras aplicaciones, tendréis que proteger el código VBA, poniéndole una contraseña desde Herramientas, seleccionando Propiedades de VBA Project…, y desde la pestaña Protección. Desde ahí podremos bloquear la visualización, poniéndole una muesca a esa opción, y pondremos el password dos veces, una de ellas para confirmarlo:

Private Sub Workbook_Open()
'Desactivamos las teclas de cancelación de macros
Application.EnableCancelKey = xlDisabled
'Ocultamos el procedimiento
Application.ScreenUpdating = False
'Mostramos la Hoja3
Hoja3.Visible = xlSheetVisible
'omitimos los mensajes de aviso
Application.DisplayAlerts = False
'Seleccionamos la hoja3
Hoja3.Select
'Selecionamos la celda A1
Range("A1").Select
'Informamos del número máximo de ordenadores
'donde se puede ejecutar la aplicación

maximo_de_ordenadores = 5
'Empezamos...
Set oWMI = GetObject("WINMGMTS:")
Set Discos = oWMI.instancesof("Win32_PhysicalMedia")
'Para el conjunto de discos de ese PC...
For Each Disco In Discos
'leemos el número de serie, eliminando
'previamente los espacios vacios del
'principio y del final del número de serie

numero_de_serie = Trim(Disco.serialnumber)
'si no tiene número de serie (como las
'memorias flash, por ejemplo), que
'ponga: "Memoria flash o similar"

If IsNull(numero_de_serie) Then numero_de_serie = "Memoria flash o similar"
'y lo escribimos a partir de la primera
'celda vacía que encontremos, siempre
'y cuando no tengamos registrado ya ese
'número de serie del disco

Do While Not IsEmpty(ActiveCell)
'comprobamos si el valor de la celda
'es igual o no al número de serie del disco
'duro que estamos leyendo en este momento

If ActiveCell <> Trim(numero_de_serie) Then
'Si es distinto, bajamos a la fila siguiente
ActiveCell.Offset(1, 0).Select
Else
'Si es igual, entonces finalizamos el macro
'pero antes ocultamos la Hoja3 al máximo

Hoja3.Visible = xlSheetVeryHidden
'Grabamos el fichero
ThisWorkbook.Save
'finalizamos el macro
Exit Sub
End If
Loop
ActiveCell = numero_de_serie
'pasamos a la siguiente fila
ActiveCell.Offset(1, 0).Select
Next
Set Disco = Nothing
Set Discos = Nothing
Set oWMI = Nothing
'ponemos en B1 el número de ordenador en el
'que se ha ejecutado la aplicación, controlando
'que no se pase del límite máximo
'limpiamos los objetos

If Range("B1") = "" Then
Range("B1") = 1
'Grabamos el fichero
ThisWorkbook.Save
Else
If Range("B1") < maximo_de_ordenadores Then
'Sumamos 1 al valor que haya
Range("B1") = Range("B1") + 1
'Grabamos el fichero
ThisWorkbook.Save
Else
'Cerramos el libro, porque habrá
'llegado al máximo permitido

ThisWorkbook.Close
End If
End If
'Volvemos a mostrar los mensajes de aviso
Application.DisplayAlerts = True
'Ocultamos la Hoja3 al máximo
Hoja3.Visible = xlSheetVeryHidden
'Seleccionamos la Hoja1
Hoja1.Select
'Mostramos el procedimiento
Application.ScreenUpdating = True
End Sub

Os dejo el fichero para que os lo descarguéis con todo el código fuente de este ejemplo, y donde hay dos macros más, uno para ocultar la Hoja3, y otro para mostrarla (esto es para hacernos más fáciles las cosas, y saber todo lo que hace el macro, pues al estar la Hoja3 oculta no veremos nada de lo que sucede). Desde aquí podéis descargar el fichero de excel, con todo el código que os presento en este artículo,

Si queréis comprobar que realmente solo se puede trabajar con esta aplicación en 5 ordenadores diferentes, tan solo debéis de cambiar el número de serie del disco duro que se habrá grabado en la Hoja3 (podéis poner un código inventado). Cambiad el número que aparece en la celda B2, ponded un 5, y grabad el fichero. Cuando abráis el fichero nuevamente se os cerrará de forma automática, y os impedirá trabajar con él.



40 comentarios:

hl dijo...

su planteamiento me ha parecido excelente.Pero tuve un inconveniente al aplicarlo en uno de mis trabajos. Cada vez que abro el libro excell se registra en la hoja3 la serie del disco sin importar que se trata del mismo número puesto que estoy trabajando con un solo disco. Esto hace que a la sexta vez que abro el Libro, este se bloquea y no tengo opcion de volverlo a abrir.
Sería genial si esto puede solucionarse

Javier Marco dijo...

Pues eso no debería ocurrirte, por un simple hecho. La primera vez que abres el fichero desde un PC nuevo, se registra el número de serie del disco duro. La segunda vez que lo abres en ese mismo PC, lee si existe un número de serie del disco ya registrado anteriormente (de la 1ª vez que se abrió el fichero), y si está grabado en la hoja3, lo compara con el número de serie del disco duro del PC. Si ambos son iguales, no pasa nada, pues no se registra nada nuevo (en tu caso sí, por algún motivo que desconozco, ...probablemente tenga que ver con tu disco duro).

Yo lo he probado en el PC de casa y en el del trabajo, y me funciona perfectamente, pues puedo trabajar con el fichero infinitas veces.

Te invito a que pruebes el funcionamiento del fichero en otro PC distinto, porque creo que el problema podría estar en tu disco duro, aunque es muy raro.

Un saludo.

Anónimo dijo...

el programa sólo funciona en la medida que este bajo, el nivel de seguridad.

R.B.D.

Javier Marco dijo...

Te comento lo mismo que en tu otro comentario: Sí, claro, pero se supone que vas a distribuir un fichero con macros, que va a ser útil a la gente, y que te ha llevado un tiempo desarrollar. Se supone que si el usuario no permite la ejecución de macros, tampoco le va a servir de nada el fichero.

Un saludo, y gracias por tu comentario.

Anónimo dijo...

DISCULPA LA PREGUNTA SOY NUEVO EN ESTO PERO QUISIERA SABER COMO HAGO PARA QUE SOLO SE PUEDA UTILISAR UN SOLO Pc

Javier Marco dijo...

Pues simplemente cambia esta línea del código:

maximo_de_ordenadores = 5

Por esta otra:

maximo_de_ordenadores = 1

Si no sabes como hacer macros, en ese enlace también se explica.

Un saludo.

question dijo...

Pregunta: He notado que si a una USB se le formatea, cambia el numero de serie... pasa lo mismo con los discos duros?

Javier Marco dijo...

Pues hasta donde yo se, el nº de serie es siempre el mismo, para cualquier dispositivo, y no cambia con los formateos.

Anónimo dijo...

HOLA ya probre el macro y funciono en otros equipos pero tengo un problema en win vistar con office 2007 no se activo dejo abrir el archivo que hago

Javier Marco dijo...

Pues no tengo Office 2007, así que no puedo ayudarte. Mira a ver si te marca algún error, y en tal caso habría que cambiar esas líneas de código que no le gusten a Win Vista y Office 2007. pero ya te digo que yo no tengo instalada esa versión, así que poco te puedo ayudar.

Un saludo.

Anónimo dijo...

JAVIER TE AGRADESCO TU COLABORACION DEVERD MUCHAS GRACIAS.

Javier Marco dijo...

Muchas gracias por tu comentario.

Anónimo dijo...

me parece excelente. un muy buen aporte. hace tiempo trabajo con macros y necesitaba proteger mi trabajo. muy agradecido y sobro todo, gracias por no proteger el tuyo, sino seguiriamos siendo plageados. Un abrazo grande. Temuco - Chile

Javier Marco dijo...

Muchas gracias por tu comentario. Todo lo que encontraréis aquí, es de libre distribución, y está sin proteger :-)

edison dijo...

javier que pena molestarte con un problema diferente,mi nombre es edison alvarez antes te escrito como anonimo. pero tengo un problema resulta que tengo un userfrom 3 textbox dos donde ingreso numeros y donde muestro el resultado de una division. funciona pero al insertar me da un error "error 6 desbordamiento depuro y me muestra en amarillo TextBox3 = Round(Val(TextBox1) / Val(TextBox2), 0)
si me puedes colaborar con algo te lo agradesco. chao

Jorge dijo...

Hola pero a mi no me resulta nada. corro la macro y no hace nada, no me muestra el numero de serie del disco duro

Jorge dijo...

Hola pero a mi no me resulta nada. corro la macro y no hace nada, no me muestra el numero de serie del disco duro

perdon pero en el comentario anterior no seleccione dar seguimiento

Lucía dijo...

Excelente!

Voy a ver si lo puedo adaptar para una macro de Word.

Al menos los números de series los lee.

:)

Lucía

Lucía dijo...

Porqué el número de serie que me devuelve esta macro no coincide con el número de serie que logro con un DIR?

Son distintos formatos?

Javier Marco dijo...

Creo que el número de serie que obtienes con el comando DIR, es un número "lógico" y no "físico", y lo asigna el propio sistema operativo. Hasta donde yo sé, ese número que te devuelve el comando DIR, es modificable (puedes cambiarlo por ejemplo con un ejecutable llamado HardDiskSerialNumberChanger, ...googleando lo encontrarás), mientras que el otro no, pues se trata del nº de serie físico (cada disco tiene el suyo, y es unívoco).

Lucía dijo...

Excelente, gracias!

Estoy tratando de desarrollar una macro de Word para que al ejecutarse me devuelva el número de serie del disco, la ruta donde se guardan las plantillas normales y también la versión de Word actual.

Con esos datos pretendo luego personalizar una macro para que solo funcione en esa computadora.

O sea mi idea es primero mandar a mis clientes la macro 1 para que mis clientes copiando y pegando (o tal vez lo haga con la misma macro) me envíen a mi correo el número de serie de su disco, donde se guardan las plantillas y la versión de Word.

Con esos datos creo una macro personalizada que solo funcione en ese disco duro y la incorporo a un archivo RAR que se autoinstale en la carpeta donde está la normal.dot.

Pienso que al hacer eso lograría "instalar" a distancia una macro personalizada y protegida.

Qué te parece?

Anónimo dijo...

hasta donde entendí esta macro impide que el mismo archivo se ejecute en más de 5 pc's pero nada impide que dupliques el archivo excel infinitas veces para que cada uno pueda trabajar en 5 pc's.

Asi que si tienes 25 ordenadores con duplicar el archivo original 5 veces tendriamos licencias de sobra. jejeje

el blog muy bueno para los que nos iniciamos sin muchos conocimientos en excel.

Un saludo.

Javier Marco dijo...

Solo una mente muy retorcida haría una copia de un fichero excel, previniendo que no se pueda ejecutar más de X veces :-)

Evidentemente esta es una medida para ponerle las cosas más difíciles al usuario, porque como bien sabes, no hay ningún software que sea inviolable, y hasta con el programa más complejo y caro del mercado, hay gente que te lo revienta en un plis plas.

Anónimo dijo...

Javier, saludos
tu pagina esta excelente, tu utilizas mucho esta instruccion: 'Ocultamos el procedimiento
Application.ScreenUpdating = False ¿cual es su principal funcion?, pues segun creía yo que el procedimiento de una macro no se ve mientras se ejecuta, ¿o se refiere a otra cosa?
yo no lo utilizo, ¿me estaré perdiendo de algo?, soy programador novato.

Javier Marco dijo...

Pues sirve pare evitar los pantallazos mientras se ejecuta un macro, o lo que es lo mismo, el refresco de pantalla :-)

Webmaster dijo...

No me lee el número de serie del disco duro. ¿Será porque uso windows vista?

Anónimo dijo...

Hola Javier

Excelente tu Blog, me ha ayudado bastante.
pero, disculpame mucho la pregunta que te voy a hacer, pero es que necesito la respuesta, la he buscado en todo internet y no la encuentro.

Yo tengo un blog de impuestos y he estado buscando la manera de tener todos mis articulos publicados asi como tu los tienes, que no se escondan, porque en el apartado de archivos si se esconden. ¿me puedes decir como le hiciste?

de antemano muchas gracias.

disculpa.

Javier Marco dijo...

Pues lamentablemente yo tampoco he conseguido ningún script que te ponga eso de forma automática en blogger, porque esta plataforma es muy rígida para algunas cosas.

Lo que he hecho es simplemente añadir un gadget en html/javascript, y he ido introduciendo los enlaces de forma artesanal (a mano), a medida que he ido publicando los artículos.

Anónimo dijo...

Que buena idea, Javier.

lo voy a intentar hacer asi.

te agradezco mucho que hayas contestado esta pregunta, sobre todo porque no tiene nada que ver con los excelentes articulos de excel que publicas.

mil gracias y dios te bendiga.

bye

Sandra dijo...

Hola:

He estado mirando tu página y realmente tiene cosas muy útiles para aplicar tanto personal como laboralmente.

Pero no he conseguido encontrar algo que me pueda ayudar en una fórmula que necesito para realizar unos informes en el trabajo, he probado varias formulas y no ha habaido problema, ¿me podrías ayudar?

El informe consiste es saber si una serie de envíos se han realizado correctamente en el horario que le hemos solicitado a la compañía de transporte.
El horario suele ser entre dos horas (por ejemplo: desde las 10:00h a las 12:00h) y el cliente me da una hora exacta de entrega (por ejemplo: a las 10:30h), por lo que necesito una formula que me diga que esta entrega se ha realizado en el horario correcto o en su defecto, si la entrega del pedido se hubiera realizado a las 12:15h por ejemplo, que me diga que la entrega ha sido incorrecta.

Si me pudierais ayudar me hariais un gran favor.

Muchas gracias.

Sandra

Javier Marco dijo...

Imagina que tienes en A1 la hora de inicio de la entrega, en B1 la hora final, y en C1 la hora en la que realmente se ha efectuado la entrega. Escribe esto en D1:

=SI(Y(C1>=A1;C1<=B1);"En horario";"Fuera de horario")

Si tienes una tabla larga, con horarios de entrega, tampoco hace falta que copies y pegues la hora inicial (10:00) y la hora final (12:00). Las puedes dejar fijas arriba, como en esta imagen que te incluyo en el enlace (fíjate en la fórmula que aparece arriba, en la barra de fórmulas de esa imagen):

http://img245.imageshack.us/img245/4955/pantallazosy.png

a dijo...

Hola Javier, me podés enviar un correo electrónico a la casilla: flack.06@hotmail.com explicándome con ejemplos claros como hacer ésto. Intenté hacerlo y no lo puedo lograr.
pd: quiero que el archivo excel se abra solamente si coincide el código con el de la pc. Desde ya, muchas gracias.

Julio Aguilar dijo...

Hola Javier te felicito esta macro me ha servido de mucho esta buenísima, la pobre en dos maquinas distintas y me funciono pero solo tengo una duda, limite el acceso a a una maquina y cuando intente abrirla en la segundo se bloqueo, he intente abrirla desde la memoria e igual se desabilito, Perfecto, pero cuando le cambie a 2 maquinas me funciono en las dos maquinas y después abri el fichero desde la memoria y también se habilito, y yo esperara que no se habilitara ya que se había habilitado anteriormente en las 2 pc eso es normal siempre se habilitara en la memoria o usb en varias maquinas aunque ya se aya usado 2 veces anteriores en 2 pc? gracias

Javier Marco dijo...

La cuestión es que si te bajas un fichero de internet con macros, tu aplicación Excel la bloqueará por defecto, para que no se ejecuten las macros, porque podrían contener código malicioso (obviamente en mis fichero no, jejeje).

Por eso, Excel te bloquea las macros, y no te permite ejecutarlas, a no ser que expresamente autorices la ejecución de las macros. Si en algún PC no te ha funcionado, y posteriormente sí te ha funcionado (da igual que lo ejecutes desde una llave USB, desde un disco externo, desde el propio disco duro, etc), es porque tú le has dicho que habilite las macros.

En principio Excel bloquea todas las macros que no hayas creado tú, por temas de seguridad. Si habilitas las macros, podrás ejecutarlas en cualquier pc, y cargando el macro desde cualquier sitio (USB, disco externo, etc.).

Saludos.

Fernando dijo...

Ante todo muchas gracias por tantas herramientas útiles.
Te comento una dificultad que tuve, la macro en la primer compu que la probe anduvo sin problemas y tomo el numero de serie pero para probar la limitacion la abri en otra, pero me dio error la macro diciendo "Compile error" "Cant find project o library" y me marca la parte que dice "maximo de ordenadores = 5"
Porque será?

Javier Marco dijo...

No debe haber espacios entre "maximo de ordenadores", de ahí que usemos un guión bajo. Es decir, la variable se tiene que llamar: "maximo_de_ordenadores".

Si aún así no te funciona, sustituye esa línea por estas dos:

Dim maximo_de_ordenadores As Byte
maximo_de_ordenadores = 5

Saludos.

Fernando dijo...

Muchas gracias! funcionó ese pedazo pero luego se volvió a frenar por razones similares, la macro me quedó en ese pedazo así:

Dim maximo_de_ordenadores As Byte
maximo_de_ordenadores = 2
'Empezamos...
Set oWMI = GetObject("WINMGMTS:")

Pero cuando llega a esa última línea vuelve a poner "Can´t find project or library.

Para tratar de solucionarlo le agregué lo siguiente:

Dim oWMI As Object
Dim Disco As Object
Dim Discos As Object

Pero entonces se traba en la fila siguiente:

numero_de_serie = Trim(Disco.serialnumber)

y me marca la palabra Trim.

Realmente me intriga que funcione tan bien en una compu y en la otra de errores.

Te agradecería muchísimo ayudarme con mi acertijo, blogs como el tuyo animan a aventurarse en las macros.

Nuevamente gracias!!! y saludos!!!

Javier Marco dijo...

Paraces tener una versión algo rarita de Excel. Quizás deberías reinstalar Office en esa máquina, porque la función TRIM es básica en Visual Basic para Aplicaciones (VBA).

Jarod dijo...

Excelente aporte, quisiera agregar algo si me lo permites en lo que se refiere a la seguridad de macros:
1. Como ya alguien menciono tiempo atras, duplicar el fichero antes de abrirlo servira para que se use en tantas maquinas como se quiera, por ejemplo si el fichero se envia por correo electronico y este se reenvia varias veces todo el quie lo reciba podra replicarlo cuantas veces quiere con solo abrirlo desde el correo ya que este llega "limpio" de numeros de serie de discos duros... una solucion a este impase y dependiendo de la criticidad para proteger el fichero... seria determinar de antemano cuales serian los 5 discos duros en los que correria el fichero y asi dejarlos guardados en el programa... pero para ello habria que pedirle al destinatario que comunique antes de enviar el fichero los numeros de serie de los discos duros.
2. Donex es una plaicacion que convierte a codigo de maquina o mejor dicho convierte un fichero de excel a un ejecutable o .exe; aunque no se hasta que punto esto es inviolable (no lo he determinado aun) tengo entendido que seria la forma mas certera de evitar el plagio, obviamente combinandola con la medida anterior. Si estoy equivocado en algo hazmelo saber, para avanzar en conocimiento... saludos

Man in Black dijo...

Hola Javier Marco.
Te agradezco tu valiosa aportación. Aunque este comentario es muy tardío en este blog quiero compartir una idea para proteger nuestros trabajos en excel.
Obviamente queremos proteger un trabajo que funciona con Macros que es lo que le da valor agregado. Pero si alguien ha podido romper la primera barreraxde acceso para usarlo se puede incluir en las demás macros una verificación si se accedió al archivo mediante la macro de acceso (que registre Núm de disco por ejemplo registrado en una hoja oculta) u otra marca que dejé registrado la macro de acceso y si no pasa esa verificación que harían las demás macros de nuestro archivo entonces podría dentro de su mismos procesos detenerse o dejar de mostrar resultados en el funcionamiento esperado y con lo cual dejaría de tener nuestro archivo la funcionalidad esperada para ser usado. Con esto aun cuando se pueda acceder el pirata no obtendrá el botín deseado. Saludos desde México. Un admirador de tu trabajo soy Sebastián Pat