Desvelando el misterio de las capturas de pantalla automáticas en Windows 8/8.1

En cada nueva versión de Windows, se incorporan nuevas “mini características” o herramientas que por lo general, son para mejorar diferentes tareas básicas pero necesarias cuando se está trabajando con el sistema operativo.

Normalmente no hay tanto para cubrir en este tipo de cosas como para escribir un artículo, sin embargo, hace un tiempo alguien planteó una duda muy interesante con respecto a una funcionalidad en Windows 8/8.1 que permite crear capturas de pantalla automáticas y almacenarlas en una carpeta dentro de Imágenes con tan solo presionar las teclas de Windows + ImprPantPetSis.

Dentro de la carpeta, se van creando las imágenes con su respectivo índice que inicia en uno (1):

image

Los dos aspectos más interesantes, son el hecho de no tener que guardar y nombrar la captura de pantalla manualmente después de presionar ImprPantPetSis como hasta Windows 7 se debía hacer, así que es muy fácil y rápido, perfecto para escenarios donde necesitemos documentar varias pantallas y no haya el tiempo de detallarlas mucho usando la herramienta de Recortes, por ejemplo. El índice irá aumentando de a uno en uno, así que no hay problemas por colisión de nombres o ausencia de capturas, ya que todo lo hará Windows de una forma efectiva.

Ahora, lo interesante de la pregunta en el Foro de Windows en Microsoft Community, era que si uno elimina alguna, o todas las capturas de pantalla que se generan y se vuelve a presionar las teclas Windows + ImprPantPetSis con el objetivo de generar una nueva, el índice no será nuevamente uno (1) (Si es que se borraron todas), pues en vez de eso, el índice continuará donde se dejó en la última captura. Por ejemplo, si se crearon 10 capturas, se borran y se vuelve a crear una, no se llamará Screenshot(1), sino que tendrá como identificador numérico el que seguía en el orden lógico, es decir: Screenshot(11). 

¿Por qué sucede esto? ¿Cómo administra Windows los índices internamente? ¿Se puede volver a inicializar desde el uno? Todas estas preguntas las respondió de una forma precisa Ramón Sola en el hilo del foro, así que este artículo no es más que una ampliación un poco más detallada del comportamiento con dos objetivos: 1) Solucionar las inquietudes a quienes se hagan la misma pregunta, 2) Explorar un poco sobre lo complejo e inteligente que puede llegar a ser Windows.

La herramienta que utilizaré para entender esto será por supuesto Process Monitor.

La primera captura

Con la primera captura de pantalla que se tome puede ser suficiente para entender cómo funciona, aunque es más interesante ver paso a paso cómo es que responde Windows a los diferentes escenarios.

Cuando se presiona la combinación de teclas Windows + ImprPantPetSis, veremos que la pantalla se vuelve un poco oscura por no más de uno o dos segundos y en el directorio de Imágenes –como lo expliqué al principio- se generará una carpeta llamada Screenshots; dentro de esta, una primera captura con el nombre de Screenshot (1). ¿Qué hizo Windows en este tramo de tiempo? Pues bien, esto es lo que nos muestra Process Monitor:

image

Recordemos que los resultados de Process Monitor se leen de forma descendiente, así que teniendo esto en cuenta, Windows de forma inteligente intenta crear toda la estructura de carpetas hasta llegar a la última que en últimas es la necesaria para la operación y en este caso sería Screenshots.

*Nota: Hay que aclarar que si estuviéramos programando con la API de Windows, utilizar la función de CreateDirectory no genera toda la estructura de carpetas como sí lo hace la de RegCreateKeyEx en el Registro, por ejemplo así que tendríamos que automatizarlo nosotros mismos.

Enfocándonos un poco más en las 6 operaciones que muestra la captura de la traza, Windows utiliza CreateFile para intentar crear el directorio Pictures (Imágenes), pero obtiene como resultado NAME COLLISION devuelto por el Manejador de Errores de Windows, que en contexto de programación tendría el identificador ERROR_ALREADY_EXITS y más específico, el código de error 183. 

Ahora, la razón por la que en dos veces en principio se muestra la operación de CreateFile, es porque Process Monitor la utiliza para referenciar diferentes funciones asociadas, que en este caso se referirían a intentar crear, y si ya existe, simplemente abrir el directorio y posteriormente consultar la información con QueryBasicInformationFile. En otras palabras, hasta la cuarta operación, Windows verifica que se cree o abra la carpeta Pictures, para luego volver a llamar a la operación CreateFile, que internamente está es utilizando CreateDirectory y así escribir la carpeta de Screenshots. Lo último que hace es cerrar con CloseFile. Cabe destacar que cuando crea el directorio, obtiene resultado de SUCCESS, porque al ser primera vez, no existe de forma predeterminada.

Después de esto, y luego de realizar muchas otras tareas, entre las que se incluye crear y trabajar con un archivo desktop.ini ubicado en la misma carpeta, viene lo realmente interesante mientras se copia la captura de pantalla en Screenshots:

S1

*Nota: Pueden hacer clic en la imagen para verla de tamaño completo.

Las cuatro operaciones encerradas con rojo permiten que Windows nos despeje gran cantidad de las dudas con respecto a la característica:

La primera operación, que Process Monitor reporta como RegQueryValue, utiliza la función (Entre otras) de NtQueryValueKey en modo Kernel, y que en modo usuario sería RegQueryValueEx para leer el contenido de un Valor de Registro, en este caso, el de ScreenshotIndex, pero en principio, el resultado es NAME NOT FOUND indicando que el Valor de registro ni siquiera se encuentra creado. Windows pasa entonces a abrir el archivo Screenshot (1).png pero también recibe NAME NOT FOUND así que el archivo no existe.

Para entender un poco mejor, veamos lo que ocurre en las otras dos operaciones resaltadas: Antes de la operación en rojo, hay una operación de RegCreateKey, que en este contexto es abrir la clave para escribir un valor, luego procede y finalmente reporta operación de RegSetValue –internamente utilizando RegSetValueEx- para crear un valor muy interesante llamado ScreenshotIndex, y si entramos en las propiedades, podremos ver que es de tipo DWORD y almacena el contenido de dos (2). Así quedaría en el Registro:

image

Después de esto, se cierra la operación sobre la sub-clave y se procede a crear el archivo llamado Screenshot (1).png, que previamente se había buscado para saber si existía o no. ¡Ahí tenemos nuestra primera captura!

Como siempre, los valores de registro suelen decir un poco su objetivo en el nombre, y este básicamente nos da a entender que gestionará los índices que aparecen después del nombre Screenshot entre paréntesis. ¿Pero por qué tiene el 2 y no el 1, creado en primera instancia? Para responder eso, hay que probar un poco más la característica:

Segunda captura

Si presionamos Windows + ImprPantPetSis por segunda vez, mientras monitoreamos con la ayuda de Process Monitor el comportamiento de Windows, podremos ver que primero se creará una segunda captura con el nombre Screenshot (2).png en el directorio Screenshots:

image

En las operaciones a nivel de archivos y registros hay un pequeño cambio interesante:

image

Las operaciones son exactamente las mismas que para la primera captura, pero aquí debemos notar que el primer RegQueryValue que se hace sobre ScreenshotIndex ya no es NAME NOT FOUND (Porque no existía), sino que ahora es SUCCESS, y por ende, ahora Windows tiene el contenido exacto del valor, es decir, el número dos (2) que estableció desde la primera captura.

A continuación se verifica que exista o no (CreateFile) el archivo Screenshot (2).png; como recibe una respuesta de NAME NOT FOUND (No se encuentra), procede a escribir en el valor de registro ScreenshotIndex nuevamente con la operación RegSetValue pero esta vez con un contenido de tres (3):

image

Después de esto cierra (otra vez) y finalmente crea el archivo Screenshot (2).png.

¿Excelente, no creen? En términos más sencillos, y para resumir un poco todo hasta aquí, Windows 8/8.1 tiene un nombre predeterminado de Screenshot para cada captura de pantalla generado a partir de la combinación de teclas Windows + ImprPantPetSis; para evitar colisión y pérdida de capturas, tiene un valor de registro llamado ScreenshotIndex que mantiene el índice que sigue a continuación, y para evitar que ya esté, siempre valida el nombre que va a utilizar antes de modificar el índice en el valor.

Así las cosas, si creáramos una tercera captura de pantalla automática, se llamaría Screenshot (3).png, pero el valor de ScreenshotIndex tendría contenido de cuatro (4), referenciando su próximo índice.

Tratando de engañar a Windows

Aquí es donde finalmente veremos qué tan inteligente puede llegar a ser Windows sobre diferentes escenarios, y empezando por el más básico, supongamos que tenemos tres capturas creadas, es decir, Screenshot (1), Screenshot (2) y Screenshot (3); quiere decir, que el valor ScreenshotIndex tiene el contenido de cuatro (4) para el próximo índice –Tal cual lo expliqué en el párrafo anterior-.

¿Qué sucede si cambiamos el contenido de ScreenshotIndex a tres (3), para que la próxima captura se tenga que llamar Screenshot (3) y colisione contra la que ya está creada? Process Monitor nos responde:

S2

Como en las anteriores veces, primero se abre la sub-clave de Explorer, se procede a consultar el valor de ScreenshotIndex (con un contenido de 3), cierra la operación y luego como en las otras veces intenta abrir el Screenshot (3).png para ver si existe y como en este caso recibe SUCCESS (El archivo ya está creado), de forma muy inteligente procede a cerrarlo y verificar el siguiente en su orden lógico, es decir, Screenshot (4).png y al no encontrarlo (NAME NOT FOUND), procede con su comportamiento normal y actualiza el índice, pero no al 4 (Teniendo en cuenta que habíamos puesto 3), sino al 5, porque da por hecho de que escribirá el archivo con índice 4, y de hecho lo hace en las próximas operaciones.

image

*Nota: Aunque traté de verlo desde Process Monitor, ignoro cómo maneja los índices cuando no puede depender del valor de registro completamente.

Segundo intento

Vamos a suponer ahora, partiendo de donde quedó el ejercicio anterior, que contenido de ScreenshotIndex no será el que sigue, es decir, cinco (5), sino dos más adelante, o sea: 6. ¿Qué sucede al crear la captura? Process Monitor responde:

image

En este caso, Windows lee el índice (6), intenta abrir el archivo con ese nombre y al ver que no existe, pasa como en su procedimiento normal, a establecer el contenido de ScreenshotIndex al siguiente, es decir: 7. Como no hay problemas con eso, termina creando la captura de pantalla con ese índice. Las capturas habrán pasado entonces de 4 a 6:

image

Sobre esto podemos concluir que no valida el inmediatamente anterior, solo el siguiente, así que aunque es inteligente, no le interesa en este caso qué hay atrás. No fue lo suficientemente audaz en este caso.

Último intento

Para terminar, y sobre la base anterior, es decir, capturas creadas del 1 al 6, sin incluir el 5 porque no existe, ¿Qué pasa si cambio el contenido de ScreenshotIndex a cero (0)? Pues bien, Process Monitor responde:

image

Windows consulta el contenido de ScreenshotIndex (Que tiene cero (0)), pero como ese no lo utiliza para poner índice, procede a iniciar desde el número uno (1); como encuentra que ya existe, pasa inmediatamente a verificar si el siguiente en orden existe pero como también recibe SUCCESS (Existe), sigue de a uno en uno hasta encontrar un hueco, es decir, hasta que el resultado sea NAME NOT FOUND (No existe) y en este caso, sería precísamente en la captura con índice cinco (5). 
Por último, establece el contenido de ScreenshotIndex al siguiente, es decir, 6 que incluso ya está creado, pero nos damos cuenta que Windows no hace ninguna comparación contra el nombre del archivo para ver si el índice está referenciado o no, y de igual forma, así tenga uno repetido (Como vimos en el primer ejercicio), procederá luego es a crear el siguiente, es decir: Screenshot (7).png. 

Hay más escenarios, como intentar escarlarlos en diferente orden, pero Windows sólo escribirá donde encuentre un espacio, sea al principio, en la mitad o en la final, así que no es necesario documentar más.

Restablecer el índice al valor inicial

Como punto final, ¿Cómo podemos hacer que todo inicie nuevamente? Muy sencillo, debemos borrar todas las capturas de pantalla (el directorio no es necesario, pero también se puede hacer), y después eliminar el valor ScreenshotIndex ubicado en:

HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersionExplorer

image

De esta forma, o eliminando los archivos y poniendo el índice en uno (1), todo empezará nuevamente:

image

Eso es todo, espero les pueda ser de utilidad.

¡Comentarios y correcciones bienvenidas!

PD. No olviden seguirme en Twitter: http://www.twitter.com/secalderonr

Saludos,

Checho

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *