Come funziona la compatibilità delle applicazioni Windows — modalità di compatibilità, shim e Compatibility Administrator
· Go Komura · Windows, Modalità di compatibilità, Shim, Compatibilità delle applicazioni, Compatibility Administrator, Riutilizzo di asset esistenti, Sviluppo Windows, Sistemi esistenti
«Un’app aziendale di dieci anni il cui codice sorgente è sparito non parte su un nuovo PC Windows 11. Ho spuntato “Windows XP” nella scheda Compatibilità della finestra Proprietà e ha funzionato e basta. — Cosa sta facendo davvero? Va bene continuare a dipenderne?» È una consulenza che sentiamo spesso.
Quando una sola casella fa funzionare qualcosa, il disagio è naturale. La vera identità della modalità di compatibilità, che sembra magia, è una raccolta di piccoli pezzi di codice chiamati shim che si interpongono tra l’app e l’API di Windows e restituiscono una «bugia». Windows stesso usa questo ripiego su larga scala per tenere in vita app di molte generazioni e apre parte del meccanismo a utenti e amministratori.
Usata senza capire il meccanismo, la prolungazione diventa un «non si deve toccare perché non sappiamo perché funziona» instabile. Capire il meccanismo permette di decidere, con ragioni, fino a dove potete fidarvi in sicurezza, cosa la romperà e quando dovreste riscrivere.
flowchart TB
accTitle: Capire il meccanismo cambia la qualità della prolungazione
accDescr: Usare la modalità di compatibilità senza capire il meccanismo porta a una prolungazione instabile che non osate toccare; capire il meccanismo permette di decidere con ragioni fino a dove fidarsi, cosa la romperà e quando riscrivere
unknown["Usare senza capire il meccanismo"] --> fear["Prolungazione instabile che non osate toccare"]
known["Usare dopo aver capito il meccanismo"] --> judge["Decisioni con ragioni"]
judge -.-> j1["Fino a dove potete fidarvi"]
judge -.-> j2["Cosa la romperà"]
judge -.-> j3["Quando dovreste riscrivere"]
Figura 1: Anche per la stessa prolungazione, la qualità differisce tra l’ansia di non conoscere il meccanismo e una decisione basata sulla comprensione.
Destinato al personale IT delle PMI e agli sviluppatori di app Windows che curano vecchie app aziendali, questo articolo organizza, dalle fonti primarie Microsoft Learn, il meccanismo degli shim che è la vera identità della modalità di compatibilità, cosa possono gli shim rappresentativi, come applicarli in organizzazione con Compatibility Administrator, i limiti che gli shim non salvano e come decidere tra prolungazione e migrazione.
1. Prima la conclusione
- La vera identità della modalità di compatibilità sono gli shim (un livello di compatibilità). Le impostazioni della scheda Compatibilità vengono scritte in
HKCU\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layerse all’avvio un insieme di shim viene applicato al processo.12 - Uno shim è un hook API in user mode che riscrive la import address table (IAT). Intercetta il percorso con cui l’app chiama le API di Windows e restituisce le stesse risposte che avrebbe dato un Windows vecchio. Non cambia il sistema stesso.3
- Ciò che uno shim può fare è lo stesso ambito di ciò che può fare una correzione di codice nell’app. Non può aggirare i meccanismi di sicurezza e non può correggere problemi in kernel mode (driver di dispositivo).3
- Microsoft fornisce un gran numero di shim pronti — bugie di versione, rimappatura dei percorsi file, falsificazione del registro, falsificazione dei controlli di amministratore e altro. Potete applicarli a singoli EXE da Compatibility Administrator.4
- Windows stesso usa gli shim per impostazione predefinita. Il database di compatibilità standard del sistema (.sdb) viene confrontato a ogni avvio e PCA (Program Compatibility Assistant) può anche rilevare un problema e applicare automaticamente un’impostazione di compatibilità.15
- «Rispondere come se fosse un Windows più vecchio» è ormai il comportamento predefinito. Da Windows 8.1 in poi,
GetVersionExnon restituisce una versione di sistema che l’app non ha dichiarato nel manifesto. La modalità di compatibilità è un’estensione di quel meccanismo.67 - Gli shim non funzionano su app a 16 bit, dipendenze da driver kernel o accesso hardware diretto. In particolare, le app a 16 bit non possono affatto girare su Windows a 64 bit.8
- Per le app che «richiedono l’amministratore ma non ne hanno davvero bisogno», RunAsInvoker è la mossa standard.
__COMPAT_LAYER=RunAsInvokersopprime la richiesta di elevazione e lascia girare l’app con privilegi standard.9 - Girare sotto uno shim significa che potete prolungare la vita per ora, ma la via vera è «farla girare senza shim». Se decidete di prolungare, annotate quali shim la fanno girare e gestite quello come materiale per una decisione di riscrittura.
2. Il quadro d’insieme della compatibilità delle applicazioni — i livelli di retrocompatibilità che Windows ha già
Prima di parlare di shim, ecco l’elenco dei meccanismi che Windows ha già per le app vecchie. Anche quando si dice «ha ricominciato a funzionare in modalità di compatibilità», ciò che salva davvero l’app è uno di questi livelli, o una combinazione di più.
| Livello | Cosa fa | Destinazione tipica |
|---|---|---|
| Shim (modalità di compatibilità) | Intercetta le chiamate API e falsifica le stesse risposte che avrebbe dato un Windows vecchio | App scritte per un sistema più vecchio in generale |
| Virtualizzazione UAC (file / registro) | Reindirizza le scritture senza permesso verso HKLM\Software o Program Files in un VirtualStore per utente |
App a 32 bit scritte presupponendo privilegi di amministratore |
| WOW64 | Esegue le app a 32 bit così come sono su Windows a 64 bit (fornisce viste a 32 bit del registro e del file system) | App a 32 bit in generale |
| Virtualizzazione DPI | Fa disegnare un’app non DPI-aware a 96 DPI e la mostra stirando il bitmap | App vecchie su display ad alta densità |
La virtualizzazione UAC è una misura transitoria che si applica ai processi interattivi a 32 bit senza manifesto, e Microsoft stessa afferma che è «una tecnologia temporanea che intendiamo rimuovere da una versione futura di Windows».10 Il danno reale del reindirizzamento Wow6432Node e del VirtualStore, e come affrontarlo, è trattato in dettaglio in «Registry 32-bit/64-bit Redirection and Virtualization Pitfalls»; questo articolo tiene gli shim al centro e menziona gli altri livelli solo quanto serve.
flowchart TB
accTitle: Dove sta la virtualizzazione UAC
accDescr: La virtualizzazione UAC è una misura transitoria per i processi interattivi a 32 bit senza manifesto; reindirizza le scritture in un VirtualStore per utente, ma Microsoft stessa afferma che è una tecnologia temporanea destinata alla rimozione da un Windows futuro
proc["Processo interattivo a 32 bit senza manifesto"] --> uacv["Si applica la virtualizzazione UAC"]
uacv --> vs["Reindirizzato a un VirtualStore per utente"]
uacv -.-> tmp["Tecnologia temporanea destinata a una rimozione futura"]
Figura 2: La virtualizzazione UAC è una misura transitoria per i processi a 32 bit senza manifesto e non ci si può fare affidamento in modo permanente.
Come nota a lato sulla virtualizzazione DPI: un’app che non ha dichiarato la consapevolezza DPI viene trattata come se disegnasse a 96 DPI (100%) e Windows stira il bitmap per la visualizzazione. Ecco perché le app vecchie sembrano «sfocate» su un monitor ad alta densità, e «Sostituisci il comportamento di ridimensionamento DPI elevato» della scheda Compatibilità è l’interruttore che cambia questo comportamento di virtualizzazione.11
flowchart TB
accTitle: Come funziona la virtualizzazione DPI
accDescr: Un'app che non ha dichiarato la consapevolezza DPI viene trattata come se disegnasse a 96 DPI; Windows stira il bitmap quindi sembra sfocata, e la sostituzione delle impostazioni DPI elevato della scheda Compatibilità commuta questo comportamento di virtualizzazione
app["App che non dichiara la consapevolezza DPI"] --> treat["Trattata come se disegnasse a 96 DPI"]
treat --> stretch["Il bitmap viene stirato per la visualizzazione"]
stretch --> blur["Sembra sfocata su un monitor ad alta densità"]
tab["Sostituisci il comportamento di ridimensionamento DPI elevato"] -.->|Commuta il comportamento di virtualizzazione| treat
Figura 3: Un’app non DPI-aware viene trattata come 96 DPI e stirata; la sostituzione della scheda Compatibilità è l’interruttore di questa virtualizzazione.
3. Cos’è davvero uno shim — intercettare tra le API riscrivendo l’IAT
3.1. L’«interprete» che sta tra l’app e il sistema
Un eseguibile Windows (formato PE) chiama le API in DLL esterne tramite la import address table (IAT). Quando l’app chiama GetVersionEx, sta solo saltando all’indirizzo scritto nell’IAT. Il meccanismo degli shim sfrutta quello. Al caricamento riscrive la voce IAT dell’API di destinazione verso l’indirizzo del codice dello shim e si inserisce tra l’app e Windows. Le API ottenute dinamicamente tramite GetProcAddress vengono gestite agganciando GetProcAddress stesso.3
Una volta intercettato, uno shim può restituire un numero di versione vecchio a «qual è la versione attuale del sistema?» oppure rimappare un accesso file a una posizione non scrivibile altrove, e poi chiamare la vera API se serve. Dal punto di vista dell’app sembra che «giri su un Windows vecchio»; dal punto di vista del sistema sembra che «giri un’app ben educata» — lo shim è l’interprete tra i due.
flowchart TB
accTitle: Il percorso con cui uno shim intercetta una chiamata API
accDescr: La chiamata API di un'app passa per l'IAT; riscrivere la voce IAT verso lo shim al caricamento permette allo shim di intercettare, falsificare la stessa risposta che avrebbe dato un Windows vecchio e poi chiamare la vera API se serve
app["App"] -->|Chiamata API| iat["Voce IAT"]
iat -->|Riscrivita verso lo shim al caricamento| shim["Shim (interprete)"]
shim -->|Se serve| api["La vera API di Windows"]
shim -.-> lie["Falsifica la stessa risposta che avrebbe dato un Windows vecchio"]
gpa["Chiamate via GetProcAddress"] -.->|Gestite da un hook| shim
Figura 4: Uno shim intercetta tra l’app e l’API di Windows. Ciò che viene riscritto è l’IAT lato app; il sistema stesso non cambia.
Da questo disegno seguono tre proprietà importanti.3
- Uno shim gira come codice lato app. Non è parte del sistema, quindi è soggetto alle stesse restrizioni di sicurezza dell’app. Uno shim non può aggirare i meccanismi di sicurezza del sistema e non serve allentare le impostazioni di sicurezza per usarlo.
- Ciò che uno shim può correggere, una correzione di codice lato app può correggerlo anch’essa. Uno shim è un sostituto per i casi in cui «non c’è il sorgente / non possiamo correggere»; non è più potente di una correzione di codice.
- Solo user mode. I problemi di compatibilità dei driver di dispositivo che girano in kernel mode non possono essere corretti da uno shim.
3.2. Il database degli shim (.sdb) e il matching
La tabella di corrispondenza «quale shim applicare a quale EXE» è il database degli shim, un file binario con estensione .sdb. Gli eseguibili di destinazione vengono registrati nel database per attributi come nome file, dimensione, checksum e versione (attributi di matching) e vengono confrontati all’avvio del processo. I rimedi includono Appfix (uno shim), che inietta un hook API, e Apphelp, che mostra un messaggio «questa app ha un problema di compatibilità». Un insieme di più shim e flag è un livello di compatibilità (modalità di compatibilità).1
Facile da perdere: questo matching non gira solo sulle app che hanno la modalità di compatibilità impostata, ma a ogni avvio di processo. Windows fornisce un database standard di correzioni per migliaia di app note (i file stanno sotto %WINDIR%\AppPatch) e sul vostro PC oggi qualche app vecchia sta quasi certamente partendo con uno shim attaccato senza che nessuno se ne accorga. Le correzioni di compatibilità fornite da Microsoft vengono distribuite come parte di Windows e aggiornate tramite Windows Update.3
flowchart TB
accTitle: Matching del database degli shim all'avvio del processo
accDescr: Ogni avvio di processo viene confrontato con il database degli shim; se una registrazione corrisponde agli attributi di matching, Appfix inietta uno shim o Apphelp mostra un messaggio, altrimenti il processo parte così com'è
start["Avvio del processo"] --> db["Confrontare con .sdb"]
db -.-> attr["Nome file, dimensione, ecc."]
db --> hit{"Una registrazione?"}
hit -->|Sì| appfix["Appfix: iniettare shim"]
hit -->|Sì| apphelp["Apphelp: un messaggio"]
hit -->|No| plain["Partire così com'è"]
layer["Livello di compatibilità"] -.->|Insieme di shim e flag| appfix
Figura 5: Il matching gira a ogni avvio di processo, non solo sulle app che hanno la modalità di compatibilità impostata.
3.3. PCA — il meccanismo che applica gli shim automaticamente
Un altro percorso con cui uno shim può essere applicato senza che un amministratore lo intenda è PCA (Program Compatibility Assistant). PCA osserva l’esecuzione delle app e, quando rileva segni di un problema di compatibilità noto, propone all’utente di applicare una correzione o, in alcuni casi, applica automaticamente un’impostazione di compatibilità. Ad esempio, a un’app che va in crash chiamando codice dentro una DLL liberata viene assegnato PINDLL, e a un’app che fallisce la scrittura su un file Windows protetto viene assegnato WRPMITIGATION.5
flowchart TB
accTitle: Come PCA applica automaticamente un'impostazione di compatibilità
accDescr: PCA osserva l'esecuzione delle app e, quando rileva segni di un problema di compatibilità noto, propone all'utente di applicare una correzione o, in alcuni casi, applica automaticamente un'impostazione di compatibilità
run["Esecuzione dell'app"] --> pca["PCA osserva"]
pca --> sign{"Segni di un problema noto?"}
sign -->|Sì| resp{"Quale caso?"}
resp -->|Gestito da una proposta| suggest["Proporre di applicare una correzione"]
resp -->|Alcuni casi| auto["Applicare automaticamente un'impostazione di compatibilità"]
sign -->|No| none["Eseguire così com'è"]
auto -.-> ex["Esempio: PINDLL o WRPMITIGATION"]
Figura 6: PCA osserva l’esecuzione e, quando rileva segni di un problema noto, propone una correzione o ne applica una automaticamente.
L’identità di «non ho mai impostato niente, ma a un certo punto la casella della modalità di compatibilità era attiva» è, in molti casi, questo. Non è un guasto né un clic sbagliato; è Windows che si comporta come progettato.
4. Cosa possono gli shim rappresentativi
Tra gli shim pronti che Microsoft pubblica, ecco una selezione che torna davvero spesso quando si prolunga la vita di un’app aziendale.4
| Shim | Cosa può fare (sintesi) |
|---|---|
| WinXPSP3VersionLie e altri shim della famiglia VersionLie | Restituire una versione più vecchia specificata alle interrogazioni di versione del sistema (falsificazione di versione) |
| CorrectFilePaths | Rimappare l’accesso a un percorso file non scrivibile o inesistente verso un’altra posizione |
| VirtualRegistry | Reindirizzare o falsificare letture e scritture del registro (inclusa la falsificazione di versione e la simulazione di chiavi inesistenti) |
| ForceAdminAccess | Restituire temporaneamente True a un controllo «sei membro del gruppo Administrators?» |
| RunAsAdmin / RunAsHighest / RunAsInvoker | Dare dall’esterno un livello di esecuzione equivalente a requireAdministrator / highestAvailable / asInvoker nel manifesto |
| WRPMitigation | Falsificare il successo delle scritture su file e chiavi di registro protette del sistema così l’app può proseguire |
| EmulateGetDiskFreeSpace | Segnalare lo spazio disco libero come massimo 2 GB (per le app che vanno in overflow sui dischi grandi) |
| GlobalMemoryStatusLie | Falsificare i valori di stato della memoria segnalati (per le app che falliscono un controllo memoria all’avvio) |
| LoadLibraryRedirect | Caricare la DLL attuale di Windows invece di una vecchia DLL di sistema che l’app porta con sé |
Guardando l’elenco, la maggior parte degli shim è «una bugia che restituisce la risposta che l’app vecchia si aspetta». Il disco è al massimo 2 GB, il sistema è XP, siete amministratore — ricreano, solo dentro quel processo, la visione del mondo dell’epoca in cui l’app è nata.
La falsificazione di versione è diventata un «comportamento ufficiale predefinito»
La falsificazione di versione non è un hack speciale. Da Windows 8.1 in poi, il valore che GetVersionEx restituisce dipende dal manifesto dell’app. Un’app senza dichiarazione <supportedOS> nella sezione <compatibility> del manifesto riceve sempre l’equivalente di Windows 8 (6.2), qualunque sia il sistema reale. Quando c’è una dichiarazione, viene restituito il valore fino al sistema più alto tra quelli dichiarati (ad esempio, se avete dichiarato fino al GUID di Windows 8.1, ottenete 6.3 anche su Windows 11).67
Quindi la «versione di Windows che l’app vede» si decide in questi stadi impilati.
- Viene restituito il valore fino al sistema dichiarato nel manifesto (6.2 se non c’è dichiarazione)
- Se è applicata la modalità di compatibilità (uno shim della famiglia VersionLie), viene restituita la versione del sistema selezionato6
flowchart TB
accTitle: Come si decide la versione di sistema che l'app vede
accDescr: Il valore che GetVersionEx restituisce si decide in base alla presenza di una dichiarazione supportedOS nel manifesto; senza dichiarazione viene restituito l'equivalente Windows 8 6.2, con dichiarazione il valore fino al sistema dichiarato più alto, e se è applicato uno shim VersionLie viene sovrascritto con la versione del sistema selezionato
q["Interrogazione GetVersionEx"] --> m{"C'è una dichiarazione supportedOS?"}
m -->|No| v62["Viene restituito l'equivalente Windows 8 (6.2)"]
m -->|Sì| decl["Valore fino al sistema dichiarato più alto"]
v62 --> lie{"Shim della famiglia VersionLie applicato?"}
decl --> lie
lie -->|Sì| fake["Il valore di sistema scelto in modalità di compatibilità"]
lie -->|No| asis["Il valore viene restituito così com'è"]
Figura 7: La versione di Windows che l’app vede si decide in stadi impilati dal manifesto e dagli shim.
Se un’app interna «si ramifica sulla versione del sistema e, in modo confuso, viene giudicata come 8 anche se questo è Windows 11», sospettate prima la dichiarazione supportedOS nel manifesto. Detto al contrario, un’app vecchia che rifiuta di partire su un controllo di versione può, con alta probabilità, passare con uno shim VersionLie. In molti casi guarda solo il numero di versione e il comportamento reale va bene su un sistema più nuovo.
flowchart TB
accTitle: Due sintomi dovuti alla versione e come affrontarli
accDescr: Se un'app interna viene giudicata come 8 anche se questo è Windows 11, sospettate la dichiarazione supportedOS nel manifesto; un'app vecchia che rifiuta di partire su un controllo di versione può, con alta probabilità, passare con uno shim VersionLie
sym1["Giudicata come 8 anche se questo è Windows 11"] --> fix1["Sospettare la dichiarazione supportedOS"]
sym2["Avvio rifiutato su un controllo di versione"] --> fix2["Provare a passare con VersionLie"]
fix2 -.-> why["Il comportamento reale spesso va bene su un sistema più nuovo"]
Figura 8: Quando il giudizio è stantio, sospettate il manifesto; quando l’avvio è rifiutato, sospettate VersionLie.
5. Cosa fa la casella della modalità di compatibilità
Le impostazioni di Proprietà → scheda Compatibilità vengono memorizzate nella chiave di registro AppCompatFlags\Layers. Le impostazioni di compatibilità delle app DXGI e simili usano la stessa chiave come luogo in cui specificare un livello di compatibilità.2 Guardiamo davvero.
reg query "HKCU\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers"
Per un EXE su cui avete impostato «Windows XP (Service Pack 3)», «Esegui questo programma come amministratore» e «Sostituisci il comportamento di ridimensionamento DPI elevato» nella scheda Compatibilità, vedrete un valore come il seguente.
HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers
C:\LegacyApp\Gyomu.exe REG_SZ ~ WINXPSP3 RUNASADMIN HIGHDPIAWARE
Corrispondenze rappresentative tra voci della casella e valori (confermate su Windows 11; nomi delle voci e valori possono cambiare per versione del sistema).
| Voce della scheda Compatibilità | Valore scritto (esempio) | Cosa è davvero |
|---|---|---|
| Modalità di compatibilità: Windows XP (Service Pack 3) | WINXPSP3 | Un livello di compatibilità che raggruppa la falsificazione di versione e diversi altri shim |
| Modalità colori ridotta (8 bit / 256 colori) | 256COLOR | Allentamento per la vecchia modalità colori |
| Esegui a risoluzione schermo 640 × 480 | 640X480 | Eseguire a bassa risoluzione |
| Disattiva ottimizzazioni a schermo intero | DISABLEDXMAXIMIZEDWINDOWEDMODE | Disattivare le ottimizzazioni di disegno a schermo intero |
| Sostituisci il comportamento di ridimensionamento DPI elevato (Applicazione) | HIGHDPIAWARE | Fermare la virtualizzazione DPI (stiramento del bitmap)11 |
| Esegui questo programma come amministratore | RUNASADMIN | Richiedere l’elevazione all’avvio |
Tre punti da tenere.
- «Esegui questo programma come amministratore» viene scritto nello stesso posto. Modalità di compatibilità e flag di elevazione convivono nella stessa chiave Layers, ed è lì che nasce la confusione «ho impostato la modalità di compatibilità e l’elevazione è arrivata / è scomparsa». Guardare il valore direttamente separa i due.
- Ciò che è scritto in HKCU è «l’impostazione di quell’utente». Se la impostate da «Modifica impostazioni per tutti gli utenti» della scheda, viene scritta nella chiave omonima lato HKLM e si applica a tutti gli utenti. Quando la distribuite in imaging, siate consapevoli di da che lato state scrivendo.
- La casella è solo l’ingresso ai livelli pronti. La scheda vi lascia scegliere solo livelli rappresentativi; non potete scegliere shim singoli e combinarli. È quello che fa Compatibility Administrator nel capitolo successivo.
flowchart TB
accTitle: Il percorso da un'impostazione della scheda Compatibilità fino all'effetto
accDescr: Le impostazioni della scheda Compatibilità vengono memorizzate come percorso EXE e valore nella chiave AppCompatFlags Layers; al successivo avvio di quell'EXE il loader legge il valore e applica il livello di compatibilità corrispondente al processo
tab["Impostare nella scheda Compatibilità"] --> reg["Memorizzare percorso EXE e valore nella chiave Layers"]
reg --> boot["Successivo avvio dell'EXE"]
boot --> loader["Il loader legge il valore"]
loader --> apply["Applicare il livello di compatibilità al processo"]
reg -.-> hkcu["HKCU è solo quell'utente"]
reg -.-> hklm["HKLM si applica a tutti gli utenti"]
Figura 9: La casella è in realtà una scrittura nella chiave Layers e l’applicazione avviene al successivo avvio.
6. Compatibility Administrator in pratica — costruire e distribuire un .sdb personalizzato
6.1. Come ottenerlo e le avvertenze
Compatibility Administrator è uno strumento incluso nel Windows ADK (Windows Assessment and Deployment Kit).12 Dopo l’installazione sono presenti sia l’edizione a 32 bit sia quella a 64 bit, e dovete usare l’edizione a 32 bit per le app a 32 bit e quella a 64 bit per le app a 64 bit.13
C’è un’altra avvertenza importante. Se avviate Compatibility Administrator con elevazione (come amministratore) e testate, la virtualizzazione UAC e il reindirizzamento non si comportano come per un utente reale e potete giudicare male che «è sistemato». Confermate sempre l’effetto di una correzione con lo stesso account e gli stessi privilegi dell’utente reale.4
flowchart TB
accTitle: Due avvertenze nell'uso di Compatibility Administrator
accDescr: Usate l'edizione a 32 bit per le app a 32 bit e quella a 64 bit per le app a 64 bit, e confermate l'effetto di una correzione con lo stesso account e gli stessi privilegi dell'utente reale, non in uno stato elevato
app32["App a 32 bit"] --> tool32["Usare l'edizione a 32 bit"]
app64["App a 64 bit"] --> tool64["Usare l'edizione a 64 bit"]
elev["Testare in stato elevato"] -.-> wrong["Può giudicare male una correzione"]
user["Testare con i privilegi dell'utente reale"] --> ok["Confermare l'effetto"]
Figura 10: Scegliere l’edizione a 32 o 64 bit e confermare con gli stessi privilegi dell’utente reale sono le avvertenze all’ingresso.
6.2. Procedura per costruire un database di compatibilità personalizzato
Lo schema è il seguente.14
- Nel riquadro sinistro di Compatibility Administrator create un nuovo database sotto «Custom Databases» e scegliete «Create New» → «Application Fix»
- Inserite il nome dell’app e il nome del fornitore e specificate il file EXE di destinazione
- Scegliete la modalità di compatibilità (livello) da applicare — provare prima un insieme come «compatibilità Windows XP» è la via breve
- Se serve, aggiungete correzioni di compatibilità singole (shim) — potete restringere a un insieme minimo come solo VersionLie o solo CorrectFilePaths
- Confermate le condizioni di matching (dimensione file, checksum, versione e così via) e salvate
Le condizioni di matching sono la chiave di «applica questo solo a questo EXE». Le condizioni di base predefinite di solito bastano, ma raccomandiamo di lasciare una condizione che possa identificare la versione dell’app. Questo evita l’incidente di una bugia vecchia che continua ad applicarsi a una versione nuova quando il fornitore pubblicherà in seguito un’edizione corretta.1415
flowchart TB
accTitle: Procedura per costruire un database di compatibilità personalizzato
accDescr: Create un Application Fix in un nuovo database, specificate il nome dell'app e l'EXE di destinazione, provate prima un insieme di modalità di compatibilità e poi restringete agli shim singoli se serve, confermate le condizioni di matching e salvate
new["Creare un nuovo database"] --> fix["Scegliere Application Fix"]
fix --> info["Specificare il nome dell'app e l'EXE di destinazione"]
info --> layer["Provare un insieme di modalità di compatibilità"]
layer --> single["Se serve, restringere agli shim singoli"]
single --> match["Confermare le condizioni di matching e salvare"]
match -.-> ver["Lasciare una condizione che identifica la versione"]
Figura 11: Per un Application Fix, provate prima un insieme di modalità di compatibilità, restringete a un insieme minimo e limitate la destinazione con le condizioni di matching.
Testate prima il .sdb creato su una macchina di convalida. Quando funziona come previsto, lo portate in organizzazione.
6.3. Distribuire con sdbinst
Il comando che applica un .sdb personalizzato a ogni PC è sdbinst.exe (richiede privilegi di amministratore).15
:: Install (-q is silent with no confirmation)
sdbinst -q "C:\Deploy\MyCorpFixes.sdb"
:: Uninstall (by file)
sdbinst -q -u "C:\Deploy\MyCorpFixes.sdb"
:: Uninstall (by database GUID)
sdbinst -q -u -g {database GUID}
Come strategia di distribuzione organizzativa, Microsoft raccomanda di consolidare in un unico database personalizzato a livello aziendale (o per reparto) e gestirlo in modo centralizzato, invece di spedire un .sdb distinto con l’installer di ogni app. Più correzioni avete, più è facile aggiornare e ridistribuire un database che distribuirne molti di una riga. Un database personalizzato ha un proprio GUID e installare una nuova versione con lo stesso GUID sostituisce automaticamente la versione vecchia, quindi anche le operazioni di aggiornamento restano semplici. Mettete la distribuzione stessa su un percorso esistente che possa girare con privilegi di amministratore, ad esempio un pacchetto MSI o uno script di avvio.15
flowchart TB
accTitle: Il percorso dalla creazione di un .sdb personalizzato alla distribuzione
accDescr: Create un database di compatibilità personalizzato in Compatibility Administrator, testatelo su una macchina di convalida, applicatelo a ogni PC con sdbinst e, all'aggiornamento, installate una nuova versione con lo stesso GUID così la versione vecchia viene sostituita automaticamente
make["Creare in Compatibility Administrator"] --> test["Testare su una macchina di convalida"]
test --> deploy["Applicare a ogni PC con sdbinst"]
deploy --> update["Installare una nuova versione con lo stesso GUID"]
update -.-> replace["La versione vecchia viene sostituita automaticamente"]
deploy -.-> inv["Registrato in Programmi e funzionalità"]
Figura 12: Un .sdb personalizzato viene portato in esercizio attraverso creazione, convalida e distribuzione sdbinst, e gli aggiornamenti si gestiscono per GUID.
Un database personalizzato installato viene registrato come voce in «Programmi e funzionalità (App installate)», quindi potete confermare inventario e rimozione anche da lì. Quali PC hanno quale .sdb è un’informazione che appartiene al registro di gestione degli asset.
7. Casi in cui non funziona e i limiti
Gli shim non sono una pallottola d’argento. Per progettazione non funzionano nei casi seguenti.
- Problemi in kernel mode. Uno shim gira dentro un processo in user mode, quindi un’incompatibilità di driver di dispositivo non può essere corretta. Se il driver di uno strumento di misura vecchio, di un dongle USB o di una stampante non supporta Windows 11, niente che applichiate lato app lo risolverà. Il codice che gira nel kernel, come parti di un antivirus, è lo stesso.3
- App a 16 bit. Windows a 64 bit non supporta l’esecuzione di app a 16 bit. Gli handle hanno 32 bit validi su Windows a 64 bit e non possono essere troncati per passarli a un’app a 16 bit, quindi l’avvio fallisce con
ERROR_BAD_EXE_FORMAT.8 Anche quando l’app stessa è a 32 bit, esistono pacchetti di quell’epoca il cui stub dell’installer è a 16 bit, e si presentano come «l’app girerebbe, ma non possiamo installarla». - Accesso hardware diretto. Le app industriali che presuppongono di toccare direttamente porte I/O o memoria fisica non sono autorizzate a farlo dallo user mode su Windows moderno, e questo è oltre l’ambito che uno shim può falsificare.
- Aggirare i meccanismi di sicurezza. Poiché uno shim gira sotto le stesse restrizioni di sicurezza dell’app, non può rendere possibile «qualcosa che non potete fare per mancanza di privilegi». ForceAdminAccess e WRPMitigation falsificano solo il successo di un controllo o di una scrittura così l’app può proseguire; non stanno davvero riscrivendo una risorsa protetta.34
- App che controllano la propria integrità. Le app con vecchia protezione dalla copia o rilevamento di manomissione possono trattare l’hook API stesso come anomalo e smettere di funzionare.
flowchart TB
accTitle: Casi in cui uno shim non funziona
accDescr: Uno shim gira dentro un processo in user mode, quindi non funziona su problemi di driver in kernel mode, app a 16 bit, accesso hardware diretto o aggiramento dei meccanismi di sicurezza
shim["Shim (gira in user mode)"] -->|Non funziona| drv["Driver kernel"]
shim -->|Non funziona| b16["App a 16 bit"]
shim -->|Non funziona| hw["Accesso hardware diretto"]
shim -->|Non funziona| sec["Aggiramento dei meccanismi di sicurezza"]
b16 -.-> fmt["A 64 bit, fallisce già l'avvio"]
sec -.-> fake["Falsifica solo il successo così l'app può proseguire"]
Figura 13: Uno shim è solo user mode e non arriva al kernel, alle app a 16 bit, all’accesso hardware diretto o all’aggiramento della sicurezza.
E il limite essenziale comune a ogni shim è che è un ripiego. Uno shim è una bugia tagliata su un uso particolare di una API particolare, e se l’implementazione lato sistema cambia, la premessa crolla. Gli shim forniti da Microsoft vengono mantenuti come parte di Windows tramite Windows Update,3 ma occuparsi delle bugie che avete applicato con un database personalizzato è il lavoro della vostra organizzazione. Mettete a budget, come costo della prolungazione, un’operazione che convalida l’«elenco delle app tenute in vita dagli shim» a ogni aggiornamento delle funzionalità.
flowchart TB
accTitle: Gli shim come ripiego e chi è responsabile della manutenzione
accDescr: Uno shim è una bugia tagliata su un uso di API particolare e la premessa crolla se cambia l'implementazione lato sistema; gli shim Microsoft vengono mantenuti tramite Windows Update, ma occuparsi delle bugie applicate con un database personalizzato è il lavoro dell'organizzazione, e la convalida a ogni aggiornamento delle funzionalità è un costo di prolungazione
shim["Shim = una bugia-ripiego"] --> break["Un cambiamento del sistema la rompe"]
ms["Shim Microsoft"] --> wu["Tramite Windows Update"]
own["Bugie del database personalizzato"] --> self["L'organizzazione se ne occupa"]
self --> cost["Convalidare a ogni aggiornamento è il costo di prolungazione"]
Figura 14: La responsabilità di mantenere la bugia dello shim si divide tra l’insieme fornito da Microsoft e l’insieme personalizzato della vostra organizzazione.
8. Il valore pratico di RunAsInvoker — far tacere solo la richiesta di elevazione
Tra gli shim, quello che torna di più nel lavoro IT quotidiano è RunAsInvoker.
Alcune vecchie app aziendali dichiarano requireAdministrator nel manifesto, o vengono rilevate per errore come installer dal nome o dal contenuto dell’EXE, e chiedono l’elevazione UAC a ogni avvio. Molte però chiedono l’amministratore solo per inerzia dell’era XP e non usano davvero i privilegi di amministratore. Applicare lo shim RunAsInvoker sovrascrive sia il rilevamento dell’installer sia il manifesto, e l’app parte con il token ereditato dal processo padre (= privilegi di utente standard).9
flowchart TB
accTitle: Come RunAsInvoker sopprime una richiesta di elevazione
accDescr: Una dichiarazione requireAdministrator nel manifesto o un rilevamento errato come installer causa una richiesta di elevazione UAC all'avvio, ma applicare RunAsInvoker sovrascrive entrambi e l'app parte con il token ereditato dal padre
manifest["Dichiarazione requireAdministrator"] --> shim{"RunAsInvoker applicato?"}
detect["Rilevata per errore come installer"] --> shim
shim -->|No| uac["Richiesta di elevazione UAC a ogni avvio"]
shim -->|Sì| token["Parte con il token del padre"]
token -.-> limit["Il lavoro che ha davvero bisogno dell'amministratore fallisce nell'app"]
Figura 15: RunAsInvoker sovrascrive solo la causa della richiesta di elevazione; i privilegi non aumentano.
Anche senza costruire un .sdb in Compatibility Administrator, potete applicare temporaneamente lo stesso livello con la variabile d’ambiente __COMPAT_LAYER.
:: Apply RunAsInvoker to child processes started from this command prompt
set __COMPAT_LAYER=RunAsInvoker
start "" "C:\LegacyApp\Gyomu.exe"
# In PowerShell
$env:__COMPAT_LAYER = 'RunAsInvoker'
Start-Process 'C:\LegacyApp\Gyomu.exe'
Se trasformate quelle due righe in un file batch e le distribuite come collegamento, potete evitare di consegnare privilegi di amministratore locale agli utenti standard e l’IT non viene più chiamata ogni volta per una password UAC. È una tecnica di compatibilità che indurisce la difesa, in linea con il privilegio minimo.
flowchart TB
accTitle: L'effetto di distribuire un batch RunAsInvoker
accDescr: Distribuire come collegamento un batch di due righe che imposta RunAsInvoker significa che potete evitare di consegnare privilegi di amministratore locale agli utenti standard, l'IT non viene chiamata per una password UAC e l'esercizio segue il privilegio minimo
bat["Distribuire un batch di due righe"] --> noadmin["Potete evitare di consegnare privilegi di amministratore"]
bat --> nocall["L'IT non viene chiamata per UAC"]
noadmin --> lp["Un esercizio che segue il privilegio minimo"]
nocall --> lp
Figura 16: Distribuire un batch da solo può ridurre sia la consegna di privilegi di amministratore sia le chiamate per UAC.
Anche le avvertenze, con chiarezza.
- I privilegi non aumentano. Il lavoro che ha davvero bisogno dei privilegi di amministratore (scritture su HKLM, aggiornamenti sotto Program Files e così via) andrà in errore dentro l’app o, se le condizioni sono soddisfatte, verrà reindirizzato al VirtualStore dalla virtualizzazione UAC.10 Se il salvataggio delle impostazioni «ha smesso di funzionare» all’improvviso, sospettate la virtualizzazione.
- Il metodo della variabile d’ambiente si applica solo ai processi figlio. Per un’applicazione permanente, un’impostazione diretta nella chiave Layers (RUNASINVOKER non ha una voce nella scheda) o la distribuzione tramite un .sdb è affidabile.
- Correggere la destinazione di scrittura è la via vera. Se potete cambiare l’app, spostate il file delle impostazioni sotto
%APPDATA%e dichiarateasInvokernel manifesto — quella è la forma corretta.9
flowchart TB
accTitle: Applicazione temporanea e permanente di RunAsInvoker
accDescr: L'applicazione tramite la variabile d'ambiente COMPAT_LAYER si applica solo ai processi figlio avviati da lì; per un'applicazione permanente usate un'impostazione diretta nella chiave Layers o la distribuzione tramite un .sdb
env["Impostare tramite una variabile d'ambiente"] --> child["Si applica solo ai processi figlio"]
child -.-> tmp["Applicazione temporanea"]
layers["Impostare direttamente nella chiave Layers"] --> always["Applicazione permanente"]
sdb["Distribuire tramite un sdb"] --> always
Figura 17: Il metodo della variabile d’ambiente è un’applicazione temporanea limitata ai processi figlio; renderla permanente si fa con la chiave Layers o un .sdb.
9. Decidere tra prolungazione e migrazione — cosa pensare dopo che gira sotto uno shim
Il momento in cui gira sotto uno shim è un sollievo, ma è importante non smettere di pensare lì. Girare sotto uno shim significa solo che è capitato di calzare un alloggiamento che Windows aveva preparato. Gli assi della decisione, in tabella.
| Asse di decisione | Condizioni che pendono verso la prolungazione (shim) | Condizioni che pendono verso migrazione / riscrittura |
|---|---|---|
| Periodo d’uso restante | Previsto di ritirare con l’attività in 1–2 anni | Si presuppone di continuare a usare per 5 anni o più |
| Codice sorgente | Nessuno (fornitore sparito, o perso) | Esiste, o l’asset può essere recuperato |
| Profondità della dipendenza | Solo un problema di compatibilità API in user mode | Dipende da un driver, dal 16 bit o da hardware dedicato |
| Alternative | Non esiste un prodotto confezionato o una nuova versione | Il prodotto e la tecnologia di destinazione sono chiari |
| Impatto in caso di fallimento | L’attività può girare su una procedura di ripiego | L’attività core viene colpita in pieno |
| Capacità di convalida | Potete confermare il comportamento a ogni aggiornamento delle funzionalità | Nessuna risorsa di convalida e tende a essere congelata |
Se decidete la prolungazione, mettete i tre punti seguenti nell’esercizio come insieme.
- Annotare. Quale EXE, quale shim/livello e perché. Lasciate il valore della chiave Layers e il GUID del .sdb in un registro. «Nessuno sa perché funziona» è il debito più grande che lasciate alla persona successiva. È la stessa mentalità di conservazione di «When You Inherit a System With No Source Code and No Documentation».
- Convalidare. Includete avvio e operazioni principali delle app tenute in vita dagli shim tra le voci di convalida di un aggiornamento delle funzionalità Windows. Legatelo anche al piano di sostituzione del sistema (Practical Options After Windows 10 End of Support).
- Fissare una scadenza. Decidete la fine della prolungazione — «fino al prossimo rinnovo del sistema core», «fino a marzo 2028» — e portate avanti in parallelo la valutazione della migrazione.
flowchart TB
accTitle: L'insieme operativo in tre punti una volta decisa la prolungazione
accDescr: Annotate in un registro quale shim la fa girare, convalidate il comportamento delle app tenute in vita dagli shim a ogni aggiornamento delle funzionalità, fissate una scadenza per la fine della prolungazione e portate avanti in parallelo la valutazione della migrazione
decide["Decidere la prolungazione"] --> rec["Annotare: quale shim la fa girare, in un registro"]
rec --> verify["Convalidare: confermare il comportamento a ogni aggiornamento delle funzionalità"]
verify --> deadline["Scadenza: decidere la fine della prolungazione"]
deadline --> mig["Portare avanti in parallelo la valutazione della migrazione"]
Figura 18: La prolungazione si esercita come insieme di tre punti — annotare, convalidare e scadenza — inclusa la valutazione della migrazione in parallelo.
Sul lato migrazione, le opzioni standard cambiano con la tecnologia dell’app. Per VB6, la scelta a tre vie di riscrittura completa, conversione automatica e migrazione a tappe organizzata in «Fino a quando funzioneranno le applicazioni VB6? — Lo stato del supporto al runtime e un percorso pratico verso la migrazione a .NET»; per una dipendenza ActiveX/OCX, la tabella di decisione mantieni / avvolgi / sostituisci in «Come gestire ActiveX / OCX oggi - Una tabella decisionale Mantieni / Avvolgi / Sostituisci». Il modo sano di posizionare uno shim è come un acquisto di tempo perché il periodo di valutazione e preparazione di quel progetto di migrazione possa girare in sicurezza.
flowchart TB
accTitle: Opzioni sul lato migrazione e dove sta uno shim
accDescr: Le opzioni di migrazione standard cambiano con la tecnologia dell'app; per VB6 la scelta a tre vie è riscrittura, conversione automatica e migrazione a tappe, per una dipendenza ActiveX vale la tabella mantieni / avvolgi / sostituisci, e uno shim è posizionato come acquisto di tempo per la valutazione e la preparazione del progetto di migrazione
tech{"Qual è la tecnologia dell'app?"} -->|VB6| vb["Riscrittura, conversione automatica o migrazione a tappe"]
tech -->|Dipendenza ActiveX| ax["Mantenere, avvolgere o sostituire"]
shim["Prolungazione tramite uno shim"] -.->|Compra tempo per valutazione e preparazione| tech
Figura 19: Le opzioni di migrazione standard le decide la tecnologia dell’app e uno shim è posizionato come acquisto di tempo per quella valutazione.
10. Sintesi
- La vera identità della modalità di compatibilità sono gli shim. Le impostazioni della scheda Compatibilità vengono scritte nella chiave AppCompatFlags\Layers e iniettate nel processo all’avvio come hook API tramite riscrittura dell’IAT.
- Gli shim sono una raccolta di «bugie che restituiscono la risposta che l’app vecchia si aspetta». Vengono forniti shim pronti per la falsificazione di versione, la rimappatura dei percorsi, la falsificazione del registro, la falsificazione dei controlli di amministratore e simili.
- Windows stesso usa per impostazione predefinita un gran numero di shim e PCA può applicarli automaticamente. Affidarsi alla modalità di compatibilità è di per sé una scelta ragionevole che cavalca un meccanismo ufficiale del sistema.
- C’è un limite di principio solo-user-mode e nessun aggiramento della sicurezza, e i driver kernel, le app a 16 bit e l’accesso hardware diretto non possono essere salvati.
- Il rollout organizzativo è costruire un .sdb personalizzato in Compatibility Administrator (Windows ADK) e distribuirlo con sdbinst. Scegliere l’edizione a 32/64 bit, testare con l’account utente reale e gestire gli aggiornamenti per GUID sono i punti pratici.
- Le app che «richiedono l’amministratore ma non ne hanno davvero bisogno» possono essere riportate ai privilegi standard con
__COMPAT_LAYER=RunAsInvoker. È una tecnica difensiva che fa tacere la richiesta di elevazione invece di consegnare privilegi. - Girare sotto uno shim è prolungazione, non una soluzione. Annotare cosa la fa girare, convalidare a ogni aggiornamento delle funzionalità e fissare una scadenza perché la migrazione proceda in parallelo — quell’insieme di tre punti è incluso nella decisione di «affidarsi alla modalità di compatibilità».
La prossima volta che un’app vecchia ricomincia a funzionare dopo una casella della modalità di compatibilità, rifate la domanda. «Grazie a quale bugia sta girando questa app? Per quanto quella bugia resterà valida?» Se potete rispondere, la prolungazione è una strategia rispettabile.
Articoli correlati
- Registry 32-bit/64-bit Redirection and Virtualization Pitfalls — Wow6432Node and the “The Value I Wrote Isn’t There” Problem
- Fino a quando funzioneranno le applicazioni VB6? — Lo stato del supporto al runtime e un percorso pratico verso la migrazione a .NET
- Come gestire ActiveX / OCX oggi - Una tabella decisionale Mantieni / Avvolgi / Sostituisci
- Practical Options After Windows 10 End of Support — A Decision Table for ESU, LTSC, and Replacement
- When You Inherit a System With No Source Code and No Documentation — A Practical Playbook for Keeping It Running
- Integrazione con la shell Windows oggi — menu contestuali, associazioni di file e cosa è cambiato in Windows 11
Aree di consulenza correlate
KomuraSoft LLC si occupa di indagare come si comportano le vecchie app aziendali senza codice sorgente e di progettare la loro prolungazione (selezione di shim e modalità di compatibilità, costruzione e rollout di un .sdb personalizzato), della convalida di compatibilità delle app esistenti per una migrazione a Windows 11 e della pianificazione di una riscrittura o migrazione che proceda in parallelo alla prolungazione. Una consulenza già dallo stadio «ha ricominciato a funzionare in modalità di compatibilità, ma va bene lasciarla così?» va bene.
- Riutilizzo e migrazione delle risorse esistenti
- Sviluppo di applicazioni Windows
- Consulenza tecnica e revisione del progetto
- Contattaci
Riferimenti
-
Microsoft Learn, Application Compatibility Database. Che l’infrastruttura di compatibilità gestisce problemi e rimedi in un database in formato .sdb, il matching per attributi dell’eseguibile, Apphelp (mostrare un messaggio) e Appfix (un hook API tramite uno shim) e un livello di compatibilità (modalità) che raggruppa più shim e flag. ↩ ↩2 ↩3
-
Microsoft Learn, DXGI overview. Che le impostazioni di compatibilità delle applicazioni vengono memorizzate nella chiave di registro HKCU\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers (usando le impostazioni di compatibilità DXGI come esempio). ↩ ↩2
-
Microsoft Learn, Understanding and Using Compatibility Fixes. Che una correzione di compatibilità (shim) reindirizza le chiamate API riscrivendo l’IAT (import address table), che il linking dinamico viene gestito agganciando GetProcAddress, che uno shim è soggetto alle stesse restrizioni di sicurezza dell’app e non può aggirare i meccanismi di sicurezza del sistema, che è solo user mode e non può correggere problemi di driver, che una correzione possibile con uno shim è possibile anche con una correzione di codice, scenari d’uso come le app il cui supporto del fornitore è terminato e che le correzioni di compatibilità fornite da Microsoft vengono distribuite come parte di Windows e aggiornate tramite Windows Update. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8
-
Microsoft Learn, Compatibility Fixes for Windows 10, Windows 8, Windows 7, and Windows Vista. Un elenco e una descrizione delle correzioni di compatibilità note tra cui CorrectFilePaths, VirtualRegistry, ForceAdminAccess, RunAsAdmin/RunAsHighest/RunAsInvoker, WRPMitigation, EmulateGetDiskFreeSpace, GlobalMemoryStatusLie, LoadLibraryRedirect e la famiglia VersionLie; la scelta dell’edizione a 32/64 bit di Compatibility Administrator; e che testare in uno stato elevato fa sì che virtualizzazione e reindirizzamento non si comportino come previsto, quindi dovreste convalidare con l’account utente reale. ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, Program Compatibility Assistant scenarios for Windows 8. Che PCA osserva l’esecuzione delle app, rileva segni di un problema di compatibilità noto e propone di applicare una correzione consigliata o la applica automaticamente (PINDLL, DISABLEUSERCALLBACKEXCEPTION, VIRTUALIZEDELETE, WRPMITIGATION e simili), e l’applicazione di una correzione dalla scheda Compatibilità e dal Program Compatibility Troubleshooter. ↩ ↩2
-
Microsoft Learn, GetVersionExW function. Che da Windows 8.1 in poi il valore che GetVersionEx restituisce dipende dal manifesto, che a un’app non manifestata per Windows 8.1/10 viene dato il valore di versione di Windows 8 (6.2) e che quando la modalità di compatibilità è attiva viene segnalata la versione del sistema selezionato. ↩ ↩2 ↩3
-
Microsoft Learn, Targeting your application for Windows. Come dichiarare i GUID dei sistemi supportati con un elemento supportedOS nella sezione compatibility del manifesto dell’app, il comportamento in assenza di dichiarazione e che un’app x86 a 32 bit interattiva che non include trustInfo è soggetta alla virtualizzazione dei file UAC (reindirizzamento delle scritture al VirtualStore). ↩ ↩2
-
Microsoft Learn, Running 32-bit Applications. Che WOW64 è un livello di emulazione che esegue app a 32 bit su Windows a 64 bit e isola le collisioni di file e registro, e che Windows a 64 bit non supporta l’esecuzione di app a 16 bit, con avvio che fallisce con ERROR_BAD_EXE_FORMAT a causa del numero di bit validi in un handle. ↩ ↩2
-
Microsoft Learn, Using the RunAsInvoker Fix. Che la correzione di compatibilità RunAsInvoker avvia l’app con il token ereditato dal processo padre, che sovrascrive sia il rilevamento dell’installer sia l’elaborazione del manifesto, che viene applicata come flag del loader senza intercettare le API e che quando potete correggere il codice la correzione propria è dichiarare asInvoker nel manifesto. ↩ ↩2 ↩3
-
Microsoft Learn, Registry Virtualization. Che la virtualizzazione del registro è una tecnologia di compatibilità che reindirizza in modo trasparente le scritture globali verso HKLM\Software in un VirtualStore per utente, che solo i processi interattivi a 32 bit sono nell’ambito e che è disattivata per i processi che specificano requestedExecutionLevel nel manifesto e per i processi a 64 bit, e che è posizionata come tecnologia temporanea destinata alla rimozione da un Windows futuro. ↩ ↩2
-
Microsoft Learn, High DPI Desktop Application Development on Windows. Che un’app non DPI-aware viene trattata come se disegnasse a un 96 DPI fisso e, su un display ad alta densità, Windows stira il bitmap quindi sembra sfocata, e le differenze tra le modalità di consapevolezza DPI (Unaware/System/Per-Monitor). ↩ ↩2
-
Microsoft Learn, Download and install the Windows ADK. Che il Windows ADK include Compatibility Administrator e Standard User Analyzer e come pensare alla scelta di una versione ADK e come scaricare e installare. ↩
-
Microsoft Learn, Compatibility Administrator User’s Guide. Che Compatibility Administrator fornisce l’applicazione di correzioni di compatibilità, modalità di compatibilità e messaggi AppHelp e la creazione di un database personalizzato, e che vengono installate sia l’edizione a 32 bit sia quella a 64 bit e dovete usare l’edizione a 32 bit per le app a 32 bit e quella a 64 bit per le app a 64 bit. ↩
-
Microsoft Learn, Creating a Custom Compatibility Fix in Compatibility Administrator. Che una correzione di compatibilità (un tempo chiamata shim) è un piccolo pezzo di codice che intercetta una chiamata API; la procedura per creare un Application Fix in un database personalizzato (specificare nome dell’app, fornitore ed EXE di destinazione, scegliere una modalità di compatibilità, scegliere shim aggiuntivi, impostare le condizioni di matching); e che dovreste lasciare condizioni che identificano correttamente l’app restringendo le informazioni di matching. ↩ ↩2
-
Microsoft Learn, Compatibility Fix Database Management Strategies and Deployment. Che un database gestito in modo centralizzato è raccomandato come strategia di gestione di un database di compatibilità personalizzato, che una correzione di compatibilità dovrebbe includere un controllo di versione (condizione di matching) così non viene applicata a una versione nuova, l’installazione locale con Sdbinst.exe (opzioni -q, -u, -g), che installare una nuova versione con lo stesso GUID di database disinstalla automaticamente la versione vecchia e i metodi di distribuzione tramite MSI o uno script. ↩ ↩2 ↩3
Articoli correlati
Articoli recenti con gli stessi tag per approfondire argomenti vicini.
Outsourcing e sviluppo su commissione di app Windows: cosa chiarire prima di affidare l'incarico
Prima di affidare in outsourcing o su commissione lo sviluppo di un'app Windows, ecco i punti da chiarire: revisione del software esisten...
L'API thread pool Win32 — Concorrenza senza creare thread, tramite CreateThreadpoolWork
State spargendo chiamate CreateThread per tutto il codice nativo? Questo articolo spiega l'API thread pool Win32 ridisegnata in Vista — i...
Named pipe in pratica — L'IPC standard di Windows, dalla progettazione alla sicurezza
Guida pratica alle named pipe, il meccanismo standard di comunicazione tra processi su Windows. L'articolo organizza, a partire dalle fon...
App che si rompono alla ripresa dalla sospensione — Come funzionano gli eventi di alimentazione di Windows e come costruire app aziendali che li sopravvivono
Aprite il portatile e le connessioni dell'app aziendale sono morte — la causa è un progetto che non ha mai tenuto conto della sospensione...
DllMain e il loader lock — Il vero motivo per cui vi dicono di «non fare niente nell'inizializzazione della DLL»
Perché non dovete chiamare LoadLibrary o sincronizzarvi con altri thread da DllMain. A partire dalle fonti primarie, l'articolo spiega co...
Argomenti correlati
Queste pagine collocano l’argomento in un contesto più ampio di servizi e decisioni.
Argomenti tecnici Windows
Portale su sviluppo Windows, analisi dei problemi e valorizzazione delle risorse esistenti.
Servizi collegati all’argomento
L’articolo è direttamente collegato ai servizi seguenti.
Sviluppo di applicazioni Windows
Applicazioni aziendali, integrazione di dispositivi e strumenti di comunicazione, dai requisiti allo sviluppo.
Domande frequenti
Domande che ricorrono nelle consulenze sull’argomento dell’articolo.
- Se un'app ha ricominciato a funzionare dopo aver attivato la modalità di compatibilità, va bene continuare a usarla così?
- Per tenere in piedi l'attività nel breve termine, sì. La modalità di compatibilità è un hook API in user mode chiamato shim, un meccanismo ufficiale fornito dal sistema. Uno shim resta però un ripiego per far girare un'app senza correggerla, e un altro aggiornamento del sistema può cambiare le premesse e romperla di nuovo. Annotate in un registro il fatto che gira in modalità di compatibilità e trattate quella nota come parte della decisione di riscrivere l'app o di prolungarne la vita di proposito.
- Cosa fa davvero la casella della modalità di compatibilità?
- Quando salvate le impostazioni nella scheda Compatibilità della finestra Proprietà, Windows scrive il percorso dell'EXE di destinazione e un valore come "WINXPSP3" o "HIGHDPIAWARE" sotto la chiave HKCU\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers. Al successivo avvio di quell'EXE, il loader di Windows legge il valore e applica al processo il livello di compatibilità corrispondente (un insieme di shim). La modalità Windows XP, ad esempio, falsifica la versione del sistema restituendo un valore vecchio dalle API di interrogazione della versione. Il sistema stesso non viene cambiato; solo a quel processo viene mostrato un Windows più vecchio finto.
- Si possono eseguire app dell'era a 16 bit in modalità di compatibilità su Windows a 64 bit?
- No. Windows a 64 bit esegue le app a 32 bit tramite WOW64, ma non supporta l'esecuzione di app a 16 bit; un tentativo di avvio fallisce con ERROR_BAD_EXE_FORMAT. È un limite architetturale che uno shim non può aggirare. I pacchetti più vecchi il cui stub dell'installer è a 16 bit falliscono per lo stesso motivo. Se servono davvero, bisogna guardare fuori dalla modalità di compatibilità — ad esempio una macchina virtuale che include Windows a 32 bit.
- Posso eseguire con un account utente standard un'app che "non parte se non viene eseguita come amministratore"?
- RunAsInvoker merita di essere provato. Se eseguite set __COMPAT_LAYER=RunAsInvoker al prompt dei comandi e poi avviate l'app, le richieste di elevazione da un manifesto requireAdministrator o dal rilevamento dell'installer vengono soppresse, e l'app parte con gli stessi privilegi (utente standard) del chiamante. Per un'app che chiede solo i diritti di amministratore e non li usa davvero, questo da solo può togliere l'elevazione dall'esercizio quotidiano. I privilegi non aumentano, quindi il lavoro che ha davvero bisogno dei diritti di amministratore fallirà dentro l'app. Adottatelo solo dopo aver verificato il comportamento.
- Dove si ottiene Compatibility Administrator?
- È incluso nel Windows ADK (Windows Assessment and Deployment Kit). Scaricate l'ADK dal sito Microsoft e, in installazione, selezionate le funzionalità Application Compatibility Tools. Vengono installate sia l'edizione a 32 bit sia quella a 64 bit; dovete usare l'edizione a 32 bit per le app a 32 bit e quella a 64 bit per le app a 64 bit. Applicate un database di compatibilità personalizzato (.sdb) eseguendo il comando sdbinst su ogni PC.
Profilo dell’autore
Pagina di presentazione dell’autore dell’articolo.
Go Komura
Rappresentante di KomuraSoft LLC
Specializzato nello sviluppo di software Windows, nella consulenza tecnica e nell’analisi dei malfunzionamenti, soprattutto nei progetti con sistemi esistenti e guasti difficili da riprodurre.