Vai al contenuto

Software legacy

Migrazione di un gestionale Visual Basic 6

Migrazione di un vecchio gestionale VB6 da Windows XP a Windows moderni per un cliente: analisi dell'eseguibile, dipendenze ActiveX, e recupero dell'accesso amministrativo.

Visual Basic 6 Windows Software legacy ActiveX COM Reverse engineering Microsoft Access Crystal Reports

All'inizio di ottobre 2026 sono stato contattato da un cliente per recuperare un vecchio gestionale, utilizzato ancora regolarmente in azienda, e trasferirlo da un PC con Windows XP a una macchina con una versione più recente di Windows.

Fin qui nulla di particolare, se non fosse che il programma risaliva a parecchi anni prima e non erano più disponibili i sorgenti. Avevo soltanto l'installazione funzionante sul vecchio computer, il file eseguibile e una serie di DLL e OCX distribuite tra la cartella del programma e quelle di sistema.

L'obiettivo era farlo tornare operativo, non riscriverlo. Il cliente aveva bisogno di continuare a utilizzare il software e i relativi archivi, senza affrontare una migrazione verso un altro prodotto.

Identificare l'eseguibile

La prima cosa da fare è stata capire con cosa avevo a che fare. Il fatto che un programma sia un .exe Windows dice ben poco sul linguaggio utilizzato o sulle dipendenze richieste.

L'analisi del formato PE (Portable Executable) ha mostrato un eseguibile PE32 x86, risalente al 2008. Tra le librerie importate compariva MSVBVM60.DLL, il runtime di Microsoft Visual Basic 6.

Questo era già un buon indizio: un'applicazione VB6 di quell'epoca può dipendere da numerosi componenti COM, spesso installati e registrati separatamente dal programma.

Per esaminare le dipendenze ho utilizzato Dependency Walker, una vecchia utility ancora utile quando si lavora con software Windows di questo tipo. Un'altra verifica possibile è cercare all'interno dell'EXE riferimenti testuali a librerie esterne, ad esempio con strings di Sysinternals:

strings.exe -n 6 gestionale.exe | findstr /i ".dll .ocx"

Questo comando può rivelare riferimenti interessanti, ma non basta per ricostruire tutte le dipendenze. Alcuni componenti vengono caricati dinamicamente oppure istanziati come oggetti COM, quindi non compaiono necessariamente nella tabella degli import dell'eseguibile.

In altre parole, identificare il linguaggio era soltanto il primo passo.

DLL, OCX e registrazione COM

Ho recuperato la directory del gestionale dal computer originale e l'ho trasferita sulla nuova macchina. Il programma però non funzionava correttamente: mancavano diversi componenti esterni.

Tra quelli individuati c'erano:

  • MSCOMCTL.OCX, utilizzato per vari controlli dell'interfaccia;
  • vbalSbar.ocx e SSubTmr.dll, legati a componenti aggiuntivi dell'interfaccia;
  • MSCOMM32.OCX, richiesto da una specifica funzione;
  • Crystl32.OCX e CRPE32.DLL, utilizzati dal sistema di reportistica Crystal Reports.

Gli OCX sono controlli ActiveX, basati sulla tecnologia COM di Microsoft. Non sempre è sufficiente copiarli nella cartella del programma: spesso devono anche essere registrati nel sistema, in modo che Windows possa individuare la classe COM richiesta dall'applicazione.

Lo strumento classico è regsvr32.exe. Per esempio:

regsvr32 "C:\Percorso\MSCOMCTL.OCX"

C'è però una questione da tenere presente nei Windows moderni: Visual Basic 6 produce eseguibili a 32 bit. Su un sistema operativo a 64 bit questi programmi vengono eseguiti tramite WOW64 e devono utilizzare componenti COM della stessa architettura.

Anche la versione di regsvr32 conta. Su Windows a 64 bit, per registrare un OCX a 32 bit si utilizza quella presente in SysWOW64:

%SystemRoot%\SysWOW64\regsvr32.exe "C:\Percorso\MSCOMCTL.OCX"

Su Windows a 32 bit si utilizza invece la normale regsvr32 di sistema. Il percorso dell'OCX nell'esempio è indicativo: ciò che conta è usare la versione corretta del programma di registrazione e avere tutte le dipendenze necessarie.

Naturalmente non tutte le DLL possono essere registrate in questo modo. Alcune sono semplici librerie native, altre dipendono a loro volta da ulteriori file. Copiare e registrare indiscriminatamente tutto quello che si trova non è una buona soluzione.

Il classico errore 429

Una volta recuperati i primi componenti, il gestionale iniziava ad avviarsi, ma aprendo alcune finestre compariva il classico errore di Visual Basic:

Run-time error '429':
ActiveX component can't create object

Il messaggio significa che l'applicazione non è riuscita a creare un oggetto COM. Le cause possono essere diverse: OCX mancante, registrazione assente, versione incompatibile o dipendenza secondaria non disponibile.

Un caso riguardava vbalSbar.ocx. Avevo individuato un file con quel nome, ma non era sufficiente: serviva una versione compatibile con quella utilizzata dall'applicazione originale.

Un altro riguardava Crystal Reports. Il controllo Crystl32.OCX era presente, ma la relativa registrazione richiedeva anche CRPE32.DLL. Recuperata la dipendenza, è stato possibile proseguire con il ripristino dei componenti di reportistica.

In una fase successiva è emersa anche la necessità di MSCOMM32.OCX. Il programma non lo richiedeva all'avvio, ma soltanto entrando in una particolare funzione.

È una caratteristica abbastanza comune di questi software: il fatto che la schermata iniziale si apra non significa che tutte le funzionalità siano operative.

Process Monitor: vedere cosa cerca il programma

Quando il messaggio d'errore non specifica il componente coinvolto, può essere utile osservare direttamente le operazioni eseguite dal programma.

Per questo ho utilizzato Process Monitor di Sysinternals, filtrando gli eventi relativi al processo del gestionale. Lo strumento permette di vedere gli accessi ai file e al registro di Windows, comprese le ricerche delle chiavi necessarie all'attivazione COM.

Il procedimento è abbastanza semplice: avviare la cattura, riprodurre l'errore e controllare quali file o chiavi di registro venivano cercati in quel momento.

Occorre comunque interpretare i risultati. Un evento NAME NOT FOUND non indica necessariamente un problema: Windows prova spesso più percorsi prima di trovare il componente richiesto. È la sequenza degli eventi, più che la singola riga, a fornire indicazioni utili.

Senza sorgenti e senza simboli di debug, strumenti di questo tipo permettono almeno di capire che cosa sta tentando di fare l'eseguibile.

Recuperare l'accesso amministrativo

Oltre alle dipendenze di Windows c'era un altro problema: per verificare correttamente le funzionalità del gestionale serviva accedere con un utente amministratore, ma la password non era più conosciuta.

Il programma utilizzava anche un database Microsoft Access, nel classico formato .mdb. Esaminando gli archivi originali ho individuato la tabella Users, che conteneva i dati degli account applicativi, compresa la credenziale associata all'utente amministratore.

La password era quindi recuperabile direttamente dai dati del gestionale, senza intervenire sull'eseguibile e senza dover modificare il sistema di autenticazione.

Con quell'account è stato possibile accedere alle funzionalità riservate all'amministratore e completare le verifiche. Questo passaggio è stato importante quanto il recupero degli OCX: un'applicazione può anche funzionare perfettamente dal punto di vista tecnico, ma se non si dispone di un account con i permessi necessari alcune sezioni rimangono comunque inaccessibili.

La presenza della credenziale all'interno di un semplice database Access evidenzia anche un limite delle vecchie applicazioni: spesso la sicurezza dei dati e quella degli account erano affidate quasi interamente ai permessi sul filesystem e all'accesso fisico al computer. Oggi non sarebbe una soluzione adeguata per un software nuovo.

Il risultato

Al termine dell'intervento il gestionale era nuovamente avviabile e utilizzabile sul computer di destinazione. Erano state recuperate le librerie necessarie, ripristinati i controlli ActiveX e verificati gli accessi alle funzionalità dell'applicazione tramite l'account amministratore.

In tutto sono servite circa quattro ore. Non ho scritto una sola riga di codice del gestionale: il lavoro è consistito nell'analizzare un eseguibile chiuso, capire da cosa dipendesse e ricostruire un ambiente in cui potesse ancora funzionare.

Considerazioni finali

Nei programmi Windows di qualche decennio fa era normale affidarsi a librerie e controlli registrati a livello di sistema. Quando si spostava il software su un altro PC, la cartella dell'applicazione rappresentava spesso soltanto una parte dell'installazione reale.

Il problema non è tanto Windows XP contro una versione più recente di Windows. È ricostruire tutte le condizioni su cui quel programma faceva affidamento: architettura, runtime, componenti COM, database e permessi applicativi.

Non sempre è possibile recuperare un gestionale in questo modo, soprattutto quando entrano in gioco driver o componenti non più compatibili. Ma l'assenza dei sorgenti non implica automaticamente che il programma sia inutilizzabile.

Prima di pensare a una riscrittura completa, vale la pena capire esattamente che cosa gli manca per tornare a funzionare.