Visualizzazione post con etichetta Microsoft. Mostra tutti i post
Visualizzazione post con etichetta Microsoft. Mostra tutti i post

lunedì 1 giugno 2015

Mono 4.0 e C# 6.0

Mono 4.0 è la prima versione di Mono che contiene codice Microsoft .NET open source. In questa versione sono abilitate per default le nuove funzionalità del C# 6.0.

Queste sono le nuove funzionalità

  • Auto property initializers
  • Static members
  • String interpolation
  • Expression-bodied methods
  • Expression-bodied properties
  • Index initializers
  • Null-conditional operators
  • The nameof operator
  • Exception filters
  • Await in catch and finally

E questo un esempio di utilizzo (ho usato MonoDevelop 5.9)

using System;
using Newtonsoft.Json.Linq;
using System.Configuration;

//Con - Static members
using static System.Math;

namespace Azzan.Mono4Sample
{
    public class Point
    {
        /*
        //Prima di - Auto property initializers
        public int X {get; private set;}
        public int Y {get; private set;}

        public Point()
        {
            X = 4;
            Y = 9;
        }
        */

        //Con - Auto property initializers
        public int X {get; } = 4;
        public int Y {get; } = 9;

        public Point(int x, int y) { X = x; Y = y; }

        //Prima di Expression-bodied properties
        /*
        public double Dist
        {
            //Prima di - Static members
            //get { return Math.Sqrt(X * X + Y * Y); }

            //Con - Static members
            get { return Sqrt(X * X + Y * Y); }
        }
        */

        //Con - Expression-bodied properties
        public double Dist => Sqrt(X * X + Y * Y);

        //Prima di - Expression-bodied methods
        /*
        public override string ToString()
        {
            //Prima di - String interpolation
            //return string.Format("[Point: X={0}, Y={1}, Dist={2}]", X, Y, Dist);

            //Con - String interpolation
            return $"[Point: X={X}, Y={Y}, Dist={Dist}]";
        }
        */

        //Con - Expression-bodied methods
        public override string ToString() => $"[Point: X={X}, Y={Y}, Dist={Dist}]"; 

        //Prima di - Index initializers
        /*
        public JObject ToJson()
        {
            var result = new JObject();
            result["x"]  = X;
            result["y"]  = Y;
            return result;
        }
        */

        //Con - Index initializers
        public JObject ToJson() => new JObject() { ["x"]  = X, ["y"]  = Y };

        //Prima di - Null-conditional operators
        /*
        public static Point FromJson(JObject json)
        {
            if(json != null &&
                json["x"] != null &&
                json["x"].Type  == JTokenType.Integer &&
                json["y"] != null &&
                json["y"].Type  == JTokenType.Integer)
            {
                return new Point((int)json["x"], (int)json["y"]);
            }

            return null;
        }
        */

        //Con - Null-conditional operators
        public static Point FromJson(JObject json)
        {
            if(json?["x"]?.Type == JTokenType.Integer &&
               json?["y"]?.Type == JTokenType.Integer)
            {
                return new Point((int)json["x"], (int)json["y"]);
            }

            return null;
        }
            
        public Point Add(Point point)
        {
            if(point == null)
            {
                //Prima di - The nameof operator
                //throw new ArgumentNullException("point");

                //Con - The nameof operator
                throw new ArgumentNullException(nameof(point));
            }

            return point;
        }

        public void DoSomething()
        {
            //Prima di - Exception filters
            try
            {
                
            }                                //Con - Exception filters
            catch(ConfigurationException ex) //when (ex.IsSevere)
            {
                //Con - Await in catch and finally
                //await LogAsync(ex);
            }
            finally 
            {
                //Con - Await in catch and finally
                //await CloseAsync();
            }
        }
    }
}
Qui trovate i sorgenti dell'esempio creati con MonoDevelop 5.9: Download esempio

Purtroppo ho notato però che l'editor di MonoDevelop 5.9 ha ancora qualche problema nel riconoscere la sintassi C# 6.0 ma non sono cose gravi.
Invece gli "Exception filters" proprio non funzionano, se de-commentate il codice del mio esempio il compilatore vi da errore.

Che versione di Mono è installata?


Questo è un comando che potete lanciare tramite shell Linux, per vedere i dettagli della versione che avete installato:

mono --version

mercoledì 27 marzo 2013

The operation cannot be completed. “Puntatore non valido”

Se per caso vi dovesse capitare con Visual Studio 2012 di ricevere il messaggio: The operation cannot be completed. “Puntatore non valido”, quando state tentando di visualizzare un file di risorse .resx, per ripristinarlo, vi basta aprire il file incriminato con un editor di testo e rimuovere tutti gli elementi “data”, dell’xml che contengono l’attributo type="System.Resources.ResXNullRef, System.Windows.Forms".
Es. va eliminato:
<data name="lblLavoroSuLinea.Image" type="System.Resources.ResXNullRef, System.Windows.Forms">
    <value />
</data>

venerdì 27 gennaio 2012

String format .NET semplificato e naturale

Molte volte ci troviamo a dover inserire delle stringhe in una stringa più grande (di solito una frase, per notificare un messaggio all’utente dell’applicazione).
Per fare ciò usiamo il metodo “String.Format()” che accetta in input la stringa da formattare, e un array contenete le altre stringhe da inserire, al posto di segna posti speciali, costruiti con la regola: {indice dell’array}.
Es.:
MessageBox.Show(String.Format("Errore numero {0}, l'utente {1}, non ha i permessi di lettura del file
 {2}, inoltre {1}, non appartiene al ruolo {3}", new String[]{"123", "Mario", "file.txt", "admin"}));
Di solito la scrittura di questo codice avviene nella seguente maniera:
  1. Si scrive: MessageBox.Show(
  2. Si pensa al messaggio e si inizia a scriverlo: "Errore numero …
  3. Ci si accorge che il messaggio dovrà contenere dei pezzi di stringa all’interno della stringa principale.
  4. Si aggiungono i segna posto per i pezzi di stringa: numero {0}, l'utente {1}, non
  5. Completata la frase, ci si posiziona all’inizio della frase stessa.
  6. Si digita String.Format(
  7. Si va alla fine della frase e si chiude la parentesi )
Come si vede a lungo andare si perde molto tempo a compiere tale operazione e non è del tutto naturale, perché ci impegna a cercare l’inizio della frase scritta per aggiungere un pezzo di codice e a tornare alla fine di essa, per chiudere la parentesi.
Per risparmiare tempo e trovare più naturalezza nella scrittura, ho implementato la seguente classe per estendere la classe System.String:
namespace System
{
    /// <summary>
    /// Estensioni per le classi stringa
    /// </summary>
    public static class StringEx
    {
        /// <summary>
        /// Formatta la stringa
        /// </summary>
        /// <param name="pValue">Stringa</param>
        /// <param name="args">Parametri</param>
        /// <returns>Stringa formattata</returns>
        public static string Formatting(this String pValue, params object[] args)
        {
            return String.Format(pValue, args);
        }

        /// <summary>
        /// Formatta la stringa
        /// </summary>
        /// <param name="pValue">Stringa</param>
        /// <param name="format">Format provider</param>
        /// <param name="args">Parametri</param>
        /// <returns>Stringa formattata</returns>
        public static string Formatting(this String pValue, IFormatProvider format, params object[] args)
        {
            return String.Format(format, pValue, args);
        }
    }
}
Ora potere scrivere lo stesso codice dell’esempio di prima in maniera naturale, senza bisogno di tornare a cercare dove inizia la vostra Stringa:
MessageBox.Show("Errore numero {0}, l'utente {1}, non ha i permessi di lettura del file {2}, inoltre {1},
 non appartiene al ruolo {3}".Formatting(new String[] { "123", "Mario", "file.txt", "admin" }));

sabato 14 gennaio 2012

Implementare il Databindings di oggetti

Oggi mi è capitato di dover implementare il databindings di un controllo che ne era sprovvisto (il treenode). Per aggiungere il databindings ad un oggetto TreeNode, come nel mio caso, ma anche per qualsiasi altro oggetto, basta implementare l’interfaccia IBindableComponent.

In questo modo potete usare il Binding su tutte le proprietà del TreeNode; in particolare a me interessava collegare la proprietà “Name” di un mio oggetto alla proprietà “Text” di un TreeNode.

Ecco un esempio in C# dell’implementazione del databindings per la proprietà “Text” di un oggetto TreeNode:
public class TreeNodeBind : TreeNode, IBindableComponent
    {
        //Implementazione dei costruttori base
        public TreeNodeBind()
            : base()
        {
        }

        public TreeNodeBind(string text) 
            : base(text)
        {
        }

        public TreeNodeBind(string text, TreeNode[] children)
            : base(text, children)
        {
        }

        public TreeNodeBind(string text, int imgIndex, int selImgIndex) 
            : base(text, imgIndex, selImgIndex)
        {
        }

        public TreeNodeBind(string text, int imgIndex, int selImgIndex, TreeNode[] children)
            : base(text, imgIndex, selImgIndex, children)
        {
        }

        //Implementazione di IBindableComponent
        #region IBindableComponent Members

        private BindingContext _bindingContext;
        private ControlBindingsCollection _dataBindings;

        [Browsable(false)]
        public BindingContext BindingContext
        {
            get
            {
                if (_bindingContext == null)
                {
                    _bindingContext = new BindingContext();
                }
                return _bindingContext;
            }
            set
            {
                _bindingContext = value;
            }
        }

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public ControlBindingsCollection DataBindings
        {
            get { return _dataBindings ?? (_dataBindings = new ControlBindingsCollection(this)); }
        }

        public ISite Site { get; set; }

        public event EventHandler Disposed;

        public void Dispose()
        {
            if (Disposed != null)
                Disposed(this, EventArgs.Empty);
        }

        #endregion
    }
Ora potete creare ed usare nodi di tipo TreeNodeBind che supportano il Binding:
TreeNodeBind nodoBind = new TreeNodeBind();
nodoBind.DataBindings.Add(new System.Windows.Forms.Binding("Text", oggettoConDati, "Name", true));
tree.Nodes.Add(nodoBind);

lunedì 5 dicembre 2011

Istallazione Windows 8 Developer Preview with developer tools 64bit su VMWare Workstation 8

Per prima cosa scarichiamo l’immagine ISO da qui: Windows 8 Developer Preview with developer tools English, 64-bit (x64)
Avviamo VMware Workstation, e selezioniamo dal menu file, nuova, virtual machine, in questo modo partirà il wizard di creazione.

05-12-2011 11-08-22
Scegliamo tipical e premiamo next.
A questo punto selezioniamo installer disk image file (iso) e selezioniamo il percorso del file dove si trova la nostra immagine scaricata:

05-12-2011 15-56-04
Nella fase successiva selezioniamo Miscrosoft Windows dalla lista dei sistemi operativi e Windows 7 64-bit dalla lista delle versioni:

05-12-2011 15-58-14
Lasciamo libero il product key di windows e scriviamo una nostra password:

05-12-2011 16-00-51b
Diamo un nome alla nostra macchina virtuale e selezioniamo un percorso dove verranno salvati i files:

05-12-2011 16-05-41
Selezioniamo la quantità di memoria del disco rigido virtuale, desiderata (io avendo spazio ho messo 40gb, ma credo bastino 20), e se vogliamo che il disco sia diviso in più files o su uno solo:

05-12-2011 16-06-25
A questo punto rileggiamo se abbiamo impostato tutto correttamente e premiamo Finish per fare partire la macchina virtuale.

05-12-2011 16-07-22

Se è andato tutto bene dovreste vedere partire l’installazione di Windows 8:
05-12-2011 16-08-33
Ad un certo punto però otterrete questo messaggio d’errore:

05-12-2011 16-10-14
Spegnete la macchina virtuale, andate nelle menu delle impostazioni (VM –> Settings), e rimuovete il Floppy dall’elenco dei devices:

05-12-2011 16-16-25
Date OK e riavviate la macchina virtuale.
Ora l’installazione partirà correttamente e arriverete alla finestra di selezione delle opzioni internazionali del sitema operativo.
Come prima opzione lasciamo “Language to install”: English (è anche l’unica selezionabile).
Come “Time and currency format”, possiamo impostare Italiano.
Come “Keyboar or input method”, possiamo impostare Italiano (se abbiamo una tastiera italiana naturalmente).

05-12-2011 16-20-17
Portiamo a termine i vari passaggi successivi come sempre e abbiamo finito.

Conversione di un numero in colonna Excel

Ecco il codice per convertire un numero nell'indice alfanumerico di una colonna Excel:
public static class ExcelFunc
{
    public static string ConvertToLetter(int colIndex)
    {
        string ret = string.Empty;
        var alpha = colIndex/27;
        var remainder = colIndex-(alpha*26);
        if (alpha > 0)
            ret = Char.ConvertFromUtf32(alpha+64);
        if (remainder > 0)
                ret += Char.ConvertFromUtf32(remainder+64);
        return ret;
    }
}

Convertire un click in doubleclick

Utilzzando un controllo di terze parti, mi sono accorto che il suo produttore non aveva implementato l’evento double click in un punto che secondo me era essenziale, allora con qualche riga di codice mi sono trasformato un evento click in double click:
private DateTime mTimeToDoubleC = DateTime.Now;

private void button1_Click(object sender, EventArgs e)
{
    DateTime adesso = DateTime.Now;
    if ((adesso - mTimeToDoubleC) < new TimeSpan(0, 0, 0, 0, SystemInformation.DoubleClickTime))
    {
        //Esegui il metodo per il double click...
    }
    else
    {
        //Esegui il metodo per il click normale...
    }
}
Come si può vedere utilizzando la proprietà SystemInformation.DoubleClickTime ottengo un double click perciso come impostato nel sistema.

Windows Live Mail – Correttore in Italiano

Ecco come fare per aggiungere la correzione ortografica in Italiano a Windows Live Mail.
Requisiti:
aver installato MSOffice con incluso controllo ortografico e grammaticale in Italiano.

Cosa fare:
creare una directory 'prf0010' (notare il codice 0010. Se fosse stato per la lingua tedesca sarebbe dovuta essere 'prf0007', per l'inglese 'prf0009' etc.) in 'C:\Users\\AppData\Local\Microsoft\Windows Live Mail\Proof'
creare la directory '1' dentro prf0010
copiare i file 'MSSP3IT.DLL' e 'MSSP3IT.LEX' presenti di norma in 'C:\Program Files\Common Files\microsoft shared\Proof' dentro 'C:\Users\\AppData\Local\Microsoft\Windows Live Mail\Proof\prf0010\1\'
creare un file di testo in 'prf0010\1\' da rinominare poi 'spell.ini' (notare l'estensione INI) con dentro (senza lasciare righe vuote all'inizio):
Codice:
[Spellchecker]
Engine=MSSP3IT.DLL
Lex=MSSP3IT.LEX
Lang=1040(premere RETURN per creare una nuova linea vuota subito alla fine di '...1040' e salvare il file)
Riassumendo alla fine avrete: in C:\Users\\AppData\Local\Microsoft\Windows Live Mail\Proof\prf0010\1\ i 2 file (DLL e LEX) + il file spell.ini.
Fine.
A questo punto riaprendo WLM e andando alla pagina del correttore ortografico nelle preferenze di WLM vedrete apparire finalmente l'Italiano installato (e anche la spunta su 'controlla ortografia nella lingua corrente di input' per cambiare lingua e vocabolario al volo tramite la Barra delle lingue di Vista funzionerà a dovere).

Evento minimize e forms ridotti a icona nella Tray

Ecco il codice per gestire una form che passa dalla visualizzazione normale alla tray bar e dopo avere fatto doppio click sull’icona ritorna alla posizione iniziale in primo piano:

Come prima cosa aggiungiamo a design il componente “NotifyIcon” e lo chiamiamo “notifyIcon”.
Impostiamo la proprietà visible a false.
Siccome non abbiamo un evento minimized, implementiamo il seguente codice usando l’evento Resize della form:
private void FrmMain_Resize(object sender, EventArgs e)
{
    if (System.Windows.Forms.FormWindowState.Minimized == WindowState)
    {
        this.Hide();
        notifyIcon.Visible = true;
    }
}
Ora implementiamo il seguente codice per l’evento DoubleClick sulla notifyIcon e il gioco è fatto:
private void notifyIcon_DoubleClick(object sender, EventArgs e)
{
    this.Show();
    this.WindowState = FormWindowState.Normal;
    notifyIcon.Visible = false;
}

Localizzare i mesi dell'anno

Per ottenere i nomi dei mesi dell'anno localizzati in base alla lingua corrente del vostro programma potete usare questa semplice funzione:
//C#
int iMonth = 1; //Numero intero che corrisponde al mese da localizzare (in questo caso Gennaio)
string month = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(iMonth);
'VB.NET
Dim iMonth As Integer = 1
'Numero intero che corrisponde al mese da localizzare (in questo caso Gennaio)
Dim month As String = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(iMonth)

venerdì 2 dicembre 2011

Impedire l'esecuzione del programma .NET ad un utente che non sia amministratore

Un esigenza molto comune per esempio, se si vuole fare una console di amministazione di un servizio è quella che un applicazione o un metodo siano eseguiti solo se l'utente appartiene ad un determinato gruppo che ha i permessi necessari, per esempio ad accedere ad una determinata risorsa. Nel seguente esempio scritto in C# se l'utente che esegue il thread non è un amministratore allora il metodo genera un eccezione e si può chiudere l'applicazione.

Come prima cosa bisogna applicare i criteri principali del dominio applicazione corrente a WindowsPrincipal, altrimenti una richiesta di autorizzazione principale avrà esito negativo.
AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
Ora abbiamo bisogno di sapere quale è l'utente che sta eseguendo il thread corrente.
//Estrae l'identità dell'utente del thread corrente
WindowsIdentity wi = (WindowsIdentity)System.Threading.Thread.CurrentPrincipal.Identity;
                
//Estrae il nome utente da suo sid
IdentityReference mYaccount = wi.User.Translate(typeof(NTAccount));
//Visualizza il nome utente estratto da suo sid
MessageBox.Show("Utente:" + mYaccount.Value);
Adesso dobbiamo ricavare il gruppo administrator da assegnare alla funzione di controllo. Per aiutarvi potete visualizzare i nomi dei gruppi a cui l'utente del thread appartiene così:
StringBuilder sbMsg = new StringBuilder();
foreach (IdentityReference sidRef in wi.Groups)
{
    IdentityReference account = sidRef.Translate(typeof(NTAccount));
    sbMsg.AppendLine(account.Value);
}
MessageBox.Show(sbMsg.ToString());
Ora per impedire all'applicazione di partire se non siamo amministratori, usiamo le seguenti istruzioni:
try
{
    PrincipalPermission permessi = 
        new PrincipalPermission(mYaccount.Value, "BUILTIN\\Administrators");
                
    permessi.Demand();
}
catch (SecurityException ex)
{
   MessageBox.Show(ex);
   //Esci dall'applicazione
}

Comprimere e decomprimere con .Net 2.0

Ecco come usare gli oggetti per la compressione messi a disposizione dal Framework .NET 2.0
//C#
using System.IO;
using System.IO.Compression;


public static class Compressor
{
 public static byte[] Compress(byte[] data)
 {
  MemoryStream output = new MemoryStream();
  GZipStream gzip = new GZipStream(output, CompressionMode.Compress, true);
  gzip.Write(data, 0, data.Length);
  gzip.Close();
  return output.ToArray();
 }


 public static byte[] Decompress(byte[] data)
 {
  MemoryStream input = new MemoryStream();
  input.Write(data, 0, data.Length);
  input.Position = 0;
  GZipStream gzip = new GZipStream(input, CompressionMode.Decompress, true);
  MemoryStream output = new MemoryStream();
  byte[] buff = new byte[64];
  int read = -1;
  read = gzip.Read(buff, 0, buff.Length);
  

  while (read > 0)
  {
   output.Write(buff, 0, read);
   read = gzip.Read(buff, 0, buff.Length);
  }
  

  gzip.Close();
  return output.ToArray();
 }
}
'VB
Imports System.IO
Imports System.IO.Compression


Public Class Compressor


 Public Shared Function Compress(ByVal data As Byte()) As Byte()
  Dim output As MemoryStream = New MemoryStream
  Dim gzip As GZipStream = New GZipStream(output, CompressionMode.Compress, True)
  gzip.Write(data, 0, data.Length)
  gzip.Close()
  Return output.ToArray
 End Function


 Public Shared Function Decompress(ByVal data As Byte()) As Byte()
  Dim input As MemoryStream = New MemoryStream
  input.Write(data, 0, data.Length)
  input.Position = 0
  Dim gzip As GZipStream = New GZipStream(input, CompressionMode.Decompress, True)
  Dim output As MemoryStream = New MemoryStream
  Dim buff(64) As Byte
  Dim read As Integer = -1
  read = gzip.Read(buff, 0, buff.Length)


  While read > 0
   output.Write(buff, 0, read)
   read = gzip.Read(buff, 0, buff.Length)
  End While


  gzip.Close()
  Return output.ToArray
 End Function


End Class

Icone dei componenti nella Toolbox .NET

Per aggiungere un icona ad un nuovo componente creato con Visual Studio in modo che si veda nella toolbox si può usare uno dei seguenti metodi:
//C#
//Specifica la bitmap associata al tipo Button.
[ToolboxBitmap(typeof(Button))]
class MyControl1 : UserControl
{
}


//Specifica un bitmap file.
[ToolboxBitmap(@"C:\Documents and Settings\Rudy\Documenti\Immagini\myImage.bmp")]
class MyControl2 : UserControl
{
}


//Specifica un tipo che indica l'assembly in cui cercare e il nome del immagine nelle risorse.
[ToolboxBitmap(typeof(MyControl), "MioControlloBitmap")]
class MyControl : UserControl
{
}
'VB
'Specifica la bitmap associata al tipo Button.
 _
Class MyControl1
    Inherits UserControl
End Class


'Specifica un bitmap file.
 _
Class MyControl2
    Inherits UserControl
End Class


'Specifica un tipo che indica l'assembly in cui cercare e il nome del immagine nelle risorse.
 _
Class MyControl
    Inherits UserControl
End Class
Va ricordato che l'immagine deve essere una bitmap a 16x16 o 32x32, inoltre se usate il primo metodo l'immagine nelle risorse deve chiamarsi "Namespace.NomeClasse.bmp" mentre se usate l'ultimo "Namespace.MioControlloBitmap"

Percorso del file eseguibile di un programma .NET

Per ottenere il percorso del file eseguibile da cui è partita l'applicazione, il namespace System.Windows.Forms ci mette a disposizione il metodo statico Application.StartupPath.
Tuttavia se non vogliamo o non possiamo referenziare System.Windows.Forms, ad esempio, per ottenere il percorso in funzione di una dll referenziata nel progetto, allora possiamo usare il seguente metodo:
AppDomain.CurrentDomain.SetupInformation.ApplicationBase
Prestate molta attenzione se volete aprire un file che si trova nella stessa cartella dell'eseguibile, è buona norma che passiate al metodo il percorso e il nome del file Es.: File.Open(@"C:\Progetti\MiaApplicazione\test.txt"). Se usate solamente il nome file Es.: File.Open(@"test.txt") e per caso in precedenza avete usato una OpenFileDialog o SaveFileDialog per aprire o salvare un file il percorso in cui verrà cercato il vostro file text.txt sarà equivalente all'ultimo selezionato tramite questi controlli.

P.S: anche System.Environment.CurrentDirectory soffre dello stesso problema.

Lettura e scrittura con MemoryStream .NET

Poichè ogni volta che devo usare un MemoryStream devo sempre ricordarmi come funzionano gli stream e le operazioni di lettura e scrittura meglio postare questo pezzetto di codice che può essere utile:
//C#
System.IO.MemoryStream ms = new System.IO.MemoryStream();
Byte[] by = System.Text.Encoding.UTF8.GetBytes("Mio testo");
ms.Write(by, 0, by.Length);
ms.Position = 0;
Byte[] buffer = new byte[by.Length];
ms.Read(buffer, 0, buffer.Length);
string sTesto = System.Text.Encoding.UTF8.GetString(buffer);
'VB
Dim ms As System.IO.MemoryStream = New System.IO.MemoryStream
Dim by As Byte() = System.Text.Encoding.UTF8.GetBytes("Mio testo")
ms.Write(by, 0, by.Length)
ms.Position = 0
Dim buffer(by.Length) As Byte
ms.Read(buffer, 0, buffer.Length)
Dim sTesto As String = System.Text.Encoding.UTF8.GetString(buffer)

Singola istanza di un applicazione C#

Per essere sicuri si eseguire una singola istanza di un applicazione C# potete scrivere il seguente codice:
//C#
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Threading;

namespace ProvaCSharp
{
 static class Program
 {
  private static Mutex mutex;

  ///
  /// The main entry point for the application.
  /// 
  [STAThread]
  static void Main()
  {
   mutex = new Mutex( true, Application.ProductName );
   if (mutex.WaitOne(0, false))
   {
    Application.Run(new Form1());
   }
   else
   {
    MessageBox.Show(Application.ProductName + " è già in esecuzione");
   }
  }
 }
}

Modificare lo stato di un controllo da un operazione asincrona .NET

Quante volte avete avuto la necessità di aggiornare un controllo che si trova su una form istanziata dal thread principale dell'applicazione, da un altro thread che sta seguendo un operazione asincrona? Ecco come evitare errori di cross thread e non duplicare il codice:
//C#
private delegate void InvokeMiaFunzione();
private InvokeMiaFunzione mInvokeMiaFunzione;

private void MiaFunzione()
{
 if (this.InvokeRequired)
 {
  this.Invoke(mInvokeMiaFunzione);
 }
 else
 {
  // Qui si può modificare lo stato del controllo della form senza incorrere in nessun problema
 }
}

private void CostruttoreDellaClasse()
{
 mInvokeMiaFunzione = new InvokeMiaFunzione(MiaFunzione);
}

//Chiamata da un processo asincrono
private void ProcessoAsincrono()
{
 MiaFunzione();
}

//Chiamata da un processo sincrono
private void ProcessoSincrono()
{
 MiaFunzione();
}
'VB
Private Delegate Sub InvokeMiaFunzione()
Private mInvokeMiaFunzione As InvokeMiaFunzione

Private Sub MiaFunzione()
    If Me.InvokeRequired Then
        Me.Invoke(mInvokeMiaFunzione)
    Else
        'Qui si può modificare lo stato del controllo della form senza incorrere in nessun problema
    End If
End Sub

Private Sub CostruttoreDellaClasse()
    mInvokeMiaFunzione = AddressOf MiaFunzione
End Sub

'Chiamata da un processo asincrono
Private Sub ProcessoAsincrono()
    MiaFunzione()
End Sub

'Chiamata da un processo sincrono
Private Sub ProcessoSincrono()
    MiaFunzione()
End Sub

I files di configurazione di un applicazione .NET

Segnalo questo link, al mio primo articolo, relativo ai files di configurazione delle applicazioni .NET, è stato scritto qualche anno fa, ma a oggi è ancora valido.

giovedì 1 dicembre 2011

Ottenere l'IP reale anche con un proxy

RealIP = Request.ServerVariables["REMOTE_ADDR"].ToString();
ClientIP = Request.ServerVariables["HTTP_CLIENT-IP"];

if(ClientIP!="")
{
    RealIP = ClientIP;
}
else
{
    Forwarded = Request.ServerVariables["HTTP_X_Forwarded-For"];
}

if (Forwarded != "")
    RealIP = Forwaded;

Verificare se SqlServer è installato

Per determinare via codice se sul vostro computer sia installato SqlServer, basta controllare la seguente chiave di registro:
//C#
public static bool IsSqlServerInstalled()
{
    bool isInstalled = false;
    RegistryKey regSql = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\MSSQLServer\MSSQLServer\CurrentVersion");
    if (regSql.GetValue("CurrentVersion") != null)
    {
        isInstalled = true;
    }
    return isInstalled;
}
'VB
Public Shared Function IsSqlServerInstalled() As Boolean
    Dim isInstalled As Boolean = False

    Dim regSql As RegistryKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\MSSQLServer\MSSQLServer\CurrentVersion")

    If regSql.GetValue("CurrentVersion") IsNot Nothing Then
        isInstalled = True
    End If

    Return isInstalled
End Function