Microsoft documenta che cos'è il Package Support Framework. Ciò che è molto più difficile da trovare è quello che vi serve davvero alle 16 di un giovedì: l'applicazione si è confezionata senza errori, si installa, si avvia, e poi fa qualcosa di sbagliato. Quale correzione cura quale sintomo?
Questa è quella mappatura. Presuppone che il pacchetto in sé sia valido e che il problema sia comportamentale.
Cosa fa davvero PSF
Il Package Support Framework si colloca tra un'applicazione confezionata e Windows, e intercetta le chiamate che l'applicazione effettua. MSIX esegue le applicazioni in un contenitore con scritture su file e registro reindirizzate, e con una directory di lavoro che non è sempre quella che l'applicazione dava per scontata. Le applicazioni più datate sono state scritte prima che tutto questo esistesse, quindi chiedono le cose in modi a cui il contenitore risponde diversamente.
Meccanicamente sono tre pezzi. PSFLauncher32.exe o PSFLauncher64.exe sostituisce la vostra applicazione come attributo Executable dell'elemento Application nel manifesto, così viene eseguito per primo. Legge config.json dalla radice del pacchetto. Poi inietta il runtime PSF e le DLL di correzione che avete indicato nel processo dell'applicazione, e l'applicazione parte dietro di esse. Se non siete certi dell'architettura dell'applicazione, il launcher a 32 bit funziona in ogni caso.

PSFLauncher parte per primo, legge la configurazione, inietta le correzioni, poi passa il testimone.
PSF non corregge i bug. Traduce le assunzioni.
Quella distinzione conta, perché vi dice quando smettere di ricorrere a PSF e correggere invece il pacchetto.
La tabella dei sintomi
L'applicazione si avvia ma non trova subito i propri file.
Di solito è la directory di lavoro. L'applicazione dava per scontato di partire nella propria cartella di installazione e ora parte altrove, quindi i percorsi relativi non risolvono nulla. Quando non è dichiarata alcuna directory di lavoro, Windows usa System32, che non è quasi mai ciò che un'applicazione legacy si aspettava. Questa è la singola causa più comune e la più economica da correggere, perché richiede un valore workingDirectory in config.json anziché una correzione di reindirizzamento vera e propria. Verificatelo prima di ogni altra cosa.
L'applicazione parte, funziona e perde le impostazioni tra una sessione e l'altra.
Reindirizzamento dei file, tramite FileRedirectionFixup.dll. L'applicazione sta scrivendo la configurazione accanto al proprio eseguibile, dentro il pacchetto, dove le scritture non persistono. La scrittura sembra riuscire e va silenziosamente da nessuna parte di utile. Reindirizzate quei percorsi verso una posizione per utente e le impostazioni sopravvivono.
L'applicazione scrive nella propria cartella di installazione e poi fallisce all'avvio successivo. Stessa causa profonda del punto precedente, che si manifesta in modo più violento perché il file che ha scritto è uno di cui ha bisogno. Stessa correzione. In Process Monitor questo si legge come un esito di accesso negato sotto la cartella del pacchetto.
Qualcosa fallisce solo per gli utenti standard e funziona per gli amministratori.
Diritti di accesso al registro, di solito, gestiti da RegLegacyFixups.dll. L'applicazione apre una chiave a livello di macchina e chiede più accesso di quanto le serva, tipicamente controllo completo quando in realtà legge soltanto. Un amministratore la passa liscia, un utente standard no. La correzione riscrive l'accesso richiesto in qualcosa che il contenitore concederà, usando conversioni come Full2RW e RW2R. Può anche simulare l'eliminazione di chiavi che l'applicazione insiste a rimuovere, e nascondere chiavi che non dovrebbero essere visibili dentro il contenitore.
Un plug-in, un componente aggiuntivo o un eseguibile di supporto non si carica.
Caricamento dinamico delle librerie, tramite DynamicLibraryFixup.dll. L'applicazione sta caricando qualcosa da un percorso che il contenitore risolve diversamente, oppure cerca una dipendenza che si aspetta di trovare installata a livello di macchina. La sua configurazione imposta forcePackageDllUse ed elenca ogni libreria per name insieme al filepath relativo al pacchetto da cui dovrebbe provenire. Questa è la correzione che più spesso rivela una dipendenza non confezionata, che è un problema più grande di un percorso.
Niente di evidente, e nessuno schema chiaro.
Tracciate per primo, con TraceFixup.dll. Non tirate a indovinare. La correzione di tracciamento registra ciò che l'applicazione sta davvero chiedendo, il che trasforma un gioco di ipotesi in una lista breve. Ogni ora spesa a tracciare ne fa risparmiare parecchie spese ad applicare correzioni a caso chiedendosi quale abbia aiutato.
Che aspetto ha davvero la configurazione
Vive tutto in un unico file alla radice del pacchetto, e la forma è la stessa qualunque correzione applichiate:
{
"applications": [
{ "id": "ContosoApp", "executable": "ContosoApp/ContosoApp.exe", "workingDirectory": "ContosoApp/" }
],
"processes": [
{ "executable": "ContosoApp",
"fixups": [
{ "dll": "FileRedirectionFixup.dll",
"config": { "redirectedPaths": { "packageRelative": [ { "base": "ContosoApp/", "patterns": [ ".*\\.ini", ".*\\.log" ] } ] } } }
] }
]
}
Tre cose vale la pena interiorizzarle. L'id deve corrispondere all'attributo Id dell'elemento Application nel manifesto, altrimenti non succede nulla e non ottenete alcun errore utile. L'executable sotto processes è normalmente il nome del file privato di percorso ed estensione, ed è trattato come un pattern, quindi un valore sbadato cattura più processi di quanti intendevate. E applications, processes e fixups sono tutti array, che è il modo in cui un pacchetto finisce per portarsi dietro una pila di correzioni che nessuno sa spiegare in seguito.
Tracciate prima di tirare a indovinare
Due strumenti fanno quasi tutto il lavoro diagnostico, e rispondono a domande diverse.
Process Monitor vi dice cosa è successo al confine del sistema operativo. Filtrate sul vostro eseguibile, escludete gli esiti riusciti, poi leggete dal fondo dell'elenco verso l'alto, perché gli eventi più recenti stanno lì. State cercando due espressioni: accesso negato, e percorso o nome non trovato. La prima punta di solito al reindirizzamento o ai diritti di accesso al registro. La seconda punta alla directory di lavoro.
La correzione di tracciamento racconta la stessa storia dall'interno del processo, ed è pensata proprio per far emergere i fallimenti di compatibilità. Aggiungete la DLL al pacchetto e un frammento a config.json:
{ "dll": "TraceFixup.dll", "config": { "traceLevels": { "filesystem": "allFailures" } } }
Per impostazione predefinita il tracciamento filtra via i fallimenti che considera attesi, che di solito è quello che volete, perché le applicazioni tentano di routine di eliminare file che non ci sono mai stati e ignorano l'esito. Il costo è che un fallimento genuino può nascondersi dentro il rumore che rimuove. Iniziate con l'impostazione predefinita e allargate ad allFailures per l'area che sospettate solo quando la vista predefinita non ha spiegato il comportamento.
L'output va a un debugger collegato. Se non state effettuando il debug, eseguite DebugView di Sysinternals e leggetelo lì. Questo è tutto il flusso di lavoro, ed è molto più rapido che applicare una correzione e sperare.
La regola che fa risparmiare più tempo
Lavorate in quest'ordine:
- Riproducete il malfunzionamento con un account utente standard, non con uno amministrativo. Metà delle segnalazioni "MSIX l'ha rotto" sono assunzioni sui permessi che c'erano da sempre ed erano prima mascherate.
- Tracciate prima di correggere. Scoprite cosa sta chiedendo l'applicazione.
- Correggete la directory di lavoro prima di ricorrere a qualsiasi reindirizzamento.
- Applicate una correzione alla volta e ritestate. Impilarne tre in una volta significa che non saprete mai quale servisse, e ve le porterete dietro tutte e tre per sempre.
Quell'ultimo punto conta più di quanto sembri. La configurazione delle correzioni è qualcosa che la persona successiva eredita. Un pacchetto che porta tre correzioni dove ne serviva una è un pacchetto che nessuno oserà toccare tra due anni.
C'è una quinta regola che emerge dopo qualche decina di pacchetti: scrivete il perché, accanto al pacchetto, in una forma che sopravviva a chi ha deciso. Una riga per correzione, che nomini il sintomo curato, è sufficiente. Senza di essa il revisore successivo deve riprodurre il fallimento originale prima di poter rimuovere qualcosa in sicurezza, ed è per questo che così poche correzioni vengono mai rimosse.
Quando PSF è la risposta sbagliata
PSF è uno strato di compatibilità, e gli strati si accumulano. Rivolgetevi ad altro quando:
- L'applicazione ha bisogno di un driver o di un servizio a livello di sistema. Non è un problema di contenitore e nessuna correzione lo risolverà. Probabilmente non dovrebbe essere MSIX.
- L'applicazione ha bisogno di scrivere in una posizione davvero a livello di macchina e altre applicazioni devono leggerla. Il reindirizzamento rende quella scrittura invisibile a tutti gli altri, il che sembra una soluzione e non lo è.
- L'applicazione fallisce solo quando è in esecuzione una seconda applicazione. La comunicazione tramite file condivisi, chiavi di registro condivise o oggetti con nome non sopravvive in modo pulito alla containerizzazione, e nessuna singola correzione la affronta.
- Siete alla quarta correzione. A quel punto la risposta onesta è che oggi questa applicazione non è un buon candidato MSIX. MSI o un pacchetto PowerShell App Deployment Toolkit la consegneranno con meno cerimonie, e potrete tornarci più avanti.
Sapere quando fermarsi è la differenza tra una pratica di packaging e un cumulo crescente di strati non documentati. Incide anche sulla consegna: un pacchetto che porta correzioni si comporta diversamente sotto App Attach rispetto a uno pulito, che è l'argomento di cosa significa PSF per App Attach.
Farlo ripetutamente
Diagnosticare una applicazione in questo modo è soddisfacente. Farlo per quattrocento è un problema di organico, ed è il motivo per cui la mappatura tende a vivere nella testa di una persona sola e ad andarsene con lei.
Su scala di parco applicativo la mappatura è anche l'unità di lavoro sbagliata. Ciò che vi serve è un verdetto per applicazione: si consegna così com'è, si consegna con correzioni, oppure non può ancora muoversi. Arrivarci in fretta trasforma una conversione da legacy a MSIX da progetto aperto a calendario, ed è l'inquadratura dietro il nostro percorso applicazioni legacy.
Dove si inserisce EtherApps Forge
EtherApps Forge predispone le correzioni PSF come parte del packaging anziché come un progetto di rimedio separato successivo, così la decisione viene registrata insieme al pacchetto invece che ricordata. L'approccio più ampio è sul nostro percorso packaging e distribuzione MSIX, e la predisposizione delle correzioni stessa è arrivata in EtherApps Forge 1.0.6.
L'effetto pratico è sulla ripartizione dei verdetti anziché su un singolo pacchetto. Le applicazioni che in precedenza sarebbero state accantonate perché si comportavano male dentro il contenitore passano invece nella categoria "si consegna con correzioni", con il motivo allegato, così che la persona successiva ad aprire il pacchetto possa vedere cosa è stato deciso e perché.
EtherApps Forge è un'applicazione desktop per Windows con una prova gratuita di 7 giorni, così potete testare il ciclo di diagnosi su un'applicazione che sapete già essere ostica.
Esplora il packaging e distribuzione MSIX
Iniziate dalla directory di lavoro, tracciate prima di tirare a indovinare, e aggiungete una correzione alla volta.
