¿Cómo enviar más de 255 letras?

Iniciado por Meta, 26 Diciembre 2021, 02:39 AM

0 Miembros y 1 Visitante están viendo este tema.

Meta

Buenas:

Quiero enviar un email en modo consola que supere los 255 caracteres tal como se hace en cualquier navegador.

¿Es posible hacerlo?

Aquí dejo un ejemplo con  Ggail.

// Activar / desactivar Acceso de aplicaciones poco seguras en Google.
// https://myaccount.google.com/lesssecureapps

using System;
using System.IO;
using System.Net;
using System.Net.Mail;
using System.Text;

namespace Enviar_email_Consola_07
{
    internal class Program
    {
        static void Main(string[] args)
        {
            #region Configuración ventana.
            // Título de la ventana.
            Console.Title = "Gestor correo electrónico";

            // Tamaño de la ventana, x, y.
            Console.SetWindowSize(80, 25);

            // Color de fondo.
            Console.BackgroundColor = ConsoleColor.Black;

            // Color de las letras.
            Console.ForegroundColor = ConsoleColor.Gray;

            // Limpiar pantalla y dejarlo todo en color de fondo.
            Console.Clear();

            // Visible el cursor.
            Console.CursorVisible = true;
            #endregion

            // Variables.
            string usuario, contraseña, destinatario, asunto, mensaje;

            // Título del programa.
            Console.WriteLine("\t\t----------------------------------------");
            Console.WriteLine("\t\t\tEnviar Correo Electrónico");
            Console.WriteLine("\t\t----------------------------------------");

            try
            {
                Console.WriteLine("\n");
                Console.ForegroundColor = ConsoleColor.Cyan;
                Console.Write("\t\tTu correo electrónico: ");
                Console.ForegroundColor = ConsoleColor.Gray;
                usuario = Console.ReadLine();
                Console.WriteLine();
                Console.ForegroundColor = ConsoleColor.Cyan;
                Console.Write("\t\tIntroducir contraseña: ");
                Console.ForegroundColor = ConsoleColor.Gray;
                contraseña = LeerPassword();
                Console.WriteLine();
                Console.ForegroundColor = ConsoleColor.Cyan;
                Console.Write("\t\tDestinatario: ");
                Console.ForegroundColor = ConsoleColor.Gray;
                destinatario = Console.ReadLine();
                Console.WriteLine();
                Console.ForegroundColor = ConsoleColor.Cyan;
                Console.Write("\t\tAsunto: ");
                Console.ForegroundColor = ConsoleColor.Gray;
                asunto = Console.ReadLine();
                Console.WriteLine();

                //----------------------------------------------
                byte[] bytes = new byte[2000]; // Nuevo tamanho máximo.
                Stream inputStream = Console.OpenStandardInput(bytes.Length);
                Console.SetIn(new StreamReader(inputStream));
                //----------------------------------------------

                Console.ForegroundColor = ConsoleColor.Cyan;
                Console.Write("\t\tMensaje: ");
                Console.ForegroundColor = ConsoleColor.Gray;
                mensaje = Console.ReadLine();
                Console.WriteLine();

                MailMessage correo = new MailMessage(usuario, destinatario, asunto, mensaje);

                SmtpClient servidor = new SmtpClient("smtp.gmail.com")
                {
                    Port = 587
                };
                NetworkCredential credenciales = new NetworkCredential(usuario, contraseña);
                servidor.Credentials = credenciales;
                servidor.EnableSsl = true;

                Console.WriteLine();
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine("\t\tEnviando correo...");
                servidor.Send(correo);
                Console.WriteLine();
                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine("\t\tCorreo enviado satisfactoriamente.");
                correo.Dispose();
                Console.CursorVisible = false;
                Console.ReadKey();
            }
            catch (Exception ex)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("ERROR: \n");
                Console.WriteLine("\t\t" + ex.Message);
                Console.WriteLine();
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine("\t\tNo se ha enviado el correo.");
                Console.ReadKey();
            }

        }

        // A la hora de introducir la contraseña, se sustituye por asterístos (*) en pantalla.
        public static string LeerPassword()
        {
            ConsoleKeyInfo cki;
            StringBuilder sb = new StringBuilder();
            int contador = 0;

            do
            {
                cki = Console.ReadKey(true);
                if (cki.Key != ConsoleKey.Enter)
                {

                    sb.Append(cki.KeyChar);
                    if (contador < 4)
                    {
                        Console.Write("*");
                    }
                    contador++;
                }

                else
                {
                    break;
                }

            } while (true);
            Console.WriteLine();
            return sb.ToString();
        }
    }
}


Felices fiestas camaradas.
Tutoriales Electrónica y PIC: http://electronica-pic.blogspot.com/

Mohicano

#1
La función Console.ReadLine() tiene implícito ese límite de 256 caracteres (254 sin CarriageReturn + LineFeed). Ese es el límite del tamaño del búfer del que hace uso al adquirir el flujo de entrada estándar o std-in especificado en la función Console.OpenStandardInput.

Puedes incrementar dicho límite a 32.767(-2) caracteres de la siguiente manera:
Código (csharp) [Seleccionar]
Console.SetIn(new StreamReader(Console.OpenStandardInput(Int16.MaxValue), Console.InputEncoding, false, Int16.MaxValue));

O a 65.535(-2) caracteres si lo prefieres:
Código (csharp) [Seleccionar]
Console.SetIn(new StreamReader(Console.OpenStandardInput(UInt16.MaxValue), Console.InputEncoding, false, UInt16.MaxValue));

El límite máximo teórico es Int32.MaxValue ( Maximum length of byte[]? + <gcAllowVeryLargeObjects> element ), pero llegar a esos extremos para este tipo de escenario lo veo totalmente innecesario.

La llamada al método Console.SetIn() puedes acomodarlo de forma reutilizable como en el siguiente ejemplo de clase, y simplemente llamar al método SetInBufferSize() cuando sea necesario:

Código (vbnet) [Seleccionar]
Public NotInheritable Class ConsoleUtil

#Region " Constructors "

   ''' ----------------------------------------------------------------------------------------------------
   ''' <summary>
   ''' Prevents a default instance of the <see cref="ConsoleUtil"/> class from being created.
   ''' </summary>
   ''' ----------------------------------------------------------------------------------------------------
   <DebuggerNonUserCode>
   Private Sub New()
   End Sub

#End Region

#Region " Private Members "

   ''' <summary>
   ''' The underlying standard input stream (stdin) used for <see cref="ConsoleUtil.SetInBufferSize"/> method.
   ''' </summary>
   Private Shared stdIn As StreamReader

#End Region

#Region " Public Methods "

   ''' ----------------------------------------------------------------------------------------------------
   ''' <summary>
   ''' Sets the buffer size of the standard input stream (std-in)
   ''' acquired from the <see cref="System.Console.OpenStandardInput"/> function.
   ''' <para></para>
   ''' So the <see cref="Console.ReadLine()"/> function can benefit from a larger buffer size.
   ''' <para></para>
   ''' Default buffer size is 256.
   ''' </summary>
   ''' ----------------------------------------------------------------------------------------------------
   ''' <param name="bufferSize">
   ''' Minimum value is: 256.
   ''' <para></para>
   ''' Note that the last two characters in the buffer are reserved for
   ''' <see cref="ControlChars.Cr"/> + <see cref="ControlChars.Lf"/>.
   ''' </param>
   ''' ----------------------------------------------------------------------------------------------------
   <DebuggerStepThrough>
   Public Shared Sub SetInBufferSize(bufferSize As Integer)
       If bufferSize < 256 Then
           Throw New ArgumentException(NameOf(bufferSize), message:="Value must be equal or greater than 256.")
       End If

       ConsoleUtil.stdIn?.Close()
       ConsoleUtil.stdIn = New StreamReader(Console.OpenStandardInput(bufferSize), Console.InputEncoding, False, bufferSize)
       Console.SetIn(ConsoleUtil.stdIn)
   End Sub

#End Region

End Class

#End Region


Traducción a C#:
Código (csharp) [Seleccionar]
public sealed class ConsoleUtil {

#region  Constructors

/// ----------------------------------------------------------------------------------------------------
/// <summary>
/// Prevents a default instance of the <see cref="ConsoleUtil"/> class from being created.
/// </summary>
/// ----------------------------------------------------------------------------------------------------
[DebuggerNonUserCode]
private ConsoleUtil() { }

#endregion

#region  Private Members

/// <summary>
/// The underlying standard input stream (stdin) used for <see cref="ConsoleUtil.SetInputBufferSize"/> method.
/// </summary>
private static StreamReader stdIn;

#endregion

#region  Public Methods

/// ----------------------------------------------------------------------------------------------------
/// <summary>
/// Sets the buffer size of the standard input stream (std-in)
/// acquired from the <see cref="System.Console.OpenStandardInput"/> function.
/// <para></para>
/// So the <see cref="Console.ReadLine()"/> function can benefit from a larger buffer size.
/// <para></para>
/// Default buffer size is 256.
/// </summary>
/// ----------------------------------------------------------------------------------------------------
/// <param name="bufferSize">
/// Minimum value is: 256.
/// <para></para>
/// Note that the last two characters in the buffer are reserved for
/// <see cref="ControlChars.Cr"/> + <see cref="ControlChars.Lf"/>.
/// </param>
/// ----------------------------------------------------------------------------------------------------
[DebuggerStepThrough]
public static void SetInBufferSize(int bufferSize) {
if (bufferSize < 256) {
throw new ArgumentException(nameof(bufferSize), message:"Value must be equal or greater than 256.");
}

ConsoleUtil.stdIn?.Close();
ConsoleUtil.stdIn = new StreamReader(Console.OpenStandardInput(bufferSize), Console.InputEncoding, false, bufferSize);
Console.SetIn(ConsoleUtil.stdIn);
}

#endregion

}

#endregion


----------------------

Como alternativa a lo de arriba, en caso de que prefieras no reemplazar el flujo de entrada estándar, puedes definir una función como esta de aquí abajo, que puedes añadir a la clase de arriba, para que sirva como reemplazo de la función Console.ReadLine().

VB.NET:
Código (vbnet) [Seleccionar]
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Reads the next line of characters from the standard input stream.
''' <para></para>
''' This function attempts to be a improved replacement for <see cref="System.Console.ReadLine()"/> function.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <param name="bufferSize">
''' The character limit to read in the next line of characters from the standard input stream.
''' <para></para>
''' Minimum value is: 256.
''' <para></para>
''' Default value is: <see cref="Short.MaxValue"/> (32767).
''' <para></para>
''' Note that the last two characters in the buffer are reserved for
''' <see cref="ControlChars.Cr"/> + <see cref="ControlChars.Lf"/>.
''' </param>
''' ----------------------------------------------------------------------------------------------------
''' <returns>
''' The next line of characters from the input stream,
''' or <see langword="Nothing"/> if no more lines are available.
''' </returns>
''' ----------------------------------------------------------------------------------------------------
<DebuggerStepThrough>
Public Shared Function ReadLine(Optional bufferSize As Integer = Short.MaxValue) As String
   If bufferSize < 256 Then
       Throw New ArgumentException(NameOf(bufferSize), message:="Value must be equal or greater than 256.")
   End If

   Dim inputStream As Stream = Console.OpenStandardInput(bufferSize)
   Dim bytes(bufferSize - 1) As Byte
   Dim outputLength As Integer = inputStream.Read(bytes, 0, bufferSize)
   Dim chars As Char() = Console.InputEncoding.GetChars(bytes, 0, outputLength)

   Return New String(chars).TrimEnd({ControlChars.Cr, ControlChars.Lf})
End Function


Traducción a C#
Código (csharp) [Seleccionar]

/// ----------------------------------------------------------------------------------------------------
/// <summary>
/// Reads the next line of characters from the standard input stream.
/// <para></para>
/// This function attempts to be a improved replacement for <see cref="System.Console.ReadLine()"/> function.
/// </summary>
/// ----------------------------------------------------------------------------------------------------
/// <param name="bufferSize">
/// The character limit to read in the next line of characters from the standard input stream.
/// <para></para>
/// Minimum value is: 256.
/// <para></para>
/// Default value is: <see cref="Short.MaxValue"/> (32767).
/// <para></para>
/// Note that the last two characters in the buffer are reserved for
/// <see cref="ControlChars.Cr"/> + <see cref="ControlChars.Lf"/>.
/// </param>
/// ----------------------------------------------------------------------------------------------------
/// <returns>
/// The next line of characters from the input stream,
/// or <see langword="Nothing"/> if no more lines are available.
/// </returns>
/// ----------------------------------------------------------------------------------------------------
[DebuggerStepThrough]
public static string ReadLine(int bufferSize = short.MaxValue) {
if (bufferSize < 256) {
throw new ArgumentException(nameof(bufferSize), message:"Value must be equal or greater than 256.");
}

Stream inputStream = Console.OpenStandardInput(bufferSize);
byte[] bytes = new byte[bufferSize];
int outputLength = inputStream.Read(bytes, 0, bufferSize);
char[] chars = Console.InputEncoding.GetChars(bytes, 0, outputLength);

return (new string(chars)).TrimEnd(new[] {'\r', '\n'});
}


Modo de empleo en C#:
Código (csharp) [Seleccionar]
// Copy very long string to clipboard.
string longString = new string('0', short.MaxValue);
Clipboard.SetText(longString);

// Manually paste the string here...
string line = ConsoleUtil.ReadLine(bufferSize:ushort.MaxValue);

Console.WriteLine();
Console.WriteLine($"String Length: {line.Length}");

Console.WriteLine("Press any key to exit...");
Console.ReadKey();

Environment.Exit(0);

Meta

Muy buen planteamiento. Muchísimas gracias, ya me sirvió.

Dejo el código completo por si alguien lo necesita.

Funciona todo al 100 %, con tildes incluidos.
Código (csharp) [Seleccionar]
using System;
using System.IO;
using System.Net;
using System.Net.Mail;
using System.Text;

namespace Enviar_email_Consola_07
{
    internal class Program
    {
        static void Main(string[] args)
        {
           

            // Variables.
            string usuario, contraseña, destinatario, asunto, mensaje;
            const int MAXIMA_LONGITUD = 2048;

            #region Configuración ventana.
            // Título de la ventana.
            Console.Title = "Gestor correo electrónico";

            // Tamaño de la ventana, x, y.
            Console.SetWindowSize(80, 25);

            // Color de fondo.
            Console.BackgroundColor = ConsoleColor.Black;

            // Color de las letras.
            Console.ForegroundColor = ConsoleColor.Gray;

            // Limpiar pantalla y dejarlo todo en color de fondo.
            Console.Clear();

            // Visible el cursor.
            Console.CursorVisible = true;
            #endregion

            // Título del programa.
            Console.WriteLine("\t\t----------------------------------------");
            Console.WriteLine("\t\t\tEnviar Correo Electrónico");
            Console.WriteLine("\t\t----------------------------------------");

            try
            {
               
                Console.WriteLine("\n");
                Console.ForegroundColor = ConsoleColor.Cyan;
                Console.Write("\t\tTu correo electrónico: ");
                Console.ForegroundColor = ConsoleColor.Gray;
                usuario = Console.ReadLine();
                Console.WriteLine();
                Console.ForegroundColor = ConsoleColor.Cyan;
                Console.Write("\t\tIntroducir contraseña: ");
                Console.ForegroundColor = ConsoleColor.Gray;
                contraseña = LeerPassword();
                Console.WriteLine();
                Console.ForegroundColor = ConsoleColor.Cyan;
                Console.Write("\t\tDestinatario: ");
                Console.ForegroundColor = ConsoleColor.Gray;
                destinatario = Console.ReadLine();
                Console.WriteLine();
                Console.ForegroundColor = ConsoleColor.Cyan;
                Console.Write("\t\tAsunto: ");
                Console.ForegroundColor = ConsoleColor.Gray;
                asunto = Console.ReadLine();
                Console.WriteLine();
                Console.ForegroundColor = ConsoleColor.Cyan;
                Console.Write("\t\tMensaje: ");
                Console.ForegroundColor = ConsoleColor.Gray;
                //mensaje = Console.ReadLine();

                #region Enviar más de 255 caracteres.
                // Enviar mensaje de más de 255 caracteres. ################################
                Stream inputStream = Console.OpenStandardInput();
                byte[] buffer = new byte[MAXIMA_LONGITUD];
                int numerosBytesLeidos = inputStream.Read(buffer, 0, MAXIMA_LONGITUD);
                char[] chars = Console.InputEncoding.GetChars(buffer, 0, numerosBytesLeidos);
                mensaje = new string(chars);
                // #########################################################################
                #endregion
                Console.WriteLine();
                Console.ForegroundColor = ConsoleColor.DarkCyan;
                Console.Write("\t\tCantidad de texto introducido: ");
                Console.ForegroundColor = ConsoleColor.Gray;
                Console.WriteLine(mensaje.Length);               

                MailMessage correo = new MailMessage(usuario, destinatario, asunto, mensaje);

                SmtpClient servidor = new SmtpClient("smtp.gmail.com")
                {
                    Port = 587
                };
                NetworkCredential credenciales = new NetworkCredential(usuario, contraseña);
                servidor.Credentials = credenciales;
                servidor.EnableSsl = true;

                Console.WriteLine();
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine("\t\tEnviando correo...");
                servidor.Send(correo);
                Console.WriteLine();
                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine("\t\tCorreo enviado satisfactoriamente.");
                correo.Dispose();
                Console.CursorVisible = false;
                Console.ReadKey();
            }
            catch (Exception ex)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("ERROR: \n");
                Console.WriteLine("\t\t" + ex.Message);
                Console.WriteLine();
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine("\t\tNo se ha enviado el correo.");
                Console.ReadKey();
            }

        }

        // A la hora de introducir la contraseña, se sustituye por asterístos (*) en pantalla.
        public static string LeerPassword()
        {
            ConsoleKeyInfo cki;
            StringBuilder sb = new StringBuilder();
            int contador = 0;

            do
            {
                cki = Console.ReadKey(true);
                if (cki.Key != ConsoleKey.Enter)
                {

                    sb.Append(cki.KeyChar);
                    if (contador < 1)
                    {
                        Console.Write("*");
                    }
                    contador++;
                }

                else
                {
                    break;
                }

            } while (true);
            Console.WriteLine();
            return sb.ToString();
        }
    }
}


Que tengan buen fin de lo que queda de año.  ;-) ;-) ;-) ;-)
Tutoriales Electrónica y PIC: http://electronica-pic.blogspot.com/