2010-08-09 15 views
5

¿Existe una función de C++ .NET a la que pueda llamar que detectará si mi programa se está ejecutando en modo de compatibilidad? Si no hay uno, ¿podría alguien mostrarme el código para uno? Gracias.Es un programa que se ejecuta en modo de compatibilidad

Por ejemplo:

cargas programar hasta de comprobación de compatibilidad Modo si es cierto entonces salir demás ejecutar

+0

¿Qué quiere decir con "compatibilidad"? – Klaim

+3

Los usuarios de todo tipo lo ODIAN si deshabilita el modo de compatibilidad para su aplicación. ¿Por qué querrías hacer eso? –

+0

Sí, la desactivación del modo de compatibilidad es bastante restrictiva –

Respuesta

8

de otro foro

Después de unas cuantas búsquedas de Google fue en vano, me Decidí experimentarme a mí mismo. Encontré que las configuraciones de compatibilidad para cada ejecutable son almacenadas, como pensé que sería, en el registro de Windows.

La clave, donde los ajustes se almacenan es
HKEY_CURRENT_USER \ Software \ Microsoft \ Windows NT \ CurrentVersion \ AppCompatFlags \ Capas

Para cada aplicación que tiene su configuración de compatibilidad especificado, existe un valor bajo esa clave cuyo nombre es la ruta al ejecutable y los datos son una cadena que consta de la configuración de compatibilidad .

Las palabras clave en la cadena que especificar la configuración de compatibilidad son: WIN95 WIN98 NT4SP5
WIN2000 256color 640X480
DisableThemes DisableCicero

Si se especifican varios ajustes (o deben especificarse), los datos consiste en la configuración superior a separados por un espacio cada uno. Los primeros cuatro ajustes de son mutuamente excluyentes, , es decir, solo uno de ellos debe ser especificado (si es que lo está). No he probado las consecuencias de especificar sistemas operativos múltiples.

Entonces, volvamos a solucionar su problema. para comprobar si un archivo ejecutable (digamos, "C: \ ruta \ executable.exe") se ajusta en se ejecute en modo de 256 colores, no habría un valor denominado "C: \ ruta \ executable.exe" (sin las comillas, incluso si la ruta contiene espacios) bajo la clave [HKEY_CURRENT_USER \ Software \ Microsoft \ Windows NT \ CurrentVersion \ AppCompatFlags \ Capas], y los datos asociados con el valor contendría la cadena "256color ". Si también está configurado para ejecutarse en el modo de compatibilidad bajo Windows 98/ME, los datos serían "WIN98 256COLOR".

Por lo tanto, el enfoque es simple. Pruebe si hay un valor con la ruta completa de el ejecutable bajo la clave I mencionada anteriormente.Si no existe, el ejecutable no se ha especificado ninguna configuración de compatibilidad . Si existe el valor , recupere sus datos y verifique para conocer la presencia de "256COLOR" en los datos . Por consiguiente, la presencia de "WIN95" o "WIN98" o "NT4SP5" o "WIN2000" significa que el ejecutable está configurado para ejecutarse en el modo de compatibilidad para ese sistema operativo particular .

+1

Genial, pero en el código, ¿cómo verificaría HKEY_CURRENT_USER \ Software \ Microsoft \ Windows NT \ CurrentVersion \ AppCompatFlags \ Layers por uno de estos valores? ¡Gracias! – user409939

+0

Las clases Registry y RegistryKey. Conceptualmente, es muy similar a la manera de la API de Windows en lugar de la forma .NET. –

2

obtener la versión del sistema operativo que se devuelve desde GetVersionEx y compararlo con la versión del archivo en kernel32.dll. Cuando en el modo de compatibilidad de aplicaciones GetVersionEx siempre devolverá la versión del sistema operativo que se está 'emulando'. Si ambas versiones son diferentes, entonces estás en el modo de compatibilidad de aplicaciones.

1

La respuesta anterior me ayudó a obtener una "solución" para la pregunta en cuestión. Probablemente no sea el más elegante, pero parece funcionar. Obviamente, puede ser un poco más creativo en el tipo de devolución. Booleon no es suficiente aquí. Creo que una API nativa sería buena.

typedef VOID (NTAPI* TRtlGetNtVersionNumbers)(LPDWORD pdwMajorVersion, LPDWORD pdwMinorVersion, LPDWORD pdwBuildNumber); 

bool IsRunningCompatMode() 
{ 
    TRtlGetNtVersionNumbers RtlGetNtVersionNumbers = (TRtlGetNtVersionNumbers)GetProcAddress(GetModuleHandleA("ntdll.dll"), "RtlGetNtVersionNumbers"); 

    assert(RtlGetNtVersionNumbers); 

    if(RtlGetNtVersionNumbers) 
    { 
     OSVERSIONINFO osInfo = {0}; 
     osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); 
     GetVersionEx(&osInfo); 

     DWORD dwMajorVersion; 
     DWORD dwMinorVersion; 
     DWORD dwBuildNumber; 

     RtlGetNtVersionNumbers(&dwMajorVersion, &dwMinorVersion, &dwBuildNumber); 

     dwBuildNumber &= 0x0000FFFF; 

     if(osInfo.dwBuildNumber != dwBuildNumber) 
     { 
      return true; 
     } 
    } 
    return false; 
}; 
Cuestiones relacionadas