Inno Setup Installazione ocx e dll

Indice

A chi è rivolto questo articolo?
Concetti base su dll e ocx
Come faccio a sapere di che dll o ocx il mio programma ha bisogno?
Eccezioni più comuni
Installiamo realmente le dll
Esempio completo

A chi è rivolto questo articolo?

Questo articolo è rivolto a chi già conosce almeno a livello base Inno Setup e vuole imparare a installare in maniera corretta gli ocx e le dll di cui un programma può avere bisogno. Se non si conosce Inno Setup è consigliabile leggere e imparare prima la guida base, anche perchè i concetti in essa spiegati non verranno rispiegati qui.

Concetti base su dll e ocx

Bene in sostanza per capire come installare una dll o un ocx bisogna innanzitutto capire di che tipo sono le dll o ocx in questione e in base a quello impostare i flag corretti, ora io ne darò una spiegazione veloce, ma consiglio comunque un approfondimento per chi è nuovo a questi concetti.
I tipi di dll e ocx che ci interessano sono (faccio gli esempi con le dll, ma per gli ocx è la stessa cosa)
  • dll com e dll non com
    Le dll com "spiegazione" (che a meno di particolari procedure sono le dll prodotte da visual basic) sono delle dll che necessitano di essere registrate per funzionare, ovvero hanno bisogno di alcuni dati che in fase di regisatrazione della dll vengono scritti all interno del registro di sistema di windows. Un esempio di dll com può essere la Microsoft Scripting Runtime(scrrun.dll), mentre un esempio di dll non com può essere KERNEL32.DLL
  • dll condivise e dll non condivise
    Le dll condivise sono librerie che vengono utilizzate da più di un programma, quindi quando disinstalliamo una dll di questo tipo dobbiamo stare attenti ad eliminarla se e solo se non c'è nessun altro programma che la utilizza, per avere questa informazione bisogna controllare nel registro di sistema dove c'è un contatore degli utilizzi che ci dice quanti programmi stanno usando questa dll. Un esempio di dll condivisa può essere la Microsoft Scripting Runtime(scrrun.dll), mentre per le dll non condivise l'esempio più semplice sono quelle che creiamo noi ad hoc per i nostri programmi
  • dll di sistema e dll non di sistema
    Quest'ultima distinzione è abbastanza intuitiva, le dll di sistema sono le dll che fanno parte di windows mentre quelle non di sistema sono tutte le altre. In sostanza una dll di sistema non va mai disinstallata e va installata se e solo se la versione che noi andiamo ad installare è successiva a quella già presente ed è adatta al sistema operativo sul quale la stiamo installando. Un esempio di dll di sistema può essere KERNEL32.DLL mentre una dll non di sistema può essere la Microsoft Scripting Runtime(scrrun.dll)

Come faccio a sapere di che dll o ocx il mio programma ha bisogno?

Ottima domanda, in teoria visto che il programma lo stiamo facendo noi dovremmo già sapere di che cosa il nostro programma ha bisogno, ma se (come a me purtroppo è capitato) dobbiamo realizzare il setup di un programma non fatto da noi e senza documentazione dobbiamo fare noi un analisi e capire di che cosa questo programma ha bisogno.
Visto che stiamo parlando di visual basic bisogna dire che in vb esistono due modi per utilizzare dei componenti o dll esterni uno con associazione diretta (Progetto -> Componenti o Progetto -> Riferimenti) e uno con associazione tardiva (CreateObject o Controls.Add), se i progetti sono pochi possiamo farli passare tutti uno ad uno e cercare queste cose oppure possiamo scriverci un programmino che faccia questo tipo di ricerca per noi e cerchi all'interno di ogni file con estensione vbp (Visual Basic Project) le stringhe che iniziano con Object (ocx) o reference (dll) dopodiche in ogni file con estensione frm (form) o ctl (controllo utente) cerchi le stringhe che contengono CreateObject o Controls.Add, possiamo così ottenere un elenco "quasi" sicuramente completo delle dll e degli ocx di cui il nostro programma ha bisogno.
Ho scritto quasi perchè nulla vieta che una dll o un ocx abbia a sua volta delle dipendenze, perchè questo è quello che dobbiamo fare adesso, ovvero per ogni dll o ocx di cui il nostro programma necessita dobbiamo documentarci il più possibile e capire di che natura è e quali sono le sue eventuali dipendenze e se le dipendenze sono in funzione di qualcosa (ad esempio la lingua del sistema operativo). In questo ci può venie in aiuto il file .dep della dll o ocx, se presente questo file dovrebbe darci le informazioni di cui abbiamo bisogno.
Esempio scrrun.dll -> SCRRUN.DEP, apriamo col notepad SCRRUN.DEP e scopriremo che innanzitutto è una dll com (Register=$(DLLSelfRegister)) inoltre vedremo che per far funzionare la scrrun.dll dobbiamo installare anche la MSVCRT.dll e poi in base alla lingua in cui viene deciso di fare installare il programma (o la lingua del sistema operativo dipende dai casi) una delle altre dll elencate (nel caso dell italiano la ScrrnIT.dll), quindi controlliamo se queste due dll aggiuntive hanno anchesse dei file dep, no non ne hanno quindi dovremmo aver risolto tutte le dipendenze della dll.
Se invece il file dep non c'è e si tratta di una dll di terze parti bisogna documentarsi su quella cercando in internet o contattando la casa produttrice o l'autore
Il procedimento che ho appena descritto non è sicuro al 100 %, ma nella stragrande maggiornza dei casi dovrebbe essere sufficente a coprire tutte le dipendenze dei vostri progetti.

Eccezioni più comuni

Ci sono almeno quattro casi noti e molto comuni in cui quanto scritto sopra non è perfettamente valido, ovvero
  • Reference=*\G{00020430-0000-0000-C000-000000000046}#2.0#0#..\..\WINNT\system32\stdole2.t lb#OLE Automation
    Questo file con estensione tlb non va mai installato perchè i file con estensione tlb servonosolo in fase di progettazione
  • I VB System Files ovvero quei file che sono sempre necessari per far funzionare un programma fatto in vb (non ci sono nei riferimenti perchè sono impliciti, vb non ha bisogno di leggere che il progetto ha bisogno di quelle dll o ocx, lo sà a priori), nei sistemi operativi moderni questi file sono preinstallati e sono di conseguenza file di sistema, ma se per caso si installa su un vecchio sistema operativo bisognerà tenerne conto. La Microsoft stessa fornisce un micro setup comandabile anche da Inno Setup questa è la versione italiana, ovviamente in base alla lingua del sistema operativo cambia anche il tipo di setup da lanciare
  • Reference=*\G{2A75196C-D9EB-4129-B803-931327F72D5C}
    #2.8#0#..\..\Programmi\File comuni\System\ADO\msado15.dll#Microsoft ActiveX Data Objects 2.8 Library
    Questo file invece fa parte degli MDAC (Microsoft Data Access Component) che servono invece a connetersi ad un db e forniscono l'occetto connection, Recordset eccetera (ADODB insomma), anche in questo caso la microsoft ci fornisce un setup comandabile anche da Inno Setup, solo che questa volta non solo bisogna stare attenti alla lingua ma anche al sistema operativo, questo comunque è il link per la versione italiana che va bene per windows xp
  • cn.Open "Provider=Microsoft.Jet.OleDb.4.0;Data Source=C:\Provadb.mdb"
    Bene in questo caso invece (che è l'unica vera eccezzione perchè negli altri casi era sufficente documentarsi e le informazioni si sarebbero trovate) si implica che nel sistema operativo sia presente l'engine Jet per accedere al database, ancora una volta la microsoft ci fornisce un setup comandabile da inno setup che varia da sistema operativo a sistema operativo e da lingua a lingua, questo è il link della versione italiana per windows xp ad esempio.

Sembra complicato vero? Bhe non voglio mentire, se fatto bene e per parecchi sistemi operativi con le relative lingue effettivamente è complicato, richiede decine di download e parecchi test (ovviamente su macchine virtuali se no si impazzisce davvero), per fortuna però c'è una piccola scappatoia:
Devo dire che normalmente non vado pazzo per questo genere di soluzioni ma dopo molte prove devo ammettere con piacere che Randem System con il suo setup autoinstallante fa in sostanza tutto il lavoro di cui abbiamo parlato sopra (ovvero installa MDac, VbRuntime e Jet appropriati al sistema operativo e alla lingua) e lo fa bense senza chiedere un centesimo evitandoci così sia il lavoro di download che quello di stesura del codice e sopratutto sono setup già testati, perchè in sostanza questa sarebbe la parte più complessa, proviamo a pensare di dover testare bene un setup che deve funzionare sotto WIn 98, Win 2000, Win Xp, Win 2003, Windows SVista, in Italiano, Inglese, Francese, Tedesco. Come detto sopra nella maggior parte dei casi stiamo parlando di file di sistema e NON POSSIAMO PERMETTERCI DI SBAGLIARE, quindi provate a pensare a quante macchine virtuali, quanti test (con Sp senza, con aggiornamenti senza....).
Per adesso io non ho mai avuto problemi con questi setup e ho fatto parecchie istallazioni, quindi anche se ovviamente non posso garantirvi che siano perfetti posso dire che per quanto mi riguarda si sono dimostrati estremamente validi e utili.

Installiamo realmente le dll

Dunque facciamo sul serio, per questo piccolo tutorial immaginiamo di aver creato un programma in vb6 che si connette ad un database Mdb (quelli che crea anche access) che oltretutto manipola dei file immagine presenti su disco, dopo l'analisi descritta sopra scopro che ho bisogno di
  1. VbRuntime (è un programma fatto in vb6)
  2. Mdac (ci connettiamo ad un db quindi...)
  3. Jet (è l'engine con il quale ci connettaimo al db access)
  4. Miscrosoft Scripting Runtime (la usiamo per spostare i file)
  5. FreeImage (la usiamo per ottenere alcune informazioni particolari sui file immagine)
  6. prj_Prova.dll (dll del mio programma che mi serve come esempio)

Ok Procediamo:

VbRuntime, Mdac, Jet con un sentito ringraziamento a RandemSystem questi li possiamo liquidare con il suo setup AutoInstallante ok scarichiamolo nella nostra solita cartella C:\ProvaSetup\DatiSetup e scriviamo

[Files]
Source: "C:\ProvaSetup\DatiSetup\VB_DCOM_MDAC_JET_AutoSetu p.exe"; DestDir: "{tmp}"; Flags: deleteafterinstall

Il Flags deleteafterinstall significa che una volta terminato il setup questo file verrà cancellato, in effetti a noi dopo questo file non servirà più, da notare infatti che viene messo nella cartella temporanea di windows.
Quindi nella sezione Run scriviamo

[Run]
Filename: "{tmp}\VB_DCOM_MDAC_JET_AutoSetup.exe"; Parameters: /NORESTAR /VERYSILENT WorkingDir: {tmp}; Flags: skipifdoesntexist
  • Parameters sono quei parametri che andranno accodati alla riga di comando del file per capirci sarebbe come se in dos o nella finestra esegui o nella shell di VB,etc scrivessimo
    VB_DCOM_MDAC_JET_AutoSetup.exe /NORESTAR /VERYSILENT
    In questo caso i parametri significano, non riavviare il pc alla fine dell aggiornamento e lancia un istallazione sileziosa (ovvero non chiedere conferma per niente)
  • WorkingDir è la directory da cui verrà lanciato il file, se omessa verrà utilizzata quella scritta in FileName, quindi in questo caso è abbastanza inutile, ma visto che su Randem System dicono di usarla così usiamola, male non fà.
  • skipifdoesntexist significa se non viene trovato il file da lanciare non dare errori ma continua con l'istallazione come se niente fosse (anche questo in sostanza abbastanza inutile visto che il file che viene lanciato lo installiamo noi)

Perfetto passiamo ora alla Microsoft Scripting RunTime che abbiamo già anallizzato all'inizio, sappiamo che è una dll com, non è una dll di sistema ed è una dll condivisa. Visto il contenuto del file dep sappiamo anche che per ogni lingua c'è un aposita dll, quindi dobbiamo chiederci per quante lingue dobbiamo prevedere questa istallazione, a titolo d'esempio scegliamo di installare solo in lingua italiana o inglese.

[Files]
Source: "C:\ProvaSetup\DatiSetup\scrrun.dll"; DestDir: "{sys}"; Flags: restartreplace sharedfile regserver
;Dipendenze di scrrun.dll
Source: "C:\ProvaSetup\DatiSetup\MSVCRT.dll"; DestDir: "{sys}"; Flags: restartreplace sharedfile
Source: "C:\ProvaSetup\DatiSetup\ScrrnIT.dll"; DestDir: "{sys}"; Languages: it; Flags: restartreplace sharedfile
;Per la lingua inglese non serve installare niente perchè è quella di default contenuta nella scrrun.dll
  • languages: it, significa che questo file viene installato se e solo se viene scelto il linguaggio italiano (it è il valore del parametro name della sezione [languages])
  • restartreplace, visto che stiamo parlando di file condivisi può darsi che il file che andiamo ad installare sia già in uso da qualche processo, quindi (se la nostra è una versione superiore ovviamente, vorrei chiarire che InnoSetup fa sempre questo controllo a meno che non gli si dica diversamente) non posso sostituirlo subito allora questo flag istruisce il setup affinche venga richiesto un riavvio del pc al termine dell istallazione e quando questo viene fatto sostituisce il file
  • sharedfile, parametro importantissimo che serve per dire a windows che stiamo installando un file condiviso e di conseguenza andrà incrementato il relativo contatore di utilizzi, di modo che quando il programma andrà disinstallato questo file verrà eliminato se e solo se il contatore di utilizzi è a 0 e previa ulteriore conferma dell utente. A onor del vero si potrebbe evitare la richiesta di conferma eliminazione all utente ma lo sconsiglio caldamente perchè ci possiamo fidare dei nostri setup, ma di quelli fatti dagli altri? Se qualcuno avesse fatto un setup nel quale viene installato quel file ma non viene incrementato il contatore di utilizzi e noi lo eliminassimo quel programma non funzionerebbe più, mentre chiedendo conferma all utente "si spera" che se sa cosa sta facendo mi consente di eliminare il file altrimenti se non ne è sicuro lo lascia dovè.
  • regserver, questo parametro semplicemente dice che è una dll o ocx che deve essere registrato.

FreeImage.dll, è una dll di terze parti (anche abbastanza famosa), quindi è non solo possibile ma anche probabile che ci sia già un qualche programma che la utilizza quindi è una dll condivisa, non è una dll di sistema visto che è prodotta da terzi e il sistema operativo funziona tranquillamente senza su questo non c'è dubbio, e non è una dll com (informazione reperita in internet o molto più semplicemente tentando di registrarla)

[Files]
Source: "C:\ProvaSetup\DatiSetup\FreeImage.dll"; DestDir: "{sys}"; Flags: restartreplace sharedfile

prj_Prova.dll, ok questa è una dll creata ad hoc per il mio programma, solo io la utilizzo quindi non è una dll condivisa, per lo stesso motivo men che mai è una dll di sistema e visto che è una dll standard fatta con vb è decisamente una dll com anche se ho letto alcuni articoli fatti da Guru del calibro di AntonioGiuliana o Gibra in cui descrivono come creare anche con vb dll non com, ma non è questo il caso e comunque se avessimo seguito uno di questi articoli per creare una dll non com credo che ce ne accorgeremmo no?

[Files]
Source: "C:\ProvaSetup\DatiSetup\prj_Prova.dll"; DestDir: "{app}"; Flags: restartreplace ignoreversion regserver

Il Flags ignoreversion significa che anche se nella cartella in cui si installa il file fosse già presente quella dll in una versione superiore a quella che io voglio installare la dll viene comunque installata e va comunque a sostituire quella esistente perchè appunto ignora la versione del file e non fa il controllo. Attenzione questo flag non va MAI usato per file di sistema o condivisi

Esempio completo

Chiaramente questa volta non posso mettere in allegato l'esempio completo perchè il setup di RandemSystem da solo sorpassa i 30 MB, ma vi scrivo qui delle istruzioni molto semplici per ricreare il tutto.

Reperimento file (esempio su windows 2000 con vb6 installato)
  • VB_DCOM_MDAC_JET_AutoSetup.exe -> download
  • scrrun.dll -> C:\WINNT\System32\scrrun.dll
  • MSVCRT.dll -> C:\WINNT\System32\MSVCRT.dll
  • ScrrnIT.dll -> C:\WINNT\System32\ScrrnIT.dll
  • FreeImage.dll -> download aprite lo zip, all'interno della cartella Dist
  • prj_Prova.dll -> da dove volete, io l'ho creata al volo con vb ma va bene una qualsiasi dll com, tanto è solo per prova

Inno Setup
codice:
[Setup]
;Nome dell'applicazione che si andrà a installare
AppName=Programma Tutorial per Inno Setup
;Nome dell'applicazione che si andrà a installare
AppVerName=Programma Tutorial per Inno Setup 2.0.2
;Ditta produttrice
AppPublisher=Programma Tutorial per Inno Setup
;Sito della ditta produttrice
AppPublisherUrl=www.MioAzienda.It
;Sito del supporto
AppSupportUrl=www.MioAzienda.It/supporto
;Sito degli aggiornamenti
AppUpdatesUrl=www.MioAzienda.It/ProgrammaTutorial/aggiornamenti
;Cartella di default per il programma
DefaultDirName={pf}\CartellaProgrammaTutorial
;Cartella di default per il menu start di windows
DefaultGroupName=Programma Tutorial
;Cartella di default per il menu start di windows
OutputDir=c:\ProvaSetup\SetupCompilato
;Cartella di default per il menu start di windows
OutputBaseFilename=Setup
;File di licenza
LicenseFile=c:\ProvaSetup\DatiSetup\Licenza.txt
;Metodo di compressione lzma, ovvero quello di 7zip
Compression=lzma
;Compressione ulteriore
SolidCompression=yes
;Personalizzazioni aggiuntive non spiegate nel tutorial
  ;Icona del setup
  SetupIconFile=IconaInstall.ico
  ;Immagine che andrà a sinistra nel setup
  WizardImageFile=C:\Programmi\Inno Setup 5\WizModernImage-IS.bmp
  ;Immagine piccola che andrà in alto a destra nel tutorial
  WizardSmallImageFile=C:\Programmi\Inno Setup 5\WizModernSmallImage-IS.bmp

[Languages]
;Setup in italiano
Name: "it"; MessagesFile: "compiler:Languages\Italian.isl"
;Setup in inglese
Name: "en"; MessagesFile: "compiler:default.isl"

[Tasks]
;Chiediamo se vuole un icona sul desktop
Name: "IconaDescktop"; Description: "{cm:CreateDesktopIcon}"; Flags: unchecked

[Files]
;Installiamo il file del programma
Source: "c:\ProvaSetup\DatiSetup\ProgrammaTutorial.exe"; DestDir: "{app}"; Flags: ignoreversion

;Mdac Jet vbRuntime
Source: "C:\ProvaSetup\DatiSetup\VB_DCOM_MDAC_JET_AutoSetup.exe"; DestDir: "{tmp}"; Flags: deleteafterinstall

;Micorsoft Scripting runtime
Source: "C:\ProvaSetup\DatiSetup\scrrun.dll"; DestDir: "{sys}"; Flags: restartreplace sharedfile regserver
;Dipendenze di scrrun.dll
Source: "C:\ProvaSetup\DatiSetup\MSVCRT.dll"; DestDir: "{sys}"; Flags: restartreplace sharedfile
Source: "C:\ProvaSetup\DatiSetup\ScrrnIT.dll"; DestDir: "{sys}"; Languages: it; Flags: restartreplace sharedfile
;Per la lingua inglese non serve installare niente perchè è quella di default contenuta nella scrrun.dll

;FreeImage
Source: "C:\ProvaSetup\DatiSetup\FreeImage.dll"; DestDir: "{sys}"; Flags: restartreplace sharedfile

;prj_Prova.dll
Source: "C:\ProvaSetup\DatiSetup\prj_Prova.dll"; DestDir: "{app}"; Flags: restartreplace ignoreversion regserver

[Icons]
;Icona e collegamento del menù di avvio
Name: "{group}\ProgrammaTutorial"; Filename: "{app}\ProgrammaTutorial.exe"
;Icona e collegamento dal desktop
Name: "{commondesktop}\ProgrammaTutorial"; Filename: "{app}\ProgrammaTutorial.exe"; Tasks: IconaDescktop

[Run]
;Lancio gli aggiornamenti sugli mDac, Jet e VbRunTime
Filename: "{tmp}\VB_DCOM_MDAC_JET_AutoSetup.exe"; Parameters: /NORESTAR /VERYSILENT WorkingDir: {tmp}; Flags: skipifdoesntexist
;Lancio il programma (se l'utente è daccordo)
Filename: "{app}\ProgrammaTutorial.exe"; Description: "{cm:LaunchProgram,ProgrammaTutorial}"; Flags: nowait postinstall