05 mar
Posted by: Andrea Lanfranchi in: Mondo IT, Programmazione
Molto spesso nelle applicazioni Web il codice che scriviamo gestisce tutta una serie di directory siano esse temporanee oppure organiche all’applicazione (come ad esempio la creazione di cartelle specifiche per contenere le immagini di un articolo) dipendenti dalla radice principale dell’applicazione. Quando queste cartelle non servono più (ad esempio l’articolo è stato eliminato) si cancellano e basta.
E qui si pone un problema : quando il codice ASP.NET (sia esso VB, C# o qualsiasi altro) cancella una sottodirectory della radice principale della applicazione, succede che l’intera sessione viene invalidata. Mi è successo proprio perchè ogni volta che, tramite codice, effettuavo una cancellazione, dovevo riautenticarmi. Il motivo di questo comportamento è dovuto a due fattori:
Come ovviare quindi al problema ? Semplice … o non si cancellano le directory (naaahhhh) … oppure si attiva lo stato di session out-of-process tramite StateServer o un provider a vostra scelta: sqlServer oppure uno custom. In questo modo non incorrete nel rischio di spaccarvi la testa per due ore perse a capire come mai la sessione scade in continuazione.
Alla prossima.
30 dic
Posted by: Andrea Lanfranchi in: Mondo IT, Programmazione
In questo mio precedente articolo mi sono già cimentato nell’implementazione di un sistema di backup utilizzando 7-zip come archiviatore. Purtroppo lo script batch che ne è uscito fuori, per quanto funzionante, è soggetto a molte, troppe limitazioni: una su tutte, la pratica impossibilità di maneggiare correttamente in un file batch nomi di file o cartelle che contengano caratteri speciali come “&” (ampersand).
Da non trascurare nemmeno le non eccellenti performance generali dello script che, non potendo gestire delle vere e proprie variabili, è costretto ad impostare continuamente variabili di ambiente. Insomma … la cara vecchia shell DOS è alla frusta da un bel pezzo, specialmente se paragonata alle estese e flessibilissime shell di comando Linux.
Forse proprio per quest’ultimo motivo (l’arretratezza delle shell di comando), Microsoft ha, ormai da un pezzo, la sua PowerShell. In pochissime parole : “Una eccellente implementazione del framework .Net in una console a riga di comando“. Troppo complicato ? Nahhhh.
PowerShell è forse uno dei maggiori balzi in avanti registrati nelle tecniche di scripting per Windows, nonchè la chiave di volta per la risoluzione dei problemi del mio script di backup con 7-zip.
E’ così nato il nuovo script : 7zBackup.ps1 . L’intero progetto è ospitato su Codeplex (la piattaforma Microsoft per la condivisione di progetti open) e non me ne vogliano gli amici italiani se è tutto in inglese. La soluzione offerta da questo script è, per me, molto interessante e con l’inglese è più facile trovare dei contributors o dei tester.
Le procedure di backup sono sempre una bella gatta da pelare. Personalmente non amo sistemi di backup “proprietari” che utilizzano codifiche esclusive perchè gli archivi generati (indipendentemente dal fatto che si tratti di copie su nastro o su disco) non sono facilmente portabili. A parte sistemi di classe enterprise che consentono procedure di disaster recovery, quello che mi aspetto da un archivio di backup è la semplice possibilità di portarlo, all’occorrenza, su un’altra macchina e di ripristinare i file senza dover installare pesanti software specifici. Insomma … che l’archivio di backup generato sia leggibile facilmente e ovunque con minime installazioni.
Il diminuito costo dello storage rende sempre più frequente l’utilizzo di backup su file (utilizzando SAN, NAS o gli stessi dischi dei server) relegando le copie su tape library ad ambiti sempre più ristretti e specializzati. In questo contesto ho sempre preferito, per il backup dei dati su server Windows, l’utilizzo dell’utilità di backup Microsoft (NTBackup) per i motivi che ho descritto sopra soprattutto la portabilità (leggo lo stesso archivio su un altro server Windows senza dover installare praticamente nulla).
L’utilizzo di NTBackup porta vantaggi ma anche svantaggi:
Ho deciso allora di “cimentarmi” nella creazione di un batch di automazione per il backup che rispondesse ai seguenti requisiti:
Il risultato è 7backup.bat : un singolo script batch (.bat) la cui esecuzione è facilmente schedulabile con minimi ed intuitivi switch da riga di comando.
Attenzione !! Questo script utilizza i junction points come caratteristica del file system NTFS. I Junction points vengono rappresentati da Windows Explorer come normali cartelle. MAI e ripeto MAI cancellare un junction point utlizzando Windows Explorer perchè questo porta alla cancellazione anche dei dati nella cartella di destinazione (ovvero quella oggetto del puntamento junction).
Disclaimer : questo script è stato testato con cura tuttavia può non essere esente da errori. Non utilizzatelo in ambienti ad alta criticità senza prima averlo testato adeguatamente su computer di prova. L’utilizzo del software è a vostra completa discrezione e rischio. Non rispondo di perdite di dati e non fornisco supporto diretto se non per il tramite, secondo tempo e disponibilità, di questo sito web.
I requisiti per il funzionamento sono :
Lo script batch è interamente documentato (in inglese) e tutte le impostazioni rilevanti possono essere codificate come costanti o passate da riga di comando. Solo due valori devono essere impostati a mano. Per fare questo potete editare il file 7backup.bat con un normale editor di testo come notepad (vi consiglio comunque di dotarvi di Notepad++). I valori rilevanti sono :
:: 7-zip executable path.
:: If you have installed 7zip using standard path, then you do not need to
:: change this
SET BK-7ZBIN=%ProgramFiles%\7-zip\7z.exe
In questa variabile dovrete inserire il percorso completo che punta all’applicazione 7-zip. Se avete installato 7-zip con le impostazioni standard non dovreste avere bisogno di modificare nulla.
L’altra variabile rilevante è la seguente:
:: Junction executable path.
:: Find where Junction.exe is and set it here. If Junction.exe is in
:: a directory within the PATH variable you can simply indicate
:: junction.exe
SET BK-JUNCTION=%ProgramFiles%\SysInternalsSuite\Junction.exe
Le applicazioni di SysInternals non prevedono una procedura di setup e quindi possono essere inserite in qualsiasi percorso. Prendetevi un momento per individuare Junction.exe all’interno del computer ed indicate quindi il percorso in cui si trova. Se il percorso prevede directory con spazi NON mettete le virgolette. Verranno aggiunte automaticamente dallo script quando serviranno.
A questo punto potete provare ad eseguire il batch senza nessun parametro. Viene emessa la schermata di aiuto come segue:
Tutti gli switch di comando sono spiegati e documentati.
Non resta altro che creare una “lista” di directory che vorrete backuppare. Con un normale editor scrivete l’elenco delle directory da backuppare, una per riga, indicandone il percorso completo inclusa la lettera di unità. Ad esempio:
C:\Dir1\Dati
C:\Dir3
D:\Archivi
Salvate il file in formato testo e annotatevi la posizione.
Attenzione. Non è ammessa l’indicazione di una Directory e di una sua Sottodirectory. Per esempio non è possibile indicare:
C:\Dir1\Dati
C:\Dir1\Dati\Commerciale
Questo perchè la procedura crea, per ogni directory elencata, un junction point nell’area di lavoro, includendo automaticamente tutte le sottodirectory. Il mancato rispetto di questa regola può portare a risultati imprevedibili e loop infiniti.
Potete ora lanciare il backup come ad esempio seguente:
7backup.bat --dirlist "C:\Mie Selezioni\Lista.txt" --type full --destdir "F:\MieiBackup" --rotation 3
Questo produrrà la generazione di un archivio di backup completo (ovvero di tutti i file contenuti nelle directory indicate nel file c:\Mie Selezioni\Lista.txt). Il file archivio verrà depositato nella directory F:\MieiBackup dove verranno mantenuti solo i 3 più recenti backup dello stesso tipo.
Alcune cose da considerare:
Ogni commento o integrazione è bene accetto.
30 ago
Posted by: Andrea Lanfranchi in: Programmazione
Sono diventato matto per un paio di giorni alla ricerca del perchè, senza apparente motivo, utilizzando il connettore .NET di MySql, per certe Stored Procedures non riuscivo ad ottenere il valore dei parametri di Output. In realtà il motivo c’era ed era documentato qui.
In pratica succede che se il comando viene eseguito per restituire un reader la collezione dei parametri associati al comando non viene sincronizzata.
Per esempio
Dim myCmd as New MySqlCommand("nome_procedura", Connection)
myCmd.CommandType = CommandType.StoredProcedure
Dim myOutParam as New MySqlParameter("nomeparametro", MySqlDbType.Int32)
myOutParam.Direction = ParameterDirection.Output
myCmd.Parameters.Add(myOutParam)
Dim myReader as MySqlDataReader = myCmd.ExecuteReader()
If Not myCmd.Parameters(myOutParam).Value Is Nothing Then
' Qui i parametri di output non hanno ancora il valore di ritorno
...
...
End If
myReader.Close
If Not myCmd.Parameters(myOutParam).Value Is Nothing Then
' Qui i parametri di output hanno il valore di ritorno
...
...
End If
Se invece il comando viene eseguito con il metodo ExecuteNonQuery … non ci sono problemi.
Quasi tutti i programmatori che abbiano basato le loro applicazioni web su ASP (VBScript) arrivano prima o poi a porsi seriamente questa domanda nel momento in cui devono partire con un nuovo progetto. La risposta, almeno nel mio caso (o meglio per l’azienda per cui lavoro), non è proprio facile e merita un qualche approfondimento.
Innanzitutto è bene sgombrare il campo da inutili allarmismi riguardanti la prevista morte futura del supporto ASP Classico sulle piattaforme Microsoft. Dal momento che IIS 7.0 supporta ASP classico perfettamente (con qualche accorgimento come spiegato in questo Tips and Tricks for Classic Asp Developers on IIS 7) è lecito pensare che la deadline di ASP classico sarà portata in avanti almeno fino al 2017 il che, rispetto alla data attuale, mette a disposizione un’ulteriore finestra di 10 anni per prendere una decisione.
Il problema quindi si sposta automaticamente sulle differenze di contenuto tecnologico offerte dai due linguaggi, anche se, è bene dirlo, è assolutamente improprio tentare di mettere sullo stesso piano di “linguaggio” le due modalità. Sono infatti profondissime le differenze tra i due e lontanissimi i presupposti su cui si basano.
ASP classico è un linguaggio di scripting: ovvero una sequenza di istruzioni scritte su normalissimi file di testo (modificabili con un qualsiasi editor – a me piace moltissimo Crimson Editor) che vengono interpretati al volo (on-the-fly) da una dll di sistema, la ASP.dll. In quanto tale la sintassi prevista per le pagine ASP (Active Server Pages) è una qualsiasi tra quelle supportate da Microsoft ovvero VBScript, JScript e PHPScript anche se la stragrande maggioranza dei casi di utilizzo prevede l’impiego di VBScript
ASP.NET (aspx), al contrario, è una completa riprogettazione del modello Active Server Pages basato sull’utilizzo del Framework .NET (versione 1 oppure 2): il codice scritto (che può essere implementato nel linguaggio che si ritiene più consono : VB, C#, C++, J#) non è più interpretato ma “tradotto” in un linguaggio intermedio (MSIL – Microsoft Intermediate Language) le cui istruzioni vengono direttamente elaborate dal framework .NET. Molti credono che le pagine ASP.NET siano pagine compilate (ovvero dei binari in linguaggio macchina) ma ciò non è vero e può indurre a conclusioni errate. Il prodotto di compilazione di un codice .NET è, come detto, di fatto una traduzione che ha bisogno comunque di un ambiente di run-time per poter funzionare: il framework .NET appunto. Per i programmatori VB (pre .NET) è immediata l’analogia con lo pseudo-code di VB che necessitava delle librerire VBRun per poter funzionare.
Ma la vera rivoluzione copernicana, di fatto quella che crea i maggiori problemi di approccio ad ASP.NET per i vecchi programmatori ASP, sta nella completa rivisitazione della sintassi e della struttura del codice. Mentre con ASP classico si è abituati a pensare al normale flusso di programma top-down, con ASP.NET bisogna cambiare completamente il proprio approccio alla progettazione ed allo sviluppo: le classi diventano l’oggetto atomico del codice.
In aggiunta a ciò è anche utile osservare che mentre VBScript è una versione light del supporto Visual Basic con un numero molto limitato di funzioni e quasi nessun oggetto nativo (per algoritmi complessi infatti i programmatori devono spesso riferirsi ad oggetti COM esterni), ASP.NET è un VB pieno (oppure un C# pieno ecc) con tutte i modelli di oggetto (e relativi metodi e proprietà) offerti dal framework .NET: in altre parole, e semplificando all’estremo, con i linguaggi .NET praticamente non si ha bisogno d’altro. Per rendere l’idea è un po’ come avere un coltellino svizzero con solo una lama ed un paio di forbici (VBScript) contro un utensile con 5 lame diverse, forbici per la carta e per la plastica, un set completo di brugole, cacciaviti di varia natura, chiavi inglesi e chiavi tubolari, seghe, martelli e chi più ne ha più ne metta ( .NET ). Tutto questo, ovviamente, rende più difficoltoso l’approccio al linguaggio quanto meno sotto il profilo dell’apprendimento mnemonico di tutti gli spazi dei nomi. Come se ciò non bastasse ogni singolo metodo può disporre di diversi override (ovvero modi di invocare il metodo con sequenze di parametri diverse) il che ha reso, nel mio personalissimo caso, praticamente impossibile avvicinarsi alla programmazione .NET senza l’ausilio di un IDE Microsoft con tanto di intellisense: per fortuna Microsoft ha reso pubblicamente disponibili e gratuite le versioni “light” del suo celeberrimo Visual Studio grazie alle versioni Visual Studio Express.
Fatte queste debite e stringatissime premesse, è forse ora di cominciare ad analizzare i perchè di una scelta a favore di ASP Classico o di ASP.NET per l’avvio di un nuovo progetto. Ci tengo però a sottolineare che le domande e risposte che sto per proporvi si basano sull’assunto di un approccio ad un progetto di sviluppo di medio piccole dimensioni: l’analisi di un progetto di grandi dimensioni che abbia tempi di sviluppo e manutenzione molto lunghi, elevate complessità e necessità di integrazione particolarmente articolate, potrebbe (anzi sicuramente richiede) un’analisi completamente diversa.
Per ora mi fermo qui … ogni commento è bene accetto.
| L | M | M | G | V | S | D |
|---|---|---|---|---|---|---|
| « lug | ||||||
| 1 | ||||||
| 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| 9 | 10 | 11 | 12 | 13 | 14 | 15 |
| 16 | 17 | 18 | 19 | 20 | 21 | 22 |
| 23 | 24 | 25 | 26 | 27 | 28 | 29 |
| 30 | 31 | |||||