Io sostengo WIKIMEDIA FOUNDATION

"Imagine a world in which every single human being can freely share in the sum of all knowledge" (wikimedia)

E' stato un atto doveroso contribuire al sostentamento di una fondazione, quella di WIKIMEDIA, da cui tutti noi giornalmente fruiamo informazioni.

Sono orgoglioso di ciò che ho fatto.

Autodesk LMTOOLS/FlexLM su Windows 2008 R2

L'avvio dei servizi di licenza mediante LMTOOLS su Windows 2008 R2 mi ha procurato non pochi problemi.

Per risolverli ho applicato in parte ciò che riporta l'articolo FlexLM on Windows 2008 R2 ed in particolare ho definito completamente il servizio immettendo il percorso per lmgrd.exe, per il file di licenza e di log del debug:

Ho inoltre inserito nel Firewall di Windows le eccezioni per la porta  2080 e dalla porta 27000 alla porta 27009

 

Installare AUTOCAD 2008 su Windows Server 2008 R2 64 bit

In seguito ad una migrazione di dominio da Windows 2003 32 bit a Windows Server 2008 R2 64 bit mi sono trovato nell'impossibilità di installare AUTOCAD 2008 (license server). Dopo diverse ricerche sono approdato al seguente articolo pubblicato sul sito diAutodesk:

http://forums.autodesk.com/t5/AutoCAD-Architecture/Updated-Workaround-instructions-for-64-Bit-OS-Install/td-p/1941946

E' quindi possibile installare la versione 2008 di AUTOCAD a patto di modificare come segue i files di installazione ACA.msi e Setup.ini presente sul DVD di installazione di Autocad:

  1. Copiare l'intero contenuto del DVD di installazione sul disco rigido del proprio PC;
  2. Scaricare l'utilità Orca da questo link, altrimenti scaricare prima Microsoft Windows SDK nella versione compatibile con il proprio sistema operativo  e quindi installare Orca eseguendo Orca.msi da C:\Program Files\Microsoft SDKs\Windows\vx.0\Bin\
  3. Aprire in modifica il file ACA.msi tramite Orca, cancellare l'azione "CheckFor64BitOS" presente nella tabella "InstallExecuteSequence" e salvare le modifiche;
  4. Modificare il file Setup.ini tramite Blocco Note eliminando la riga "PLATFORM=NO_WOW_64_PROCESS" nel gruppo "#==================== Platform Requirement"
  5. Creare infine un nuovo DVD di installazione

Pressione del tasto Enter/Invio in una textbox inserita in un form (Protect form submission on enter key-press)

La pressione del tasto enter in un qualsiasi campo di input provoca, in un form HTML, lo scatenarsi dell'evento "submit".

(Ho direttamente sperimentato la sconvenienza di tale comportamento progettando un modulo di ricerca di contenuti in un sito web. Per ragioni di progettazione, la texbox  di ricerca, si collocava in un tag form: la pressione del tasto invio nella textbox doveva rimandare ad una pagina sinottico dei risultati di ricerca. Di fatto però la caratteristica standard  del form produceva il postback della pagina impedendo il reindirizzamente voluto.)

 Per disabilitare questa caratteristica è sufficiente inserire nella pagina il seguente codice jquery:

$(function() {

 
    $("form").bind("keypress", function(e) {
            if (e.keyCode == 13) return false;
      });

 
});

 

Redirect per Manutenzione di applicazioni con app_offline.htm

Spesso sorge l'esigenza di impedire al sito di produzione di rispondere alle richieste di pagina per poter svolgere agevolmente le operazioni di aggiornamento o distribuzione di un applicazione web.

In tale contesto gli utenti dovranno così essere reindirizzare ad una pagina di "Sito in muntenzione"; cioò permette di evitare errori che potrebbero verificarsi quando le modifiche sono completate solo parzialmente.

Il modo più semplice per assolvere a tale necessità è di seguire quanto riportato nell'articolo http://msdn.microsoft.com/it-it/library/ff925031.aspx, ovvero
  • Creare un file denominato App_offline.htm (di dimensioni  maggiori di 512 byte) e includervi un messaggio per comunicare agli utenti che il sito non è disponibile perché è in fase di aggiornamento.
  • Posizionare il file App_offline.htm nella cartella radice del sito Web di destinazione.

    Di fatto questa feature era già presente nella versione 2.0 di ASP.NET. La presenta della pagina app_offline.htm provoca lo shutdown dell'Appdomain e diventa l'unica pagina vista da chiunque tenti di connettersi al sito.

Microsoft SQL Server Management Studio: risultati delle query troncati

Mi è capitato di eseguire query in Management Studio e di ottenere risultati troncati. Ho così speso parecchio tempo per comprenderne il motivo, inputando la causa dell'errore al mio codice sql.

Di fatto invece il troncamento dei risultati dipende semplicemente dall'impostazione di default dei risultati nelle query in Management Studio.

Per aumentare il numero di caretteri visualizzati in ogni colonna è quindi sufficiente fare click sul menù "Query" e quindi su "Opzioni Query".

Nella voce Testo del nodo Risultati  è quindi possibile aumentare il valore della proprietà "Numero di caratteri visualizzati in ogni colonna" impostata di default a 256

Generare "ad hoc" un menù multilivello: struttura dati e conversione da XML a HTML utilizzando XSLT

Ho utilizzato questa tecnica per generare dinamicamente un accordion menù multilivello ...
Consideramo il seguente diagramma ad albero, rappresentazione della struttura di un possibile menù di navigazione:
- Root (nodeID=1, parentID=0)
- Item 1 (nodeID=2, parentID=1)
  - item 1.1 (nodeID=3, parentID=2)
  - item 1.2 (nodeID=4, parentID=2)
     - item 1.2.1 (nodeID=5, parentID=4)
  - item 1.3 (nodeID=6, parentID=2)
- Item 2 (nodeID=7, parentID=1)
La seguente struttura può essere memorizzata nella seguente tabella di un database: MenuTable(nodeID,parentID,title).
A partire dalla tabella MenùTable è possibile generare facilmente la rappresentazione XML del grafo ad albero utilizzando il seguente codice:
Dim sqlString As String = "SELECT NodeID, ParentID, title FROM MenuTable ORDER BY NodeID"
        Dim cmd As SqlCommand = New SqlCommand(sqlString)
        Dim conn As SqlConnection
        conn = New SqlConnection(DBConnection)
        Dim ds As DataSet = New DataSet
        Dim da As SqlDataAdapter = New SqlDataAdapter
        da.SelectCommand = cmd
        da.Fill(ds)
        Dim dt As DataTable = ds.Tables(0)

        ' create an XmlDocument (with an XML declaration)
        Dim XDoc As New XmlDocument()
        Dim XDec As XmlDeclaration = XDoc.CreateXmlDeclaration("1.0", Nothing, Nothing)
        XDoc.AppendChild(XDec)

        ' iterate through the sorted data
        ' and build the XML document
        For Each Row As DataRow In dt.Rows
            ' create an element node to insert
            ' note: Element names may not have spaces so use ID
            ' note: Element names may not start with a digit so add underscore
            Dim NewNode As XmlElement = XDoc.CreateElement("_" & Row("NodeID").ToString())
            NewNode.SetAttribute("NodeID", Row("NodeID").ToString())
            NewNode.SetAttribute("ParentID", Row("ParentID").ToString())
            NewNode.SetAttribute("title", Row("title").ToString())

            ' special case for top level node
            If IsDBNull(Row("ParentID")) Then
                XDoc.AppendChild(NewNode)
            Else
                ' root node
                ' use XPath to find the parent node in the tree
                Dim SearchString As [String]
                SearchString = [String].Format("//*[@NodeID=""{0}""] ", Row("ParentID").ToString())
                Dim Parent As XmlNode = XDoc.SelectSingleNode(SearchString)

                If Parent IsNot Nothing Then
                    Parent.AppendChild(NewNode)
                Else

                    ' Handle Error: Employee with no boss
                End If
            End If
        Next
        XDoc.Save(Server.MapPath("~/menu/menu.xml"))
In tal modo nella cartella menu della nostra applicazione verrà generato il file menu.xml così fatto:
<?xml version="1.0"?>
<_1 NodeID="1" ParentID="0" title="Root">
  <_2 NodeID="2" ParentID="1" title="item 1">
    <_3 NodeID="3" ParentID="2" title="item 1.1" />
    <_4 NodeID="4" ParentID="2" title="item 1.2" >
      <_5 NodeID="5" ParentID="5" title="item 1.2.1" />
    </_4>
    <_6 NodeID="6" ParentID="2" title="1.3" />
  </_2>
  <_7 NodeID="7" ParentID="1" title="item 2"/>
</_1>
Vogliamo ora trasformare la struttura XML in una stringa HML così fatta:
<li><a name="_2" href="#">item 1</a>
   <ul>
      <li><a name="_3" href="page.aspx?nodeID=3">item 1.1</a></li>
      <li><a name="_4" href="#">item 1.2</a>
         <ul>
            <li><a name="_5" href="page.aspx?nodeID=5">item 1.2.1</a>
         </ul>
      </li>
      <li><a name="_6" href="page.aspx?nodeID=6">item 1.3</a></li>
   </ul>
</li>
<li><a name="_7" href="page.aspx?nodeID=7">item 2</a></li>
Definiamo quindi il seguente file XSLT di trasformazione e memorizzaiamolo nella cartella "menu" con il nome menu.xslt
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes"/>


    <!--The <xsl:template> element contains rules to apply when a specified node is matc-->
    <xsl:template match="node()">
        
        <!--calcola il numero di nodi figli dell'elemento corrente-->
        <xsl:variable name="total-el">
            <xsl:value-of select="count(descendant::*)"/>
        </xsl:variable>

        <xsl:variable name="name">
            <xsl:value-of select="name()"/>
        </xsl:variable>       
            
        <!--se il nodo nonè la root ed il numero di nodi figlio è >0 allora applica il seguente modello ai nodi figlio dell'elemento corrente..-->

            <xsl:if test="$total-el > 0 and $name != '_1'">
                <li>
                    <a name="{name()}" href="#" rel="self">
                        <xsl:value-of select="@NodeHTML"/>
                    </a>
                    <ul>
                        <xsl:apply-templates />
                    </ul>
                </li>
            </xsl:if>


            <xsl:if test="$total-el > 0 and $name = '_1'">
                    <ul class="topnav">
                        <xsl:apply-templates />
                    </ul>
            </xsl:if>      
        
            <!--altrimenti ...-->
            <xsl:if test="$total-el = 0">
                <li>
                    <a name="{name()}" href="articles.aspx?NodeID={name()}">
                        <xsl:value-of select="@NodeHTML"/>
                    </a>
                </li>
            </xsl:if>


    </xsl:template>

</xsl:stylesheet>
Non ci resta infine che applicare la trasformazione mediante il segunte codice:
Dim xDoc As New XmlDocument()
xDoc.Load(Server.MapPath("~/menu/menu.xml"))
Dim sw As New System.IO.StringWriter()
Dim xslTrans As New XslCompiledTransform()
xslTrans.Load(Server.MapPath("~/menu/menu.xslt"))
xslTrans.Transform(xDoc.CreateNavigator(), New XsltArgumentList(), sw)

Using writer As System.IO.StreamWriter = System.IO.File.AppendText(HttpRuntime.AppDomainAppPath & "menu\menu.txt")
   writer.WriteLine(sw.ToString())
End Using
producendo nel file menu.txt nella cartella menu il codice html desiderato.

Come mantenere invariato il formato valuta in ASP.NET in un'applicazione multi lingua

Le impostazioni linguistiche in una pagina ASP.NET sono dipendenti da due proprietà: Culture e UICulture. 
La proprietà Culture deterimina il risultato delle funzioni dipendenti dalle impostazioni lingiuistiche come ad esempio l'uso delle maiuscole e delle minuscole, la formattazione di date e numeri, il formato della valutam, il confronto tra stringhe ecc...
La proprietà UICulture determina quali risorse devono essere caricate per la pagina.
Da questa premessa è quindi semplice comprendere come è possibile mantenere invariato il formato della valuta in un'applicazione multilingua: sarà sufficiente infatti mantenere costante il valore della proprietà Culture e cambiare la propietà UICulture per caricare di volta in volta le risorse della pagina in base alla lingua selezionata.
Ciò è possibile  eseguendo l'override del metodo InitializeCulture in ogni pagina dell'applicazione. Volendo quindi mantenere costante il formato della valuta all'€, per ogni pagina sarà sufficiente richiamare la seguente Sub:
Protected Overrides Sub InitializeCulture()
        ' Culture: valore costante
        Thread.CurrentThread.CurrentCulture = New CultureInfo("it-IT")

        ' UI Culture: valore contenuto nella variabile di Sessione Session("UICulture")
        Dim c As CultureInfo
        If Session("UICulture") IsNot Nothing Then
            c = DirectCast(Session("UICulture"), CultureInfo)
        Else
            c = New CultureInfo("it-IT")
        End If

        Thread.CurrentThread.CurrentUICulture = c

        MyBase.InitializeCulture()
    End Sub
in cui il valore di UICulture è determinato dalla variabile di Sessione UICulture in modo che diventi comune a tutte le pagine.

Abilitare il Full-Text Search in SQL Server 2008 Express

In SQL SERVER 2008 Express, la caratteristica  Full-Text Search è disponibile solo nella versione "Microsoft SQL Server 2008 Express with Advanced Services" scaricabile all'indirizzo http://www.microsoft.com/downloads/it-it/details.aspx?FamilyID=B5D1B8C3-FDA5-4508-B0D0-1311D670E336

Segnalo che per abilitare il Full-Text Search non è possibile eseguire l'upgrade di una installazione eseguita da una versione di SQL Server Express differente dalla sopra citata.

Per cui per fruire della caratteristica Full-Text Search si deve eseguire una nuova installazione di SQL Server Express utilizzando il download eseguito da Microsoft.

I problemi di incompatibilità eventualmente rilevati nell'installazione possono essere tralasciati; la soluzione indicata, ovvero l'applicazione del Service Pack 1, non è applicabile per la versione "Microsoft SQL Server 2008 Express with Advanced Services" in quanto il Serviche Pack 1 non è corredato dei Servizi avanzati utili per abilitare il Full-Text Search.