lunedì 10 agosto 2026

C# Windows Forms: visualizzare una finestra di dialogo per salvare un file

In questo esempio, realizzato in C# e nell'ambiente Windows Forms, vedremo come visualizzare una finestra di dialogo che consenta all'utente di scegliere il percorso e il nome del file da salvare.

A tale scopo possiamo utilizzare la classe SaveFileDialog, disponibile nel framework .NET.

Di seguito viene riportato un semplice esempio di utilizzo.

C#

using (SaveFileDialog sfdSalvaFile = new SaveFileDialog())

{

    //Filtro solo per il formato pdf o docx formato di salvataggio

    sfdSalvaFile.Filter = "Pdf (*.Pdf)|*.Pdf|Word (*.docx)|*.docx";

    sfdSalvaFile.FilterIndex = 1;

 

    //Imposto di default il nome file

    sfdSalvaFile.FileName = "mioFile.pdf";

 

    //Imposto la cartella iniziale da visualizzare nella finestra

    sfdSalvaFile.InitialDirectory = @"C:\";

    byte[] dati = GetDati();  

    //Visualizzo la finestra di salvataggio, se è ok salvo

    if (sfdSalvaFile.ShowDialog() == DialogResult.OK)

    {

        string percorso = sfdSalvaFile.FileName;

                   

        File.WriteAllBytes(percorso , dati);

                   

    }

}


domenica 9 agosto 2026

Come leggere e importare file VCF in C# senza librerie di terze parti

In questo esempio, realizzato in  C# per l'ambiente Windows Forms , vedremo come estrarre le informazioni contenute nei file di tipo  VCF (vCard) , utilizzati per rappresentare e scambiare i dati dei contatti, anche tramite applicazioni come Outlook.

L'obiettivo è leggere i file VCF presenti all'interno di una cartella, estrarre alcune informazioni del contatto, come nome, indirizzo e-mail e note , e visualizzarle successivamente all'interno di un controllo `DataGridView`.

Il tutto viene realizzato tramite una classe personalizzata, senza utilizzare librerie di terze parti.

La classe `DtoContattiVcf` rappresenta il singolo contatto e contiene le proprietà `Nome`, `Email` e `Note`.

Il metodo `Contatti()` si occupa invece di individuare tutti i file `.vcf` presenti nella cartella specificata e di creare un oggetto `DtoContattiVcf` per ciascun file.



C#

    public class DtoContattiVcf

    {

        public string Nome { get; set; } = string.Empty;

 

        public string Email { get; set; } = string.Empty;

 

        public string Note { get; set; } = string.Empty;

 

        public DtoContattiVcf()

        {

        }

 

        public DtoContattiVcf(string percorsoNomeFile)

        {

            if (!File.Exists(percorsoNomeFile))

            {

                return;

            }

 

            string[] lines = File.ReadAllLines(percorsoNomeFile);

 

            foreach (string line in lines)

            {

                if (line.StartsWith("FN:", StringComparison.OrdinalIgnoreCase))

                {

                    Nome = line.Substring(3).Trim();

                }

                else if (line.StartsWith("EMAIL;", StringComparison.OrdinalIgnoreCase))

                {

                    int posizione = line.IndexOf(':');

 

                    if (posizione >= 0)

                    {

                        Email = line.Substring(posizione + 1).Trim();

                    }

                }

                else if (line.StartsWith("NOTE;", StringComparison.OrdinalIgnoreCase))

                {

                    int posizione = line.IndexOf(':');

 

                    if (posizione >= 0)

                    {

                        Note = line.Substring(posizione + 1).Trim();

                    }

                }

            }

        }

 

        public List<DtoContattiVcf> Contatti(string percorsoFilesVcf)

        {

            List<DtoContattiVcf> returnContatti = new List<DtoContattiVcf>();

 

            if (!Directory.Exists(percorsoFilesVcf))

            {

                return returnContatti;

            }

 

            foreach (string fileVcf in Directory.EnumerateFiles(

                percorsoFilesVcf,

                "*.vcf",

                SearchOption.TopDirectoryOnly))

            {

                try

                {

                    DtoContattiVcf contatto = new DtoContattiVcf(fileVcf);

 

                    returnContatti.Add(contatto);

                }

                catch (IOException)

                {

                    

                    continue;

                }

                catch (UnauthorizedAccessException)

                {

                   

                    continue;

                }

            }

 

            return returnContatti;

        }

    }

 



Una volta definita la classe, possiamo utilizzarla all'interno del codice di una form Windows Forms.

Nell'esempio seguente, il percorso della cartella contenente i file VCF viene recuperato da una `TextBox`. I contatti vengono quindi letti e associati al controllo `DataGridView`.


C#


private void BtnRilevaVCF_Click(object sender, EventArgs e)
{
    Cursor.Current = Cursors.WaitCursor;
    try
    {
        string percorso = TxtPercorsoVCF.Text.Trim();

        if (string.IsNullOrWhiteSpace(percorso))
        {
            Utility.MessaggioInfo(
                "Selezionare la cartella contenente i file VCF.");

            return;
        }

        if (!Directory.Exists(percorso))
        {
            Utility.MessaggioInfo(
                "La cartella selezionata non esiste.");

            return;
        }

        DtoContattiVcf contatti = new DtoContattiVcf();

        List<DtoContattiVcf> listaContatti = contatti.Contatti(percorso);

        if (listaContatti.Count == 0)
        {
            Utility.MessaggioInfo(
                "Nessun file VCF presente nella cartella selezionata.");

            return;
        }

        dtgDatiVcf.DataSource = listaContatti;


    }
    catch (Exception ex)
    {
        Utility.MessaggioErrore(ex.Message);
    }
    finally
    {
        Cursor.Current = Cursors.Default;

    }
}

sabato 8 agosto 2026

Programma Toro, strumento per le funzionalità di Windows

 

Programma Toro

In questi giorni è possibile scaricare una versione stabile di Toro, un software che ho realizzato per rilevare informazioni sul sistema operativo Windows e offrire diverse funzionalità.

Il programma fornisce una scheda informativa dettagliata sul sistema operativo Windows, oltre a diverse funzioni utili.

È possibile scaricare il programma e consultare il relativo codice sorgente, sviluppato in C# utilizzando Windows Forms, a questo indirizzo:https://github.com/Emanuele2025/Toro


venerdì 7 agosto 2026

Come leggere le informazioni della firma digitale di un PDF in C# senza librerie esterne

In questo esempio, scritto in C# per applicazioni Windows Forms, vedremo come estrarre alcune informazioni dalle firme digitali presenti in un file PDF, senza utilizzare librerie di terze parti.


Dopo aver selezionato il file PDF, il codice verifica la presenza di una o più firme digitali. Se ne trova almeno una, legge il contenuto del certificato associato a ciascuna firma ed estrae alcune informazioni, tra cui:


il soggetto del certificato;

l'autorità che lo ha emesso;

il periodo di validità;

l'algoritmo di firma;

il numero di serie del certificato.


L'esempio mostra una delle possibili tecniche per leggere le informazioni dei certificati associati alle firme digitali presenti in un file PDF. Poiché la struttura interna di un PDF può variare (ad esempio in presenza di oggetti compressi o differenti modalità di memorizzazione della firma), questo approccio potrebbe non funzionare con tutti i documenti. L'obiettivo dell'articolo è illustrare il funzionamento della tecnica, senza realizzare un parser completo del formato PDF.



Di seguito è riportata la funzione che converte una stringa esadecimale in un array di byte.

C#

byte[] HexStringToBytes(string hex)

{

    if (hex.Length % 2 != 0)

        throw new ArgumentException("Stringa esadecimale non valida.");

 

    byte[] bytes = new byte[hex.Length / 2];

    for (int i = 0; i < bytes.Length; i++)

        bytes[i] = Convert.ToByte(hex.Substring(i * 2, 2), 16);

 

    return bytes;

}


Di seguito è riportato il codice dell'evento Click del pulsante, che individua le firme digitali presenti nel PDF, legge il certificato associato a ciascuna di esse ed estrae le principali informazioni.



C#

private void BtnLeggiCertificatiPdf_Click(object sender, EventArgs e)

 {

     try

     {

         dtgCertificatiFilePdf.DataSource = null;

         //Verifico se è stato selezionato il file

         if (string.IsNullOrEmpty(TxtPercorsoCartella.Text.Trim()))

         {

             Utility.MessaggioInfo("Selezionare un file PDF.");

             return;

         }

         List<DtoFirmaDigitale> certificatiTrovati = new List<DtoFirmaDigitale>();

         string pdfPath = @TxtPercorsoCartella.Text.Trim();

         byte[] pdfBytes = File.ReadAllBytes(pdfPath);

         string pdfText = Encoding.ASCII.GetString(pdfBytes);

 

         // Trova TUTTI i blocchi /Contents <...>

         MatchCollection matches = Regex.Matches(pdfText, @"/Contents\s*<([0-9A-Fa-f]+)>");

 

         if (matches.Count == 0)

         {

             Utility.MessaggioInfo("Nessuna firma digitale trovata nel PDF.");

             return;

         }

 

              

 

         int firmaIndex = 1;

         foreach (Match match in matches)

         {

             try

             {

                 byte[] signatureBytes = HexStringToBytes(match.Groups[1].Value);

 

                 SignedCms cms = new SignedCms();

                 cms.Decode(signatureBytes);

                      

                 foreach (var firma in cms.SignerInfos)

                 {

                     X509Certificate2 cert = firma.Certificate;

                     DtoFirmaDigitale dtoCertificato = new DtoFirmaDigitale()

                     {

                          Oggetto = cert.Subject,

                          EmessoDa = cert.Issuer,

                          DataInizio = cert.NotBefore,

                          DataFine = cert.NotAfter,

                          Algoritmo = cert.SignatureAlgorithm.FriendlyName,

                          Seriale = cert.SerialNumber

 

 

                     };

 

                         

                     certificatiTrovati.Add(dtoCertificato);

                 }

             }

             catch (Exception ex)

             {

                 Utility.MessaggioErrore($"Errore nella lettura della firma #{firmaIndex}: {ex.Message}\n");

             }

 

             firmaIndex++;

         }

 

         dtgCertificatiFilePdf.DataSource = certificatiTrovati;

 

 

     }

     catch (Exception ex)

     {

         Utility.MessaggioErrore(ex.Message);

 

     }

 }