Cómo funciona la compatibilidad de aplicaciones en Windows ── el modo de compatibilidad, los shims y Compatibility Administrator para prolongar la vida de aplicaciones antiguas
· Actualizado el: · Go Komura · Windows, Modo de compatibilidad, Shims, Compatibilidad de aplicaciones, Compatibility Administrator, Activos heredados, Desarrollo en Windows, Sistemas existentes
«Una aplicación de negocio de hace diez años, de la que ya no queda el código fuente, no arranca en un PC nuevo con Windows 11. Al marcar “Windows XP” en la pestaña de compatibilidad de las propiedades, empezó a funcionar sin más. ── ¿Qué es exactamente lo que está pasando ahí? ¿Está bien seguir dependiendo de esto?». Es una consulta que recibimos con frecuencia de nuestros clientes.
Cuando basta una sola casilla para que la aplicación funcione, la sensación de inquietud aumenta más que disminuye. La verdadera naturaleza del modo de compatibilidad, que parece magia, es el shim, un conjunto de pequeños fragmentos de código que se interponen entre la aplicación y la API de Windows y devuelven una “mentira”. Para seguir haciendo funcionar aplicaciones de generaciones muy anteriores, el propio Windows utiliza este mecanismo de remedio provisional a gran escala, y una parte de él está también abierta a usuarios y administradores.
Usarlo sin conocer el mecanismo produce una prolongación inestable, del tipo “no se puede tocar porque no se sabe por qué funciona”. Por el contrario, entender el mecanismo permite decidir con fundamento hasta dónde se puede confiar con tranquilidad, qué lo rompería y cuándo conviene rehacer la aplicación.
flowchart TB
accTitle: Entender el mecanismo cambia la calidad de la prolongación de vida útil
accDescr: Usar el modo de compatibilidad sin entender el mecanismo produce una prolongación inestable que da miedo tocar, pero entenderlo permite decidir con fundamento hasta dónde se puede confiar, qué lo rompería y cuándo rehacer la aplicación
unknown["Usarlo sin entender el mecanismo"] --> fear["Prolongación inestable, sin tocar"]
known["Usarlo entendiendo el mecanismo"] --> judge["Decisión con fundamento"]
judge -.-> j1["Hasta dónde se puede confiar"]
judge -.-> j2["Qué lo rompería"]
judge -.-> j3["Cuándo rehacerla"]
Figura 1: En una misma prolongación de vida, la calidad cambia entre la inquietud de no entender el mecanismo y una decisión basada en comprenderlo.
Este artículo está dirigido a los responsables de sistemas de pequeñas y medianas empresas y a los desarrolladores de aplicaciones Windows que tienen a su cargo aplicaciones de negocio antiguas. A partir de fuentes primarias de Microsoft Learn, organiza el mecanismo del shim que hay detrás del modo de compatibilidad, lo que pueden hacer los shims más representativos, la aplicación organizada mediante Compatibility Administrator, y los límites que el shim no puede salvar, hasta llegar a la decisión entre “prolongar la vida útil o migrar”.
1. En resumen
- La verdadera naturaleza del modo de compatibilidad es el shim (capa de compatibilidad). La configuración de la pestaña de compatibilidad se escribe en
HKCU\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers, y al iniciar el proceso se le aplica el conjunto de shims correspondiente.12 - El shim es un hook de API en modo usuario mediante la sustitución de la tabla de importación (IAT). Se interpone en la ruta por la que la aplicación llama a la API de Windows y devuelve la misma respuesta que una versión antigua de Windows. No modifica el propio sistema operativo.3
- Lo que un shim puede hacer está dentro del mismo alcance que lo que se podría lograr corrigiendo el código de la aplicación. No puede eludir mecanismos de seguridad ni corregir problemas en modo kernel (controladores de dispositivo).3
- Microsoft proporciona de fábrica numerosos shims listos para usar, como la falsificación de versión, la redirección de rutas de archivo, la falsificación del registro o la falsificación de la comprobación de administrador. Se pueden aplicar a un EXE concreto desde Compatibility Administrator.4
- El propio Windows usa shims de forma predeterminada. En cada inicio se compara con la base de datos de compatibilidad estándar del SO (.sdb), y además el PCA (Program Compatibility Assistant) puede detectar problemas y aplicar automáticamente la configuración de compatibilidad.15
- “Responder que se trata de una versión antigua de Windows” es hoy el comportamiento predeterminado. Desde Windows 8.1,
GetVersionExno devuelve una versión de SO que no esté declarada en el manifiesto. El modo de compatibilidad es una extensión de este mecanismo.67 - El shim no funciona con aplicaciones de 16 bits, dependencias de controladores de kernel ni acceso directo al hardware. En particular, en Windows de 64 bits las aplicaciones de 16 bits directamente no se pueden ejecutar.8
- Para las aplicaciones que “solicitan permisos de administrador sin necesitarlos realmente”, RunAsInvoker es la solución clásica. Con
__COMPAT_LAYER=RunAsInvokerse suprime la solicitud de elevación y la aplicación se ejecuta con permisos estándar.9 - Que funcione con un shim significa que se puede prolongar su vida por el momento, pero lo esencial sigue siendo “corregirla para que funcione sin shim”. Si se decide prolongarla, hay que registrar con qué shim funciona y gestionarlo como criterio para decidir cuándo rehacerla.
2. Panorama general de la compatibilidad de aplicaciones ── las capas de retrocompatibilidad de Windows
Antes de entrar en el tema del shim, conviene hacer un repaso de los mecanismos que Windows tiene para las aplicaciones antiguas. Aunque se diga sin más “funcionó con el modo de compatibilidad”, en realidad lo que salva a la aplicación es uno de estos mecanismos, o una combinación de varios.
| Capa | Qué hace | Objetivo principal |
|---|---|---|
| Shim (modo de compatibilidad) | Intercepta las llamadas a la API y simula la misma respuesta que una versión antigua de Windows | Aplicaciones en general escritas para un SO antiguo |
| Virtualización de UAC (archivos/registro) | Redirige al VirtualStore de cada usuario las escrituras sin permisos en HKLM\Software o Program Files |
Aplicaciones de 32 bits escritas asumiendo permisos de administrador |
| WOW64 | Ejecuta aplicaciones de 32 bits tal cual en Windows de 64 bits (ofrece vistas de 32 bits del registro y los archivos) | Aplicaciones de 32 bits en general |
| Virtualización de DPI | Hace que las aplicaciones sin compatibilidad DPI se dibujen como si fueran de 96 DPI, ampliando el mapa de bits | Aplicaciones antiguas en pantallas de alto DPI |
La virtualización de UAC es una medida transitoria que actúa sobre los procesos interactivos de 32 bits sin manifiesto, y la propia Microsoft declara explícitamente que es “una tecnología provisional que planea eliminar en futuras versiones de Windows”.10 Los efectos prácticos y el tratamiento de la redirección a Wow6432Node y del VirtualStore se abordan en detalle en «Redirección y virtualización de 32/64 bits en el registro de Windows — Wow6432Node y el problema del “valor que debería estar y no está”», así que este artículo se centra en el shim y toca las demás capas solo en la medida necesaria.
flowchart TB
accTitle: El papel de la virtualización de UAC
accDescr: La virtualización de UAC es una medida transitoria que actúa sobre procesos interactivos de 32 bits sin manifiesto, redirigiendo la escritura al VirtualStore de cada usuario, pero Microsoft declara explícitamente que es una tecnología provisional que planea eliminar en futuras versiones de Windows
proc["Proceso interactivo de 32 bits sin manifiesto"] --> uacv["Actúa la virtualización de UAC"]
uacv --> vs["Redirige al VirtualStore del usuario"]
uacv -.-> tmp["Tecnología provisional a eliminar"]
Figura 2: La virtualización de UAC es una medida transitoria para procesos de 32 bits sin manifiesto, en la que no se puede confiar de forma permanente.
A modo de aclaración, la virtualización de DPI también funciona así: una aplicación que no declara compatibilidad con DPI se trata como si dibujara a 96 DPI (100 %), y Windows amplía el mapa de bits para mostrarla. Por eso las aplicaciones antiguas se ven “borrosas” en monitores de alto DPI, y la opción “Anular el comportamiento de escalado de alto DPI” de la pestaña de compatibilidad es el interruptor que cambia este comportamiento de virtualización.11
flowchart TB
accTitle: El mecanismo de la virtualización de DPI
accDescr: Una aplicación que no declara compatibilidad con DPI se trata como si dibujara a 96 DPI y Windows estira el mapa de bits para mostrarla, por lo que se ve borrosa, y la opción de anular la configuración de alto DPI en la pestaña de compatibilidad cambia este comportamiento de virtualización
app["Aplicación sin compatibilidad DPI declarada"] --> treat["Se trata como dibujo a 96 DPI"]
treat --> stretch["Se estira el mapa de bits"]
stretch --> blur["Se ve borrosa en monitores de alto DPI"]
tab["Anular configuración de alto DPI"] -.->|Cambia el comportamiento de virtualización| treat
Figura 3: Una aplicación sin compatibilidad DPI se trata como si fuera de 96 DPI y se estira, y la opción de anulación de la pestaña de compatibilidad es el interruptor de esta virtualización.
3. La verdadera naturaleza del shim ── interceptar la API sustituyendo la IAT
3.1. El “intérprete” entre la aplicación y el sistema operativo
Los archivos ejecutables de Windows (formato PE) llaman a la API de las DLL externas a través de la tabla de direcciones de importación (IAT). Cuando una aplicación llama a GetVersionEx, en realidad solo salta a la dirección escrita en la IAT. El mecanismo del shim aprovecha exactamente ese punto: al cargar la aplicación, reescribe la entrada de la IAT de la API objetivo con la dirección del código del shim, interponiéndose entre la aplicación y Windows. Las API obtenidas dinámicamente con GetProcAddress también se cubren aplicando un hook al propio GetProcAddress.3
El shim que se interpone, por ejemplo, responde con un número de versión antiguo a la consulta “¿cuál es la versión del SO actual?”, o redirige a otra ubicación el acceso a un archivo en una ruta sin permiso de escritura, y luego, si hace falta, llama a la API real. Desde el punto de vista de la aplicación, parece que se está ejecutando en “una versión antigua de Windows”; desde el punto de vista del sistema operativo, parece que se está ejecutando “una aplicación bien portada”. El shim es el intérprete entre ambos.
flowchart TB
accTitle: La ruta por la que el shim intercepta las llamadas a la API
accDescr: Las llamadas a la API de la aplicación pasan por la IAT, y al cargar el proceso se reescribe la entrada de la IAT hacia el shim, que intercepta la llamada, simula la misma respuesta que una versión antigua de Windows y, si es necesario, invoca a la API real
app["Aplicación"] -->|Llamada a la API| iat["Entrada de la IAT"]
iat -->|Se reescribe hacia el shim al cargar| shim["Shim(intérprete)"]
shim -->|Si es necesario| api["API real de Windows"]
shim -.-> lie["Simula la misma respuesta que Windows antiguo"]
gpa["Llamada vía GetProcAddress"] -.->|Se cubre mediante hook| shim
Figura 4: El shim se interpone entre la aplicación y la API de Windows. Lo que se reescribe es la IAT del lado de la aplicación; el sistema operativo en sí no cambia.
De este diseño se derivan tres propiedades importantes.3
- El shim se ejecuta como código del lado de la aplicación. Al no ser parte del sistema operativo, está sujeto a las mismas restricciones de seguridad que la aplicación. No se puede usar un shim para eludir los mecanismos de seguridad del SO, ni hace falta relajar la configuración de seguridad para usar un shim.
- Lo que un shim puede corregir también se podría corregir modificando el código de la aplicación. El shim es un medio alternativo para cuando “no hay código fuente” o “no se puede corregir”, no es más potente que corregir el código.
- Limitado al modo usuario. Los problemas de compatibilidad de controladores de dispositivo que se ejecutan en modo kernel no se pueden corregir con un shim.
3.2. La base de datos de shims (.sdb) y la coincidencia de atributos
La tabla de correspondencias que indica “qué shim aplicar a qué EXE” es la base de datos de shims, un archivo binario con extensión .sdb. En la base de datos, el ejecutable de la aplicación objetivo se registra mediante atributos (atributos de coincidencia) como el nombre de archivo, el tamaño, la suma de comprobación o la versión, y se compara al iniciar el proceso. Entre las soluciones está Appfix (el shim), que inyecta un hook de API, y también Apphelp, que muestra el mensaje “Esta aplicación tiene un problema de compatibilidad”. El conjunto de varios shims y flags agrupados es la capa de compatibilidad (modo de compatibilidad).1
Es fácil pasarlo por alto, pero esta comparación se realiza en cada inicio de proceso, no solo en las aplicaciones a las que se les configuró el modo de compatibilidad. Windows incluye de serie una base de datos estándar del SO (que reside en %WINDIR%\AppPatch) con correcciones para miles de aplicaciones conocidas, y es muy probable que hoy mismo, en su propio PC, alguna aplicación antigua se esté iniciando con un shim aplicado sin que usted lo note. Las correcciones de compatibilidad que provee Microsoft se distribuyen como parte de Windows y se actualizan mediante Windows Update.3
flowchart TB
accTitle: La comprobación con la base de datos de shims al iniciar un proceso
accDescr: Cada inicio de proceso se compara con la base de datos de shims, y si hay un registro que coincide con los atributos de coincidencia se inyecta un shim mediante Appfix o se muestra un mensaje de Apphelp, y si no hay coincidencia el proceso arranca sin cambios
start["Inicio del proceso"] --> db["Comparación con la base de datos de shims(.sdb)"]
db -.-> attr["Coincidencia por nombre, tamaño, etc."]
db --> hit{"¿Hay un registro?"}
hit -->|Sí| appfix["Appfix(inyecta el shim)"]
hit -->|Sí| apphelp["Apphelp(muestra mensaje)"]
hit -->|No| plain["Arranca sin cambios"]
layer["Capa de compatibilidad(modo de compatibilidad)"] -.->|Conjunto de shims y flags| appfix
Figura 5: La comparación no se hace solo en las aplicaciones con modo de compatibilidad configurado, sino en cada inicio de proceso.
3.3. PCA ── el mecanismo que aplica shims automáticamente
Existe otra vía por la que se aplica un shim sin que el administrador lo pretenda: el PCA (Program Compatibility Assistant). El PCA supervisa la ejecución de las aplicaciones y, al detectar indicios de un problema de compatibilidad conocido, sugiere al usuario aplicar una corrección o, en algunos casos, aplica automáticamente la configuración de compatibilidad. Por ejemplo, a una aplicación que se bloquea por llamar a código dentro de una DLL ya liberada se le puede asignar el modo de compatibilidad PINDLL, y a una que falla al escribir en un archivo protegido de Windows, WRPMITIGATION.5
flowchart TB
accTitle: Cómo PCA aplica configuraciones de compatibilidad automáticamente
accDescr: PCA supervisa la ejecución de la aplicación y, al detectar indicios de un problema de compatibilidad conocido, sugiere al usuario aplicar una corrección o, en algunos casos, aplica la configuración de compatibilidad automáticamente
run["Ejecución de la aplicación"] --> pca["PCA supervisa"]
pca --> sign{"¿Indicios de un problema conocido?"}
sign -->|Sí| resp{"¿Qué caso es?"}
resp -->|Se sugiere| suggest["Sugiere aplicar la corrección"]
resp -->|Algunos casos| auto["Aplica la configuración automáticamente"]
sign -->|No| none["Se ejecuta sin cambios"]
auto -.-> ex["Ejemplo: PINDLL o WRPMITIGATION"]
Figura 6: El PCA supervisa la ejecución de la aplicación y, al detectar indicios de un problema conocido, sugiere o aplica automáticamente la corrección.
En muchos casos, esta es la explicación de “no configuré nada y, sin darme cuenta, la casilla del modo de compatibilidad ya estaba marcada”. No es una avería ni un error de operación, sino un comportamiento previsto por el propio diseño de Windows.
4. Qué pueden hacer los shims más representativos
De entre los shims listos para usar que publica Microsoft, se presenta una selección de los que se usan realmente con más frecuencia para prolongar la vida de aplicaciones de negocio.4
| Shim | Qué hace (resumen) |
|---|---|
| WinXPSP3VersionLie y otros de la familia VersionLie | Devuelve la versión antigua indicada a las consultas de versión del SO (falsificación de versión) |
| CorrectFilePaths | Redirige el acceso a rutas de archivo sin permiso de escritura o inexistentes hacia otra ubicación |
| VirtualRegistry | Redirige y falsifica la lectura/escritura del registro (incluye falsificación de versión y simulación de claves inexistentes) |
| ForceAdminAccess | Devuelve temporalmente True a la comprobación de “¿pertenece al grupo de administradores?” |
| RunAsAdmin / RunAsHighest / RunAsInvoker | Otorga desde fuera el nivel de ejecución equivalente a las declaraciones requireAdministrator / highestAvailable / asInvoker del manifiesto |
| WRPMitigation | Simula el éxito de escrituras en archivos o el registro protegidos del SO para que la aplicación siga adelante |
| EmulateGetDiskFreeSpace | Devuelve como máximo 2 GB de espacio libre en disco (contramedida para aplicaciones que desbordan con discos de gran capacidad) |
| GlobalMemoryStatusLie | Falsifica el valor reportado del estado de memoria (contramedida para aplicaciones que fallan en la comprobación de memoria al iniciar) |
| LoadLibraryRedirect | Hace que se cargue la DLL más reciente de Windows en lugar de la DLL del sistema antigua incluida con la aplicación |
Como se aprecia de un vistazo, la mayoría de los shims son “mentiras que devuelven la respuesta que la aplicación antigua espera”. El disco tiene como máximo 2 GB, el SO es XP, usted es administrador: se reproduce, solo dentro de ese proceso, la visión del mundo de la época en que nació la aplicación.
La falsificación de versión se convirtió en el “comportamiento oficial predeterminado”
La falsificación de versión no es un truco especial. Desde Windows 8.1, el valor que devuelve GetVersionEx depende del manifiesto de la aplicación. A una aplicación sin declaración <supportedOS> en la sección <compatibility> del manifiesto se le devuelve el equivalente a Windows 8 (6.2), sea cual sea el SO real. Si hay declaración, se devuelve el valor correspondiente al SO más alto declarado (por ejemplo, si se declara hasta el GUID de Windows 8.1, se devuelve 6.3 incluso en Windows 11).67
Es decir, “la versión de Windows que ve la aplicación” se determina en las siguientes etapas.
- Se devuelve el valor correspondiente al SO declarado en el manifiesto (6.2 si no hay declaración)
- Si se aplica el modo de compatibilidad (un shim de la familia VersionLie), se devuelve la versión del SO seleccionado6
flowchart TB
accTitle: Cómo se determina la versión de SO que ve la aplicación
accDescr: El valor que devuelve GetVersionEx depende de si el manifiesto declara supportedOS: sin declaración se devuelve el equivalente a Windows 8(6.2), con declaración se devuelve el valor del SO más alto declarado, y si se aplica un shim de la familia VersionLie el valor se sobrescribe con la versión del SO elegida
q["Consulta a GetVersionEx"] --> m{"¿Hay declaración supportedOS?"}
m -->|No| v62["Devuelve el equivalente a Windows 8(6.2)"]
m -->|Sí| decl["Valor del SO más alto declarado"]
v62 --> lie{"¿Se aplica un shim VersionLie?"}
decl --> lie
lie -->|Sí| fake["Valor del SO elegido en el modo de compatibilidad"]
lie -->|No| asis["Devuelve el valor tal cual"]
Figura 7: La versión de Windows que ve la aplicación se determina en varias etapas, combinando el manifiesto y el shim.
Si con una aplicación desarrollada internamente se produce la confusión de “el código bifurca según la versión del SO, pero en Windows 11 se detecta como 8”, sospeche primero de la declaración supportedOS del manifiesto. Dicho de otro modo, una aplicación antigua que rechaza arrancar por una comprobación de versión suele poder sortearse con una alta probabilidad usando el shim VersionLie, porque en muchos casos solo se está mirando el número de versión y el funcionamiento real no tiene problemas en el SO nuevo.
flowchart TB
accTitle: Dos síntomas causados por la versión y su tratamiento
accDescr: Si una aplicación propia se detecta como Windows 8 estando en Windows 11, hay que sospechar de la declaración supportedOS del manifiesto, y una aplicación antigua que rechaza arrancar por la comprobación de versión suele poder sortearse con el shim VersionLie
sym1["Se detecta como 8 estando en Windows 11"] --> fix1["Sospechar de la declaración supportedOS"]
sym2["Rechaza arrancar por comprobación de versión"] --> fix2["Probar a sortearlo con VersionLie"]
fix2 -.-> why["El funcionamiento en sí suele ser correcto en el SO nuevo"]
Figura 8: Un síntoma de detección de versión desactualizada apunta al manifiesto, y un rechazo de arranque apunta a VersionLie.
5. Qué hace la casilla del modo de compatibilidad
La configuración de Propiedades → pestaña Compatibilidad se guarda en la clave del registro AppCompatFlags\Layers. Es el lugar donde se especifica la capa de compatibilidad, y también lo usa, por ejemplo, la configuración de compatibilidad de aplicaciones de DXGI.2 Vamos a comprobarlo realmente.
reg query "HKCU\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers"
Para un EXE al que se le configuró en la pestaña de compatibilidad “Windows XP (Service Pack 3)”, “Ejecutar este programa como administrador” y “Anular el comportamiento de escalado de alto DPI”, se verían, por ejemplo, valores como estos.
HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers
C:\LegacyApp\Gyomu.exe REG_SZ ~ WINXPSP3 RUNASADMIN HIGHDPIAWARE
A continuación, ejemplos representativos de la correspondencia entre los elementos marcados y sus valores (comprobados en Windows 11; el nombre de los elementos y los valores pueden variar según la versión del SO).
| Elemento de la pestaña de compatibilidad | Valor escrito (ejemplo) | Qué es en realidad |
|---|---|---|
| Modo de compatibilidad: Windows XP (Service Pack 3) | WINXPSP3 | Capa de compatibilidad que agrupa la falsificación de versión y varios otros shims |
| Usar 256 colores (color de 8 bits) | 256COLOR | Relajación del modo de color antiguo |
| Ejecutar con una resolución de 640 × 480 | 640X480 | Ejecución a baja resolución |
| Deshabilitar las optimizaciones de pantalla completa | DISABLEDXMAXIMIZEDWINDOWEDMODE | Desactiva la optimización de dibujo en pantalla completa |
| Anular el comportamiento de escalado de alto DPI (aplicación) | HIGHDPIAWARE | Detiene la virtualización de DPI (el estiramiento del mapa de bits)11 |
| Ejecutar este programa como administrador | RUNASADMIN | Solicita elevación al iniciar |
Hay tres puntos que conviene tener presentes.
- “Ejecutar este programa como administrador” también se escribe en el mismo lugar. El modo de compatibilidad y la especificación de elevación conviven en la misma clave Layers, y de ahí surge la confusión de “al configurar el modo de compatibilidad, apareció (o desapareció) también la elevación”. Mirando el valor directamente se puede distinguir uno de otro.
- Lo que se escribe en HKCU es “la configuración de ese usuario”. Si se configura desde “Cambiar la configuración para todos los usuarios” en la pestaña, se escribe en la clave homónima del lado de HKLM y afecta a todos los usuarios. Al distribuirlo en el proceso de preparación de equipos (kitting), tenga presente en cuál de las dos se está escribiendo.
- La casilla es solo la puerta de entrada a las capas ya hechas. Desde la pestaña únicamente se pueden elegir las capas representativas; no se pueden seleccionar y combinar shims individuales. Eso es lo que permite hacer Compatibility Administrator, del siguiente capítulo.
flowchart TB
accTitle: Cómo llega a aplicarse la configuración de la pestaña de compatibilidad
accDescr: La configuración de la pestaña de compatibilidad se guarda en la clave Layers de AppCompatFlags como ruta del EXE y valor, y al iniciar de nuevo ese EXE el cargador lee el valor y aplica la capa de compatibilidad correspondiente al proceso
tab["Configurar en la pestaña de compatibilidad"] --> reg["Guardar ruta del EXE y valor en la clave Layers"]
reg --> boot["Siguiente inicio del EXE"]
boot --> loader["El cargador lee el valor"]
loader --> apply["Aplica la capa de compatibilidad al proceso"]
reg -.-> hkcu["HKCU solo afecta a ese usuario"]
reg -.-> hklm["HKLM afecta a todos los usuarios"]
Figura 9: La casilla en realidad escribe en la clave Layers, y la aplicación ocurre en el siguiente inicio.
6. La práctica de Compatibility Administrator ── crear y distribuir un .sdb personalizado
6.1. Obtención y precauciones
Compatibility Administrator es una herramienta incluida en el Windows ADK (Windows Assessment and Deployment Kit).12 Al instalarlo se incluyen tanto la versión de 32 bits como la de 64 bits, y para corregir aplicaciones de 32 bits hay que usar la versión de 32 bits, y para las de 64 bits, la versión de 64 bits.13
Hay otra precaución importante. Si se inicia Compatibility Administrator con permisos de administrador (en estado elevado) y se prueba así, la virtualización de UAC y la redirección no funcionan como deberían, y se puede llegar a la conclusión errónea de que “se corrigió”. Confirme siempre el efecto de la corrección con la misma cuenta y los mismos permisos que el usuario real.4
flowchart TB
accTitle: Dos precauciones al usar Compatibility Administrator
accDescr: Para corregir aplicaciones de 32 bits se usa la versión de 32 bits y para las de 64 bits la versión de 64 bits, y el efecto de la corrección se debe confirmar con la misma cuenta y los mismos permisos que el usuario real, no en estado elevado
app32["Aplicación de 32 bits"] --> tool32["Corregir con la versión de 32 bits"]
app64["Aplicación de 64 bits"] --> tool64["Corregir con la versión de 64 bits"]
elev["Probar en estado elevado"] -.-> wrong["Riesgo de creer que se corrigió sin ser así"]
user["Probar con los mismos permisos que el usuario real"] --> ok["Confirma el efecto correctamente"]
Figura 10: Usar la versión de 32 o 64 bits según corresponda, y confirmar con los mismos permisos que el usuario real, son las precauciones de entrada.
6.2. Procedimiento para crear una base de datos de compatibilidad personalizada
El flujo general es el siguiente.14
- En el panel izquierdo de Compatibility Administrator, en “Custom Databases”, cree una base de datos nueva y elija “Create New” → “Application Fix”
- Escriba el nombre de la aplicación y del proveedor, y especifique el archivo EXE de destino
- Elija el modo de compatibilidad (capa) que se va a aplicar ── probar primero con un conjunto como “Compatibilidad con Windows XP” es el camino más rápido
- Si hace falta, añada correcciones de compatibilidad (shims) individuales ── se puede reducir a una configuración mínima, como usar solo VersionLie o solo CorrectFilePaths
- Confirme las condiciones de coincidencia (tamaño de archivo, suma de comprobación, versión, etc.) y guarde
Las condiciones de coincidencia son la clave para “que solo afecte a este EXE en concreto”. Las condiciones básicas predeterminadas suelen bastar, pero se recomienda dejar una condición que identifique la versión de la aplicación, porque así se evita el incidente de que, cuando el proveedor publique en el futuro una versión corregida, la mentira antigua se siga aplicando también a la versión nueva.1415
flowchart TB
accTitle: Procedimiento para crear una base de datos de compatibilidad personalizada
accDescr: Se crea un Application Fix en una base de datos nueva, se especifica el nombre de la aplicación y el EXE de destino, se prueba primero con el conjunto de un modo de compatibilidad, si hace falta se reduce a shims individuales, y se confirman las condiciones de coincidencia antes de guardar
new["Crear una base de datos nueva"] --> fix["Elegir Application Fix"]
fix --> info["Especificar nombre de app y EXE de destino"]
info --> layer["Probar con el conjunto del modo de compatibilidad"]
layer --> single["Reducir a shims individuales si hace falta"]
single --> match["Confirmar condiciones de coincidencia y guardar"]
match -.-> ver["Dejar una condición que identifique la versión"]
Figura 11: El Application Fix se prueba primero con el conjunto de un modo de compatibilidad, se reduce a la configuración mínima y se limita el objetivo con las condiciones de coincidencia.
El .sdb creado se prueba primero en un equipo de verificación. Si funciona como se esperaba, se pasa al despliegue en la organización.
6.3. Distribución con sdbinst
El comando para aplicar el .sdb personalizado a cada PC es sdbinst.exe (requiere permisos de administrador).15
:: Instalación (-q es modo silencioso sin confirmación)
sdbinst -q "C:\Deploy\MyCorpFixes.sdb"
:: Desinstalación (especificando el archivo)
sdbinst -q -u "C:\Deploy\MyCorpFixes.sdb"
:: Desinstalación (especificando el GUID de la base de datos)
sdbinst -q -u -g {GUID de la base de datos}
Como estrategia de despliegue en la organización, Microsoft recomienda consolidar y gestionar de forma centralizada una única base de datos personalizada por empresa (o una por departamento), en lugar de incluir un .sdb individual con el instalador de cada aplicación. Cuantas más correcciones se acumulen, más fácil es de gestionar actualizar y redistribuir una sola base de datos que repartir numerosas bases de datos de una sola línea cada una. La base de datos personalizada tiene un GUID propio, y al instalar una nueva versión con el mismo GUID, la versión anterior se reemplaza automáticamente, lo que también simplifica la operación de actualización. La distribución en sí se puede llevar sobre las vías de distribución existentes que se ejecutan con permisos de administrador, como el empaquetado en MSI o un script de inicio.15
flowchart TB
accTitle: Del proceso de creación a la distribución del .sdb personalizado
accDescr: Se crea una base de datos de compatibilidad personalizada en Compatibility Administrator, se prueba en un equipo de verificación, se aplica a cada PC con sdbinst, y al actualizar se instala una nueva versión con el mismo GUID que reemplaza automáticamente a la anterior
make["Crear en Compatibility Administrator"] --> test["Probar en equipo de verificación"]
test --> deploy["Aplicar a cada PC con sdbinst"]
deploy --> update["Instalar nueva versión con el mismo GUID"]
update -.-> replace["La versión anterior se reemplaza automáticamente"]
deploy -.-> inv["Se registra en Programas y características"]
Figura 12: El .sdb personalizado se despliega en el ciclo de creación, verificación y distribución con sdbinst, y la actualización se gestiona por el GUID.
Las bases de datos personalizadas instaladas quedan registradas como elementos en “Programas y características” (aplicaciones instaladas), así que el inventario y la eliminación también se pueden verificar desde ahí. Qué .sdb está instalado en cada PC es información que debería figurar en el inventario de gestión de activos.
7. Casos en los que no funciona y sus límites
El shim no es omnipotente. Por su propio diseño, no funciona en los siguientes casos.
- Problemas en modo kernel. Como el shim se ejecuta dentro de un proceso en modo usuario, no puede corregir incompatibilidades de controladores de dispositivo. Si el controlador de un instrumento de medición antiguo, una llave USB o una impresora no admite Windows 11, nada de lo que se aplique del lado de la aplicación resuelve el problema. Lo mismo ocurre con código que se ejecuta en modo kernel, como parte de algunos antivirus.3
- Aplicaciones de 16 bits. Windows de 64 bits no admite la ejecución de aplicaciones de 16 bits. Esto se debe a que en Windows de 64 bits los handles tienen 32 bits válidos y no se pueden truncar y pasar a una aplicación de 16 bits, por lo que el inicio falla con
ERROR_BAD_EXE_FORMAT.8 Existen paquetes de aquella época en los que el cuerpo de la aplicación es de 32 bits pero la parte de arranque del instalador (el stub) es de 16 bits, y en ese caso el síntoma se manifiesta como “la aplicación funciona, pero no se puede instalar”. - Acceso directo al hardware. Las aplicaciones industriales que presuponen tocar directamente puertos de E/S o memoria física ya no lo tienen permitido desde el modo usuario en el Windows moderno, y esto queda fuera del alcance de lo que un shim puede simular.
- Eludir mecanismos de seguridad. Como el shim se ejecuta bajo las mismas restricciones de seguridad que la aplicación, no puede hacer posible “lo que no se puede hacer por falta de permisos”. ForceAdminAccess y WRPMitigation solo simulan el éxito de una comprobación o una escritura para que la aplicación siga adelante; no llegan a modificar realmente el recurso protegido.34
- Aplicaciones con comprobación de autointegridad. Las aplicaciones con protecciones anticopia antiguas o detección de manipulación pueden dejar de funcionar al considerar el propio hook de API como una anomalía.
flowchart TB
accTitle: Casos en los que el shim no funciona
accDescr: Como el shim se ejecuta dentro de un proceso en modo usuario, no sirve para problemas de controladores en modo kernel, aplicaciones de 16 bits, acceso directo al hardware ni para eludir mecanismos de seguridad
shim["Shim(se ejecuta en modo usuario)"] -->|No funciona| drv["Controladores en modo kernel"]
shim -->|No funciona| b16["Aplicaciones de 16 bits"]
shim -->|No funciona| hw["Acceso directo al hardware"]
shim -->|No funciona| sec["Eludir mecanismos de seguridad"]
b16 -.-> fmt["En 64 bits el propio arranque falla"]
sec -.-> fake["Solo simula el éxito para avanzar"]
Figura 13: El shim está limitado al modo usuario y no llega al kernel, a las aplicaciones de 16 bits, al acceso directo al hardware ni a eludir la seguridad.
Y hay una limitación esencial común a todos los shims: son un remedio provisional. El shim es una mentira ajustada a un uso concreto de una API concreta, y si la implementación del lado del SO cambia, esa premisa se desmorona. Los shims que provee Microsoft se mantienen mediante Windows Update como parte de Windows3, pero cuidar la mentira aplicada mediante una base de datos personalizada corresponde a la propia organización. Cuente con la operación de verificar en cada actualización de funciones la “lista de aplicaciones prolongadas con shim” como parte del costo de esa prolongación.
flowchart TB
accTitle: El shim como remedio provisional y la responsabilidad de mantenerlo
accDescr: El shim es una mentira ajustada a un uso concreto de la API que deja de tener sentido si cambia la implementación del SO, los shims de Microsoft se mantienen mediante Windows Update, pero cuidar la mentira de una base de datos personalizada corresponde a la propia organización, y la verificación en cada actualización de funciones es el costo de esa prolongación
shim["El shim es una mentira provisional"] --> break["Deja de tener sentido si cambia el SO"]
ms["Shims provistos por Microsoft"] --> wu["Se mantienen vía Windows Update"]
own["Mentira de la base de datos personalizada"] --> self["Cuidarla corresponde a la organización"]
self --> cost["Verificar en cada actualización es el costo"]
Figura 14: La responsabilidad de mantener esta mentira que es el shim se reparte entre lo que provee Microsoft y lo que la propia organización personaliza.
8. El valor práctico de RunAsInvoker ── silenciar solo la solicitud de elevación
Entre todos los shims, el que más se usa en el trabajo diario de sistemas es RunAsInvoker.
Hay aplicaciones de negocio antiguas que declaran requireAdministrator en el manifiesto, o que se detectan por error como instaladores por su nombre de EXE o su contenido, y que solicitan elevación de UAC cada vez que se inician. Sin embargo, en muchos casos solo solicitan permisos de administrador por inercia de la época de XP, sin usarlos realmente. Al aplicar el shim RunAsInvoker se sobrescriben tanto la detección de instalador como el manifiesto, y la aplicación se inicia con el token heredado del proceso padre (es decir, con permisos de usuario estándar).9
flowchart TB
accTitle: Cómo RunAsInvoker suprime la solicitud de elevación
accDescr: La declaración requireAdministrator del manifiesto y la detección errónea como instalador provocan la solicitud de elevación de UAC al iniciar, pero al aplicar RunAsInvoker ambas se sobrescriben y la aplicación arranca con el token heredado del proceso padre
manifest["Declaración requireAdministrator"] --> shim{"¿Se aplica RunAsInvoker?"}
detect["Detectada como instalador por error"] --> shim
shim -->|No| uac["Solicita elevación de UAC cada vez"]
shim -->|Sí| token["Arranca con el token del padre"]
token -.-> limit["Lo que requiere admin falla dentro de la app"]
Figura 15: RunAsInvoker solo sobrescribe la causa de la solicitud de elevación; los permisos no aumentan.
Sin necesidad de crear un .sdb con Compatibility Administrator, se puede aplicar temporalmente la misma capa mediante la variable de entorno __COMPAT_LAYER.
:: Aplica RunAsInvoker a los procesos hijo iniciados desde este símbolo del sistema
set __COMPAT_LAYER=RunAsInvoker
start "" "C:\LegacyApp\Gyomu.exe"
# En PowerShell
$env:__COMPAT_LAYER = 'RunAsInvoker'
Start-Process 'C:\LegacyApp\Gyomu.exe'
Si estas dos líneas se convierten en un archivo por lotes y se distribuyen a modo de acceso directo, no hace falta dar permisos de administrador local a los usuarios estándar, y tampoco hace falta que llamen a sistemas cada vez por la contraseña de UAC. Es una técnica de compatibilidad orientada a reforzar la seguridad, alineada además con el principio de mínimo privilegio.
flowchart TB
accTitle: El efecto de distribuir el archivo por lotes de RunAsInvoker
accDescr: Si se distribuye como acceso directo un archivo por lotes de dos líneas que configura RunAsInvoker, no hace falta dar permisos de administrador local a los usuarios, TI deja de recibir llamadas por la contraseña de UAC, y la operación se ajusta al principio de mínimo privilegio
bat["Distribuir el batch de dos líneas"] --> noadmin["No hace falta dar permisos de administrador"]
bat --> nocall["TI ya no recibe llamadas por UAC"]
noadmin --> lp["Operación conforme al mínimo privilegio"]
nocall --> lp
Figura 16: Solo con distribuir el archivo por lotes se reduce tanto el reparto de permisos de administrador como las llamadas por UAC.
Conviene dejar claras también las precauciones.
- No aumentan los permisos. Las operaciones que realmente necesitan permisos de administrador (escribir en HKLM, actualizar algo dentro de Program Files, etc.) darán error dentro de la aplicación, o si se cumplen las condiciones, se redirigirán al VirtualStore mediante la virtualización de UAC.10 Si parece que “dejó de funcionar” el guardado de configuración, sospeche de la virtualización.
- El método de la variable de entorno solo afecta a los procesos hijo. Si se desea una aplicación permanente, lo más seguro es la pestaña de compatibilidad (como RUNASINVOKER no tiene un elemento en la pestaña, hay que configurarlo directamente en la clave Layers) o la distribución mediante .sdb.
- Corregir el destino de escritura es lo esencial. Si se puede modificar la aplicación, lo correcto es mover el archivo de configuración a
%APPDATA%y declararasInvokeren el manifiesto.9
flowchart TB
accTitle: Aplicación temporal frente a permanente de RunAsInvoker
accDescr: La aplicación mediante la variable de entorno COMPAT_LAYER solo afecta a los procesos hijo lanzados desde ahí, y para aplicarla de forma permanente se usa la configuración directa en la clave Layers o la distribución mediante .sdb
env["Configurar por variable de entorno"] --> child["Solo afecta a procesos hijo"]
child -.-> tmp["Aplicación temporal"]
layers["Configurar directamente en la clave Layers"] --> always["Aplicación permanente"]
sdb["Distribuir mediante sdb"] --> always
Figura 17: El método de la variable de entorno es una aplicación temporal limitada a los procesos hijo, y la aplicación permanente se logra con la clave Layers o el .sdb.
9. La decisión entre prolongar la vida útil o migrar ── qué pensar después de que un shim haga funcionar la aplicación
El momento en que la aplicación empieza a funcionar con el shim trae alivio, pero es importante no detener ahí el análisis. Que funcione con un shim solo significa que encajó por casualidad en uno de los receptáculos que Windows tiene preparados. A continuación, los ejes de decisión en forma de tabla.
| Eje de decisión | Condiciones que inclinan a prolongar (shim) | Condiciones que inclinan a migrar/rehacer |
|---|---|---|
| Tiempo de uso restante | Se prevé retirar el proceso de negocio en 1-2 años | Se prevé seguir usándola 5 años o más |
| Código fuente | No existe (proveedor desaparecido o código perdido) | Existe, o el activo se puede recuperar |
| Profundidad de la dependencia | Solo un problema de compatibilidad de API en modo usuario | Depende de controladores, 16 bits o hardware dedicado |
| Alternativa disponible | No existe un producto empaquetado ni una versión nueva | Existe un producto o tecnología de destino claro |
| Impacto de un fallo | Si se detiene, el negocio sigue con un procedimiento alterno | Un fallo golpea directamente el negocio central |
| Capacidad de verificación | Se puede comprobar el funcionamiento en cada actualización | No hay recursos de verificación y tiende a quedar congelado |
Si se decide prolongar la vida útil, incorpore a la operación estos tres puntos como conjunto.
- Registrar. A qué EXE, con qué shim o capa, y por qué motivo se aplicó. Deje constancia en el inventario del valor de la clave Layers y del GUID del .sdb. El estado de “nadie sabe por qué funciona” es el mayor pasivo que se le puede dejar al siguiente responsable. Esta idea es la misma lógica de conservación que se trató en «Cuando hereda un sistema sin código fuente ni documentación».
- Verificar. Incluya en los ítems de verificación de cada actualización de funciones de Windows el inicio y las operaciones principales de las aplicaciones prolongadas con shim. Coordínelo también con el plan de renovación del SO (Soluciones realistas tras el fin de soporte de Windows 10).
- Fijar un plazo. Decida el final de la prolongación, por ejemplo “hasta la próxima renovación del sistema central” o “hasta marzo de 2028”, y avance en paralelo el estudio de la migración.
flowchart TB
accTitle: El conjunto de tres prácticas al decidir prolongar la vida útil
accDescr: Se registra en un inventario con qué shim funciona la aplicación, se verifica su comportamiento en cada actualización de funciones, y se fija un plazo para el fin de la prolongación mientras se avanza en paralelo el estudio de la migración
decide["Decidir prolongar la vida útil"] --> rec["Registrar: con qué shim funciona"]
rec --> verify["Verificar: comprobar en cada actualización"]
verify --> deadline["Plazo: fijar el fin de la prolongación"]
deadline --> mig["Avanzar en paralelo el estudio de migración"]
Figura 18: La prolongación de vida útil se opera como un conjunto de registro, verificación y plazo, incluyendo el avance en paralelo del estudio de migración.
Las opciones del lado de la migración siguen prácticas habituales distintas según la tecnología de la aplicación. Si está hecha en VB6, se puede usar la elección entre las tres opciones de reescritura completa, conversión automática o migración por etapas que se organizó en «¿Hasta cuándo funcionarán las aplicaciones VB6?»; si depende de ActiveX/OCX, se puede usar la tabla de decisión de mantener, envolver o reemplazar de «Cómo tratar ActiveX / OCX hoy». Lo saludable es posicionar el shim como una forma de ganar tiempo con seguridad para el estudio y la preparación de ese proyecto de migración.
flowchart TB
accTitle: Las opciones de migración y el lugar que ocupa el shim
accDescr: Las prácticas habituales de migración cambian según la tecnología de la aplicación, para VB6 la elección entre reescritura completa, conversión automática o migración por etapas, para dependencias de ActiveX la tabla de mantener, envolver o reemplazar, y el shim se posiciona como una forma de ganar tiempo con seguridad para el estudio y la preparación del proyecto de migración
tech{"¿Qué tecnología usa la aplicación?"} -->|VB6| vb["Reescritura, conversión automática o migración por etapas"]
tech -->|Dependencia de ActiveX| ax["Mantener, envolver o reemplazar"]
shim["Prolongación con shim"] -.->|Gana tiempo para estudio y preparación| tech
Figura 19: Las prácticas habituales de migración dependen de la tecnología de la aplicación, y el shim se posiciona como una forma de ganar ese tiempo de estudio.
10. Resumen
- La verdadera naturaleza del modo de compatibilidad es el shim. La configuración de la pestaña de compatibilidad se escribe en la clave AppCompatFlags\Layers y, al iniciar el proceso, se inyecta como un hook de API mediante la sustitución de la IAT.
- El shim es un conjunto de “mentiras que devuelven la respuesta que la aplicación antigua espera”. Hay shims listos para usar como la falsificación de versión, la redirección de rutas, la falsificación del registro o la falsificación de la comprobación de administrador.
- El propio Windows usa una gran cantidad de shims de forma predeterminada, y el PCA a veces los aplica automáticamente. Depender del modo de compatibilidad es en sí mismo una decisión razonable que se apoya en un mecanismo oficial del SO.
- Existe una limitación de principio: está restringido al modo usuario y no puede eludir la seguridad, por lo que no puede salvar controladores de kernel, aplicaciones de 16 bits ni el acceso directo al hardware.
- El despliegue en la organización se hace creando un .sdb personalizado con Compatibility Administrator (Windows ADK) y distribuyéndolo con sdbinst. Los puntos clave en la práctica son usar la versión de 32 o 64 bits según corresponda, probar con la cuenta de uso real y gestionar las actualizaciones mediante el GUID.
- Una aplicación que “solicita permisos de administrador sin necesitarlos realmente” se puede llevar a permisos estándar con
__COMPAT_LAYER=RunAsInvoker. Es una técnica defensiva que silencia la solicitud de elevación en lugar de repartir permisos. - Que funcione con un shim es una prolongación de vida, no una solución. Registrar con qué funciona, verificarlo en cada actualización de funciones y fijar un plazo para avanzar la migración en paralelo: la decisión de “depender del modo de compatibilidad” incluye este conjunto de tres puntos.
La próxima vez que una aplicación antigua funcione al marcar el modo de compatibilidad, vuelva a preguntarse: “¿gracias a qué mentira funciona esta aplicación? ¿Hasta cuándo seguirá siendo válida esa mentira?”. Si puede responder a eso, prolongar su vida es una estrategia perfectamente legítima.
Artículos relacionados
- Redirección y virtualización de 32/64 bits en el registro de Windows ── Wow6432Node y el problema del “valor que debería estar y no está”
- ¿Hasta cuándo funcionarán las aplicaciones VB6? ── el estado de soporte del runtime y cómo avanzar de forma realista hacia .NET
- Cómo tratar ActiveX / OCX hoy - tabla de decisión: mantener, envolver o reemplazar
- Soluciones realistas tras el fin de soporte de Windows 10 ── tabla de decisión entre ESU, LTSC y renovar el equipo
- Cuando hereda un sistema sin código fuente ni documentación ── procedimientos prácticos para operarlo y mantenerlo sin detenerlo
- La integración con el shell de Windows hoy ── el menú contextual, la asociación de archivos y los cambios en Windows 11
Áreas de consultoría relacionadas
KomuraSoft LLC se ocupa de investigar el funcionamiento de aplicaciones de negocio antiguas sin código fuente y de diseñar su prolongación de vida (selección de shims y modos de compatibilidad, creación y despliegue de .sdb personalizados), de verificar la compatibilidad de aplicaciones existentes al migrar a Windows 11, y de elaborar planes de reconstrucción o migración que avancen en paralelo con la prolongación. Puede consultarnos incluso desde la etapa de “funcionó con el modo de compatibilidad, pero no sé si dejarlo así”.
- Aprovechamiento de activos existentes y apoyo a la migración
- Desarrollo de aplicaciones Windows
- Consultoría técnica y revisión de diseño
- Contacto
Referencias
-
Microsoft Learn, Application Compatibility Database. Sobre que la infraestructura de compatibilidad gestiona problemas y soluciones mediante una base de datos en formato .sdb, la coincidencia por atributos del ejecutable, Apphelp (muestra de mensajes) y Appfix (hook de API mediante shims), y la capa de compatibilidad (modo) que agrupa varios shims y flags. ↩ ↩2 ↩3
-
Microsoft Learn, DXGI overview. Sobre que la configuración de compatibilidad de aplicaciones se guarda en la clave del registro HKCU\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers (tomando como ejemplo la configuración de compatibilidad de DXGI). ↩ ↩2
-
Microsoft Learn, Understanding and Using Compatibility Fixes. Sobre que las correcciones de compatibilidad (shims) redirigen las llamadas a la API reescribiendo la IAT (tabla de direcciones de importación), que la vinculación dinámica se cubre con un hook sobre GetProcAddress, que el shim está sujeto a las mismas restricciones de seguridad que la aplicación y no puede eludir los mecanismos de seguridad del SO, que está limitado al modo usuario y no puede corregir problemas de controladores, que lo que un shim puede corregir también se puede corregir modificando el código, los escenarios de uso en aplicaciones sin soporte del proveedor, y que las correcciones de compatibilidad de Microsoft se distribuyen como parte de Windows y se actualizan mediante Windows Update. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8
-
Microsoft Learn, Compatibility Fixes for Windows 10, Windows 8, Windows 7, and Windows Vista. Sobre la lista y la descripción de correcciones de compatibilidad conocidas como CorrectFilePaths, VirtualRegistry, ForceAdminAccess, RunAsAdmin/RunAsHighest/RunAsInvoker, WRPMitigation, EmulateGetDiskFreeSpace, GlobalMemoryStatusLie, LoadLibraryRedirect y la familia VersionLie, el uso diferenciado de las versiones de 32 y 64 bits de Compatibility Administrator, y que probar en estado elevado impide que la virtualización y la redirección funcionen como se espera, por lo que hay que verificar con la cuenta de uso real. ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, Program Compatibility Assistant scenarios for Windows 8. Sobre que el PCA supervisa la ejecución de aplicaciones, detecta indicios de problemas de compatibilidad conocidos y sugiere o aplica automáticamente correcciones recomendadas (PINDLL, DISABLEUSERCALLBACKEXCEPTION, VIRTUALIZEDELETE, WRPMITIGATION, etc.), y sobre la aplicación de correcciones desde la pestaña de compatibilidad y la herramienta de solución de problemas de compatibilidad. ↩ ↩2
-
Microsoft Learn, GetVersionExW function. Sobre que, desde Windows 8.1, el valor devuelto por GetVersionEx depende del manifiesto, que a las aplicaciones sin manifiesto para Windows 8.1/10 se les devuelve el valor de versión de Windows 8 (6.2), y que cuando el modo de compatibilidad está activo se reporta la versión del SO seleccionado. ↩ ↩2 ↩3
-
Microsoft Learn, Targeting your application for Windows. Sobre el método para declarar los GUID de los SO admitidos mediante el elemento supportedOS en la sección compatibility del manifiesto de la aplicación, el comportamiento cuando no hay declaración, y que las aplicaciones x86 de 32 bits interactivas que no incluyen trustInfo son objeto de la virtualización de archivos de UAC (redirección de escritura al VirtualStore). ↩ ↩2
-
Microsoft Learn, Running 32-bit Applications. Sobre que WOW64 es una capa de emulación que ejecuta aplicaciones de 32 bits en Windows de 64 bits y aísla los conflictos de archivos y de registro, y que Windows de 64 bits no admite la ejecución de aplicaciones de 16 bits, por lo que el inicio falla con ERROR_BAD_EXE_FORMAT debido al problema de los bits válidos del handle. ↩ ↩2
-
Microsoft Learn, Using the RunAsInvoker Fix. Sobre que la corrección de compatibilidad RunAsInvoker hace que la aplicación se inicie con el token heredado del proceso padre, que sobrescribe tanto la detección de instalador como el procesamiento del manifiesto, que se aplica como una marca del cargador sin interceptar la API, y que si se puede corregir el código, lo correcto es declarar asInvoker en el manifiesto. ↩ ↩2 ↩3
-
Microsoft Learn, Registry Virtualization. Sobre que la virtualización del registro es una tecnología de compatibilidad que redirige de forma transparente al VirtualStore de cada usuario las escrituras globales en HKLM\Software, que solo se aplica a procesos interactivos de 32 bits y no a procesos que especifican requestedExecutionLevel en el manifiesto ni a procesos de 64 bits, y que se posiciona como una tecnología provisional que se prevé eliminar en futuras versiones de Windows. ↩ ↩2
-
Microsoft Learn, High DPI Desktop Application Development on Windows. Sobre que una aplicación sin compatibilidad DPI se trata como si dibujara siempre a 96 DPI, que en pantallas de alto DPI Windows amplía el mapa de bits para mostrarla y por eso se ve borrosa, y sobre las diferencias entre los modos de reconocimiento de DPI (Unaware/System/Per-Monitor). ↩ ↩2
-
Microsoft Learn, Download and install the Windows ADK. Sobre que el Windows ADK incluye Compatibility Administrator y Standard User Analyzer, y sobre el criterio de selección de la versión del ADK y el método de descarga e instalación. ↩
-
Microsoft Learn, Compatibility Administrator User’s Guide. Sobre que Compatibility Administrator ofrece funciones para aplicar correcciones de compatibilidad, modos de compatibilidad y mensajes AppHelp, y para crear bases de datos personalizadas, que se instalan tanto la versión de 32 bits como la de 64 bits, y que hay que usar la versión de 32 bits para aplicaciones de 32 bits y la de 64 bits para aplicaciones de 64 bits. ↩
-
Microsoft Learn, Creating a Custom Compatibility Fix in Compatibility Administrator. Sobre que una corrección de compatibilidad (antes llamada shim) es un pequeño fragmento de código que se interpone en las llamadas a la API, el procedimiento para crear un Application Fix en una base de datos personalizada (especificación del nombre de la aplicación, el proveedor y el EXE de destino, selección del modo de compatibilidad, selección de shims adicionales, configuración de las condiciones de coincidencia), y que conviene dejar condiciones que reduzcan la información de coincidencia sin dejar de identificar correctamente la aplicación. ↩ ↩2
-
Microsoft Learn, Compatibility Fix Database Management Strategies and Deployment. Sobre que se recomienda una base de datos de gestión centralizada como estrategia de gestión de bases de datos de compatibilidad personalizadas, que las correcciones de compatibilidad deberían incluir una comprobación de versión (condición de coincidencia) para que no se apliquen a versiones nuevas, la instalación local mediante Sdbinst.exe (opciones -q, -u, -g), que al instalar una nueva versión con el mismo GUID de base de datos la versión anterior se desinstala automáticamente, y los métodos de distribución mediante MSI o scripts. ↩ ↩2 ↩3
Artículos relacionados
Artículos recientes con las mismas etiquetas para profundizar en temas cercanos.
Cómo funcionan el portapapeles y arrastrar y soltar — Gestionar correctamente la transferencia de datos OLE en aplicaciones empresariales
Una tabla de Excel se deforma al pegarla y deja de poder pegarse si cierra el origen: es el portapapeles colocando el mismo contenido en ...
WPR/WPA en la práctica — Introducción al análisis de rendimiento del sistema para «todo el PC va lento»
Problemas como «todo el PC va lento» o «el arranque es lento», que el Administrador de tareas no explica, se investigan con WPR/WPA leyen...
El apagado de Windows visto desde la aplicación ── cómo sobrevivir correctamente a la notificación de cierre, el reinicio y el corte de energía
Un reinicio nocturno de Windows Update corrompió datos de medición: ese accidente se evita con buen diseño. Explicamos, con fuentes ofici...
Cómo interpretar los códigos de error de Windows — la estructura de tres capas de Win32, HRESULT y NTSTATUS
Antes de buscar 0x80004005, descompóngalo. Explicamos la estructura de tres capas Win32/HRESULT/NTSTATUS, el patrón 0x8007xxxx y cómo inv...
¿Qué representa realmente el «uso de memoria» de Windows? — Cómo interpretar correctamente Working Set, Private Bytes, Commit y el archivo de paginación
La memoria de Task Manager, Working Set, Private Bytes y Commit no son el mismo valor. Explica la memoria virtual y física de Windows y q...
Temas relacionados
Estas páginas sitúan el tema en un contexto más amplio de servicios y decisiones.
Temas técnicos de Windows
Portal sobre desarrollo de Windows, investigación de fallos y aprovechamiento de activos existentes.
Servicios relacionados con este tema
El artículo está directamente relacionado con los siguientes servicios.
Desarrollo de aplicaciones para Windows
Aplicaciones empresariales, integración de dispositivos y herramientas de comunicación, de los requisitos al desarrollo.
Preguntas frecuentes
Preguntas habituales en las consultas sobre el tema del artículo.
- ¿Está bien seguir usando una aplicación que empezó a funcionar al activar el modo de compatibilidad?
- Para la continuidad del negocio en lo inmediato, no hay problema en seguir usándola. La realidad del modo de compatibilidad es el shim, un hook de API en modo usuario, un mecanismo previsto oficialmente como configuración del sistema operativo. Sin embargo, el shim es solo un remedio provisional para hacer funcionar la aplicación sin corregirla, y si una actualización del SO cambia las premisas, puede volver a dejar de funcionar. Registre en un inventario el hecho de que la aplicación funciona gracias al modo de compatibilidad, y gestiónelo junto con la decisión de si rehacer la aplicación o prolongar su vida de forma planificada.
- ¿Qué hace exactamente la casilla del modo de compatibilidad?
- Al guardar la configuración en la pestaña de compatibilidad de las propiedades, se escribe en la clave HKCU\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers la ruta del EXE de destino junto con valores como «WINXPSP3» o «HIGHDPIAWARE». La siguiente vez que se inicia ese EXE, el cargador de Windows lee ese valor y aplica al proceso la capa de compatibilidad correspondiente (un conjunto de shims). Por ejemplo, en el modo de compatibilidad con Windows XP entra en juego, entre otras cosas, la falsificación de versión, que devuelve un valor antiguo a la API que consulta la versión del SO. No se cambia el comportamiento del sistema operativo en sí, sino que se le hace creer únicamente a ese proceso que está ante «una versión antigua de Windows».
- ¿Se puede ejecutar con el modo de compatibilidad una aplicación antigua de la era de 16 bits en Windows de 64 bits?
- No se puede. Windows de 64 bits ejecuta aplicaciones de 32 bits mediante un mecanismo llamado WOW64, pero no admite la ejecución de aplicaciones de 16 bits, y al intentar iniciarlas falla con ERROR_BAD_EXE_FORMAT. Se trata de una limitación arquitectónica que el shim no puede sortear. Los paquetes antiguos en los que solo la parte de arranque del instalador es de 16 bits fallan por el mismo motivo. Si es absolutamente necesario, hay que considerar medios distintos del modo de compatibilidad, como una máquina virtual con una versión de 32 bits de Windows.
- ¿Se puede ejecutar con permisos de usuario estándar una aplicación que «no arranca si no se ejecuta como administrador»?
- Vale la pena probar con RunAsInvoker. Si en el símbolo del sistema se ejecuta set __COMPAT_LAYER=RunAsInvoker antes de iniciar la aplicación, se suprime la solicitud de elevación provocada por la declaración requireAdministrator del manifiesto o por la detección de instalador, y la aplicación se inicia con los mismos permisos (de usuario estándar) que el proceso que la invocó. Si se trata de una aplicación que «solo solicita permisos de administrador sin usarlos realmente», esto basta para eliminar la elevación de la operación diaria. Sin embargo, como los permisos no aumentan, cualquier operación que realmente necesite permisos de administrador seguirá fallando dentro de la aplicación. Adóptelo después de confirmar el funcionamiento.
- ¿Dónde se consigue Compatibility Administrator?
- Está incluido en el Windows ADK (Windows Assessment and Deployment Kit). Al descargar el ADK desde el sitio de Microsoft y seleccionar durante la instalación las funciones de la familia Application Compatibility Tools, queda disponible para usarse. Se instalan tanto la versión de 32 bits como la de 64 bits, y hay que tener en cuenta que para corregir aplicaciones de 32 bits se debe usar la versión de 32 bits, y para las de 64 bits, la versión de 64 bits. La base de datos de compatibilidad personalizada (.sdb) que se cree se aplica en cada PC ejecutando el comando sdbinst.
Perfil del autor
Página de presentación del autor del artículo.
Go Komura
Representante de KomuraSoft LLC
Especializado en desarrollo de software para Windows, consultoría técnica e investigación de fallos, sobre todo en proyectos con sistemas existentes y errores difíciles de reproducir.