mailarch - vytvoření a odeslání zip archívu emailem

Petr Wiedemann, 29. květen 2010

Mailarch je program pro příkazový řádek, který umí vytvořit zip archív a odeslat jej emailem. Pro spuštění potřebuje nainstalovaný Microsoft .NET Framework, minimálně ve verzi 3.5.

V programu jsou použity následující komponenty:

  • knihovna DotNetZip pro kompresi do ZIP formátu
  • parser NDesk.Options pro zpracování vstupních parametrů programu

Povinné parametry pro spuštění programu

  • -l, --list
    Textový soubor v kódování UTF-8 se seznamem soborů nebo adresářů, které chcete přidat do zip archívu. Každý záznam musí být na samostatném řádku. Komentáře v soboru musí začínat znakem „#”.
  • -s, --smtp
    Adresa SMTP serveru, přes který bude zpráva doručena.
  • -f, --from
    Adresa odesílatele.
  • -t, --to
    Adresa příjemce.
  • -a, --archive
    Jméno archívu, který má být vytvořen. Tento soubor bude uložen v příloze zprávy a zadané jméno bude použito i pro předmět emailu.

Volitelné parametry pro spuštění programu

  • -p, --password
    Heslo, které bude použito pro vytvoření archívu.
  • -ssl
    Třída SmtpClient využije SSL pro odeslání dat. Podmínkou je, aby SMTP server podporoval šifrované spojení.
  • -dc
    Třída SmtpClient použije uživatelské jméno a heslo uživatele, pod kterým je program spuštěn, pro přihlášení k SMTP serveru.

Příklad použití:
mailarch.exe -l pokus.txt -s mail.example.com -f from@example.com -t to@example.com -a pokus.zip

Soubory ke stažení

Zdrojový kód

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net.Mail;
using System.Globalization;
using Ionic.Zip;

namespace mailarch
{
    class MailArch
    {
        private AppArguments args;
        private StringBuilder messages = new StringBuilder();
        private string temp_file;

        public MailArch(AppArguments app_arg)
        {
            this.args = app_arg;
        }

        public void Start()
        {
            FileStream fs = null;

            // Otevreni seznamu souboru a adresaru.
            try
            {
                using (StreamReader zip_files = new StreamReader(args.file_list))
                {
                    using (ZipFile zip = new ZipFile())
                    {
                        // Znakova sada konzole.
                        int oem_cp = CultureInfo.CurrentCulture.TextInfo.OEMCodePage;
                        zip.ProvisionalAlternateEncoding = System.Text.Encoding.GetEncoding(oem_cp);

                        // Uroven komprese.
                        zip.CompressionLevel = Ionic.Zlib.CompressionLevel.BestCompression;

                        // Ulozeni hesla pro archiv.
                        if (!String.IsNullOrEmpty(args.password))
                            zip.Password = args.password;

                        // Zpracovani vsech radku ze souboru.
                        string line;
                        while ((line = zip_files.ReadLine()) != null)
                        {
                            line = line.Trim();

                            // Preskoceni prazdnych radek nebo komentaru.
                            if (line.Length == 0 || line.StartsWith("#"))
                                continue;

                            // Kontrola, jestli je zaznam soubor nebo adresar.
                            if (File.Exists(line))
                            {
                                DisplayMessage("Zipping file " + line);
                                zip.AddFile(line);
                            }
                            else if (Directory.Exists(line))
                            {
                                string path = Path.GetFullPath(line);
                                DisplayMessage("Zipping directory " + path);
                                zip.AddDirectory(line, path);
                            }
                            else
                            {
                                DisplayMessage("List entry " + line + " not found");
                            }
                        }

                        // Vytvoreni archivu v docasnem souboru.
                        temp_file = Path.GetTempFileName();
                        zip.Save(temp_file);
                    }
                }

                // Odeslani souboru v priloze.
                DisplayMessage("Creating new message");
                MailMessage message = new MailMessage(args.sender, args.recipient);
                message.Subject = args.archive;

                DisplayMessage("Adding attachment " + args.archive);
                fs = new FileStream(temp_file, FileMode.Open, FileAccess.Read);
                message.Attachments.Add(new Attachment(fs,
                    args.archive,
                    System.Net.Mime.MediaTypeNames.Application.Octet));

                message.Body = messages.ToString();

                DisplayMessage("Sending message");
                SmtpClient client = new SmtpClient(args.smtp_server);
                client.DeliveryMethod = SmtpDeliveryMethod.Network;
                client.UseDefaultCredentials = args.default_credentials;
                client.EnableSsl = args.ssl;
                client.Send(message);

                fs.Close();
                fs = null;

                DisplayMessage("Message sent");
            }
            catch (Exception e)
            {
                DisplayMessage(e.Message);
            }
            finally
            {
                try
                {
                    if (fs != null)
                        fs.Close();

                    // Smazani docasneho souboru.
                    if (!String.IsNullOrEmpty(temp_file) && File.Exists(temp_file))
                        File.Delete(temp_file);
                }
                catch
                {
                }
            }
        }

        private void DisplayMessage(string message)
        {
            string time = DateTime.Now.ToString();

            messages.AppendLine(time + ": " + message);
            Console.WriteLine(time + ": " + message);
        }
    }
}