Vai al contenuto
Offerte

Windows: perché un programma va col doppio clic ma non da batch

In questo articolo Indice dei contenuti 3 sezioni

Capita più spesso di quanto si immagini che un programma Windows funzioni senza intoppi con un doppio clic da Esplora file e poi si blocchi, magari con un messaggio d’errore apparentemente senza senso, quando viene lanciato da un file batch. Non si tratta di un difetto di Windows 11 né di un capriccio della finestra del terminale. Molto spesso cambia semplicemente la directory di lavoro corrente assegnata al processo, un dettaglio ereditato dall’architettura Win32 di decenni fa che ha ancora oggi effetti molto concreti su applicazioni legacy, utilità portabili e software che cercano i propri file di configurazione con percorsi relativi.

Raymond Chen, storico sviluppatore Microsoft e autore del blog The Old New Thing, ha raccontato il caso di un cliente alle prese proprio con questo comportamento. Il programma partiva regolarmente in modalità grafica ma restituiva un errore se richiamato da uno script usando il percorso completo dell’eseguibile. Chen ha individuato quasi subito il possibile colpevole. Lo script avviava correttamente l’EXE ma lasciava invariata la cartella corrente del processo, una differenza minima sulla carta e invece enorme quando il software si aspetta di trovare altri file “accanto a sé”.

Percorso dell’eseguibile e cartella corrente non sono la stessa cosa

Quando Windows crea un processo entrano in gioco almeno due percorsi. Il primo indica il file eseguibile caricato, per esempio C:Program FilesMiaAppMiaApp.exe. Il secondo è la directory corrente, da cui il programma risolve molti percorsi relativi. Un’applicazione può quindi trovarsi fisicamente in C:Program FilesMiaApp e partire con C:UsersMarioDesktop come cartella di lavoro. Se il codice prova ad aprire config.ini, il sistema non deduce da solo che lo sviluppatore intendesse il file nella cartella del programma.

Con il doppio clic da Esplora file Windows imposta come directory corrente proprio la cartella che contiene l’eseguibile, anche per garantire compatibilità con i programmi che cercano file aggiuntivi tramite percorsi relativi. Se invece un batch lancia “C:Program FilesMiaAppMiaApp.exe” mentre il prompt si trova in C:Scripts, MiaApp.exe potrebbe cercare settings.dat dentro C:Scripts e fallire, pur essendo esattamente lo stesso programma. La documentazione Win32 conferma che un processo figlio eredita la directory del processo padre, salvo indicazioni diverse, e l’API CreateProcess prevede un parametro dedicato proprio a questo.

La soluzione pratica con pushd e popd

Il cliente ha risolto cambiando cartella prima dell’avvio grazie ai comandi pushd e popd, più puliti di un semplice cd. Pushd salva la posizione attuale in uno stack e si sposta nella cartella indicata, mentre popd riporta il prompt dove si trovava all’inizio. Basta quindi eseguire pushd “C:Program FilesMiaApp”, avviare MiaApp.exe e poi richiamare popd. Con le estensioni dei comandi attive pushd gestisce anche percorsi UNC come \serversharecartella creando una lettera di unità temporanea, poi rimossa da popd. Per gli script da spostare insieme all’applicazione torna utile pushd “%~dp0”, che lavora rispetto alla posizione del file .bat stesso.

Per chi sviluppa, però, correggere il batch cura il sintomo più che la causa. Un’applicazione moderna non dovrebbe dare per scontato che la cartella corrente coincida con quella dell’eseguibile. GetModuleFileName permette di ricavare il percorso dell’EXE caricato, mentre per configurazioni, cache e database locali conviene usare SHGetKnownFolderPath e cartelle come LocalAppData o RoamingAppData, lontano da Program Files. Inoltre GetCurrentDirectory e SetCurrentDirectory agiscono su uno stato condiviso dall’intero processo: se un thread cambia directory mentre un altro risolve un percorso relativo, il secondo rischia di aprire il file sbagliato.

DLL e App Paths, gli altri tasselli del problema

La directory corrente può incidere anche sul caricamento delle DLL. Se un programma chiede una libreria indicando solo il nome, Windows segue un ordine di ricerca che in certe condizioni include la cartella corrente. Una DLL omonima piazzata da un aggressore potrebbe così essere caricata al posto di quella prevista, secondo il principio del DLL hijacking. Safe DLL Search Mode abbassa la priorità della directory corrente ma non elimina il rischio, motivo per cui Microsoft consiglia percorsi completi o ricerche ristrette con SetDefaultDllDirectories, AddDllDirectory e LoadLibraryEx.

Chen indica infine una seconda pista, le chiavi App Paths del Registro, presenti almeno da Windows 95 sotto HKEYCURRENTUSER o HKEYLOCALMACHINE nel ramo SoftwareMicrosoftWindowsCurrentVersionApp Paths. Una voce può contenere un valore Path con directory supplementari che la shell aggiunge all’ambiente quando avvia l’applicazione tramite ShellExecuteEx, e così lo stesso EXE lanciato dal terminale può ricevere indicazioni diverse.

Fonte: TecnoAndroid

Condividi:
65 Condivisioni