I'm using C# and the AE.Net.Mail library to pull files from Gmail. I'm having problems with large zip files.
The same problem is described and resolved here with Java: JavaMail BaseEncode64 Error
Does anyone know how to set partial fetch flag with C# and the AE.Net.Mail library?
Go with (or take a look at) S22.Imap. It's an AE.Net.Mail documented with some extras.
From examples: Download attachments only if they are smaller than 2 Megabytes
using System;
using S22.Imap;
namespace Test {
class Program {
static void Main(string[] args)
{
using (ImapClient Client = new ImapClient("imap.gmail.com", 993,
"username", "password", Authmethod.Login, true))
{
// This returns all messages sent since August 23rd 2012
uint[] uids = Client.Search(
SearchCondition.SentSince( new DateTime(2012, 8, 23) )
);
// Our lambda expression will be evaluated for every MIME part
// of every mail message in the uids array
MailMessage[] messages = Client.GetMessages(uids,
(Bodypart part) => {
// We're only interested in attachments
if(part.Disposition.Type == ContentDispositionType.Attachment)
{
Int64 TwoMegabytes = (1024 * 1024 * 2);
if(part.Size > TwoMegabytes)
{
// Don't download this attachment
return false;
}
}
// fetch MIME part and include it in the returned MailMessage instance
return true;
}
);
}
}
}
}
Related
I want to read outlook email in C# using pop3.
when i get message from my mailbox, there is encoding exception because i read korean email.
how can i read korean email?
And Can i set mailbox that i want to read?
please help me
class Program
{
static Pop3Client client = new Pop3Client();
static StringBuilder builder = new StringBuilder();
static void Main(string[] args)
{
client.Connect("outlook.office365.com", 995, true);
client.Authenticate("blahblahblah", "blahblahblah");//로그인
Console.WriteLine("Checking Inbox");
DataTable table = new DataTable();
var count = client.GetMessageCount();//몇개의 메세지가 있는지
Console.WriteLine(count);
for (int i=count;i>=1;i--)
{
var message = client.GetMessage(i);
var fromAddress = message.Headers.From.Address;
var subject = message.Headers.Subject;
var messageBody = String.Empty;
var plainText = message.FindFirstPlainTextVersion();
if (plainText == null)
{
var html = message.FindFirstHtmlVersion();
messageBody = html.GetBodyAsText();
}
else
{
messageBody = plainText.GetBodyAsText();
}
table.Rows.Add(i,subject, fromAddress, messageBody);
}
}
}
Hi and welcome to Stack Overflow.
As per my understanding, you are using OpenPop.NET library.
OpenPop.NET uses EncodingFinder class to find correct encoding. By default it supports only utf8 and ascii (at least reading library code at github).
According to this page:
http://hpop.sourceforge.net/exampleChangeCharacterSetMapping.php
you can add your encoding(s) to EncodingFinder.
In your case, all you have to do is:
static void Main(string[] args)
{
EncodingFinder.AddMapping("ks_c_5601-1987", Encoding.GetEncoding(949));
// rest of the application
Please note this will work only on .NET Framework, not in .NET Core, since the latter supports a really limited number of encodings (https://learn.microsoft.com/en-us/dotnet/api/system.text.encodinginfo.getencoding?view=netcore-3.1).
I do not have a Korean pop3 on which to test this solution, but I hope it will work. Good luck!
Edit after some search
It should be possible to work with Korean encoding in .NET Core also, it's just a little trickier:
static void Main(string[] args)
{
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
EncodingFinder.AddMapping("ks_c_5601-1987", Encoding.GetEncoding(949));
// rest of application
Give it a try, if you are working with .NET Core.
I have been looking high and low for a while to have an easy to use piece of code to have my C# project download a text file attachment on an email from gmail. I did take a look at openpop.net lib, which is the only library I see that seems promising! Can anyone show me some code that gets the job done? I looked at other peoples examples with openpop, but the api was different in their example, maybe older version? Thank you in advance for you help!
Here's how you would do this using my MailKit library which is vastly more efficient than OpenPOP.NET:
using System;
using System.Linq;
using MailKit.Net.Pop3;
using MailKit;
using MimeKit;
namespace TestClient {
class Program
{
public static void Main (string[] args)
{
using (var client = new Pop3Client ()) {
client.Connect ("pop.gmail.com", 995, true);
// Note: since we don't have an OAuth2 token, disable
// the XOAUTH2 authentication mechanism.
client.AuthenticationMechanisms.Remove ("XOAUTH2");
client.Authenticate ("joey#gmail.com", "password");
int count = client.GetMessageCount ();
int unknown = 0;
for (int i = 0; i < count; i++) {
var message = client.GetMessage (i);
foreach (var attachment in message.Attachments.OfType<TextPart> ()) {
var fileName = attachment.FileName ?? string.Format ("unknown{0}.txt", ++unknown);
// Save the content of the attachment in whatever
// charset it is in.
using (var stream = File.Create (fileName))
attachment.ContentObject.DecodeTo (stream);
}
}
client.Disconnect (true);
}
}
}
}
If you have a lot of messages in your GMail account and/or you just want to download messages with even more efficiency, GMail supports the PIPELINING extension which MailKit can take advantage of.
Instead of downloading a single message at a time, you can use GetMessages() to batch request a range of messages which will take advantage of the PIPELINING extension which vastly reduces latency and thus can greatly reduce download times.
I want to send a file from a C# server to a AS3 Flash Client. My C# server code for sending the file is something like this:
IPEndPoint ipEnd = new IPEndPoint(IPAddress.Any, 5656);
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
sock.Bind(ipEnd);
sock.Listen(100);
//clientSock is the socket object of client, so we can use it now to transfer data to client
Socket clientSock = sock.Accept();
// This part gets the file and send the data in bytearray
byte[] fileData = File.ReadAllBytes("send/mypicture.jpg");
clientSock.Send(fileData);
Now I need a as3 client. I found this: http://flasharp.blogspot.pt/2010/03/socket-serverclient-chat.html and I constructed something like this:
public function Main():void {
...
socket.addEventListener(ProgressEvent.SOCKET_DATA, onResponse);
...
}
function onResponse(e:ProgressEvent):void {
var file:File;
var fs:FileStream;
var fileData:ByteArray = new ByteArray();
// Check if socket has data
if(socket.bytesAvailable > 0) {
while(socket.bytesAvailable) {
// read the socket data into the fileData
socket.readBytes(fileData,0,0);
}
}
file = File.documentsDirectory.resolvePath("teste.jpg");
fs = new FileStream();
fs.open(file, FileMode.WRITE);
// Writing the file
fs.writeBytes(fileData);
fs.close();
}
I've managed to send and receive a file, but it only saves up to 50kbs, anything bigger and you just gest a file with that size.
Any thoughts on how to transfer a file with any size?
I managed to solve this and updated this post with a sample.
UPDATED & SOLVED:
I wanted to send files from a C# server to AS3 Clients using sockets in a Local Network. I had some trouble finding out how to do it, but I managed to do so.
Server (C#):
1 - I create a TcpListener that listens for new clients with any IP in that network to the specified port number;
2 - When a new client connects I create a Thread to handle it;
3 - In that Thread I send the data I want to. In this case that data is divided in two parts, the first is a 4 bytearray that contains the size of the file I want to send, and the second is a bytearray of the file itself;
4 - After the data is sent I close that client connection;
Client (AS3):
1 - First of all I convert my bytearrays to LITTLE_ENDIAN, since AIR is by default BIG_ENDIAN and the data I get from the server is LITTLE_ENDIAN;
2 - Add the events to the socket connection and conect to the server;
3 - On the onResponse function I receive the socket packages to a bytearray;
4 - Save that bytearray into a file;
The last part on the client was the trickiest one, because it took me some time to figure out that AIR is BIG_ENDIAN by default, and how to read the packages.
So basically, what I do is, on the first package that comes in I read the first 4 bytes to a bytearray and then convert that to an int, which gives me my total file size. I use this to know when there are no more packages to receive and therefore finish the connection and save the file. The rest of the first package and subsequent packages are added to a bytearray that will store that file data itself. The workaround here is to start writing on the beggining the first time a package is received and then add the subsequent packages where the last one left off, i.e., first time I write from the 0 to 65321, second one I'll have to write from the 65321 to XXXX, and so on.
The file is being saved to the MyDocuments folder.
I'm unsure if this is the best method to do this, since I'm rather new to socket connection, however this works for me and I tested with files up to 165MB and it works. It supports multiple client connections and is pretty basic, but this is a starting point, not a finish line.
I hope this can help others as it helped me, since I did not find anything like it on the web (regarding file transfer not C# -> AS3 connection).
If someone wants to input some info or needs clarification on something, please feel free to ask.
Last but no least, sample can be downloaded here: http://sdrv.ms/W5mSs9 (Server in C# Express 2010 and Client in Flash Builder 4.6 with Flex SDK 4.6.0)
In case the sample in the link above ever dies out here is the
ActionScript 3 Source Code:
package
{
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.events.ProgressEvent;
import flash.events.SecurityErrorEvent;
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
import flash.net.Socket;
import flash.system.Security;
import flash.utils.ByteArray;
import flash.utils.Endian;
import flash.text.TextField;
public class FileTransferLocal extends Sprite
{
private var socket:Socket = new Socket();
private var file:File;
private var fs:FileStream = new FileStream();
private var fileData:ByteArray = new ByteArray();
private var fileSize:ByteArray = new ByteArray();
private var fileDataPosition:int = new int();
private var fileDataFlag:int = new int();
private var fileSizeFlag:int = new int();
private var fileSizeCounter:int = new int();
private var fileDataPreviousPosition:int = new int();
private var myText:TextField = new TextField();
public function FileTransferLocal()
{
try {Security.allowDomain("*");}catch (e) { };
// Convert bytearray to Little Endian
fileSize.endian = Endian.LITTLE_ENDIAN;
fileData.endian = Endian.LITTLE_ENDIAN;
socket.endian = Endian.LITTLE_ENDIAN;
fileSizeFlag = 0;
fileDataFlag = 0;
myText.width = 150;
myText.height = 150;
myText.x = 200;
myText.y = 200;
socket.addEventListener(Event.CONNECT, onConnect);
socket.addEventListener(Event.CLOSE, onClose);
socket.addEventListener(IOErrorEvent.IO_ERROR, onError);
socket.addEventListener(ProgressEvent.SOCKET_DATA, onResponse);
socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecError);
// Put the IP and port of the server
socket.connect("10.1.1.211", 5656);
}
private function onConnect(e:Event):void {
trace("onConnect\n");
}
private function onClose(e:Event):void {
trace("onClose");
socket.close();
}
private function onError(e:IOErrorEvent):void {
trace("IO Error: "+e);
}
private function onSecError(e:SecurityErrorEvent):void {
trace("Security Error: "+e);
}
private function onResponse(e:ProgressEvent):void {
if(!fileSizeFlag) {
socket.readBytes(fileSize, 0, 4);
fileSize.position = 0;
fileSizeFlag = 1;
fileSizeCounter = fileSize.readInt();
trace("fileSizeCounter -> " + fileSizeCounter);
}
trace("---- New package ----> " + socket.bytesAvailable);
if(fileSizeCounter > 0) {
fileSizeCounter -= socket.bytesAvailable;
if(fileDataPosition != 0) {
fileDataPreviousPosition += fileDataPosition;
}
if(fileData.length == 0) {
fileDataPreviousPosition = socket.bytesAvailable;
socket.readBytes(fileData, 0, socket.bytesAvailable);
} else {
fileDataPosition = socket.bytesAvailable;
socket.readBytes(fileData, fileDataPreviousPosition, socket.bytesAvailable);
}
}
// Saves the file
if(fileSizeCounter == 0) {
trace("File total size" + fileData.length);
file = File.documentsDirectory.resolvePath("test.mp3");
fs.open(file, FileMode.WRITE);
fs.writeBytes(fileData);
fs.close();
myText.text = "File successefully\nreceived!";
addChild(myText);
}
// Is still receiving packages
else {
myText.text = "Receiving file...";
addChild(myText);
}
}
}
}
In C# create a new Windows Application
add a
ListBox call it statusList
Label call it port
Label call it status
C# Source code in Sample Above:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Threading;
using System.Net;
using System.IO;
using System.Reflection;
namespace ServerThread
{
public partial class ServerThread : Form
{
private TcpListener tcpListener;
private Thread listenThread;
public ServerThread()
{
InitializeComponent();
// Port number
int portNumber = 5656;
port.Text = portNumber.ToString();
// Create a TcpListener to cover all existent IP addresses with that port
this.tcpListener = new TcpListener(IPAddress.Any, portNumber);
// Create a Thread to listen to clients
this.listenThread = new Thread(new ThreadStart(ListenForClients));
this.listenThread.Start();
}
private void ListenForClients()
{
this.tcpListener.Start();
while (true)
{
// Blocks until a client has conected to the server
TcpClient client = this.tcpListener.AcceptTcpClient();
// Create a Thread to handle the conected client communication
Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
clientThread.Start(client);
}
}
private void HandleClientComm(object client)
{
// Receive data
TcpClient tcpClient = (TcpClient)client;
NetworkStream clientStream = tcpClient.GetStream();
while (true)
{
try
{
// Sending data
string filePath = "send/mysong.mp3"; // Your File Path;
byte[] fileData = File.ReadAllBytes(filePath); // The size of your file
byte[] fileSize = BitConverter.GetBytes(fileData.Length); // The size of yout file converted to a 4 byte array
byte[] clientData = new byte[fileSize.Length + fileData.Length]; // The total byte size of the data to be sent
fileSize.CopyTo(clientData, 0); // Copy to the file size byte array to the sending array (clientData) beginning the in the 0 index
fileData.CopyTo(clientData, 4); // Copy to the file data byte array to the sending array (clientData) beginning the in the 4 index
// Send the data to the client
clientStream.Write(clientData, 0, clientData.Length);
clientStream.Flush();
// Debug for the ListBox
if (statusList.InvokeRequired)
{
statusList.Invoke(new MethodInvoker(delegate {
statusList.Items.Add("Client IP: " + tcpClient.Client.RemoteEndPoint.ToString());
statusList.Items.Add("Client Data size: " + clientData.Length);
}));
}
}
catch
{
//
break;
}
if (statusList.InvokeRequired)
{
statusList.Invoke(new MethodInvoker(delegate
{
statusList.Items.Add("File successefully sent!");
}));
}
// Close the client
tcpClient.Close();
}
}
}
}
I want to get all emails in my ASP.NET application that have a certain CC-recipient. To use this for future emails I didn't want to polling all the time to get them. But I can't find a way, how I can use push to get the emails instantly. Are their any frameworks in C# to help me for this?
I want to connect with my application to a mail server and register a method 'X'. Always when a new message arrived to the mail server, my application have to be notified and my application should execute the method 'X'.
I hope that this is possible with code like this:
void Application_Start()
{
...
ConnectWithTheSmtpServer();
RegisterMethodForNotification(DoSomethink);
...
}
void DoSomethink(Mail newMail)
{
// Do Somethink with the mail
}
EDIT:
I did it with the MailSystem.Net. It works very fine and is very easy to implement.
Sample Code:
void Application_Start()
{
var worker = new BackgroundWorker();
worker.DoWork += new DoWorkEventHandler(StartIdleProcess);
if (worker.IsBusy)
worker.CancelAsync();
worker.RunWorkerAsync();
}
private void StartIdleProcess(object sender, DoWorkEventArgs e)
{
if (_imap != null && _imap.IsConnected)
{
_imap.StopIdle();
_imap.Disconnect();
}
_imap = new Imap4Client();
_imap.ConnectSsl(server-name, 993);
_imap.Login(username, passwort);
var inbox = _imap.SelectMailbox("INBOX");
_imap.NewMessageReceived += new NewMessageReceivedEventHandler(NewMessageReceived);
inbox.Subscribe();
_imap.StartIdle();
}
public static void NewMessageReceived(object source, NewMessageReceivedEventArgs e)
{
// Do something with the source...
}
You are approaching this from the wrong angle.
SMTP does not support receiving mail (never mind PUSH mail). POP3 is what you can use for retrieving mail, but it does not have support for PUSH either (so you would have to pull for mail).
The IMAP4 IDLE extension is what most refer to as PUSH mail - so you will need to find a library for C# that supports IMAP4 IDLE. I found some information that will get you going in the right direction (no reason to duplicate it here):
Using C# .Net Libraries to Check for IMAP Messages
Accessing IMAP in C#
Keep in mind when choosing a solution that it needs to support IDLE.
I really like the look of MailSystem.Net as it fulfills your requirements.
Remember that your mail server also needs to have IMAP4 and IMAP4 IDLE enabled. Some mail servers don't support it, so you might be clean out of luck (and will have to use POP3 pulling).
You could send a copy of your emails(i.e. using /etc/aliases file in PostFix) to a MAIL SERVER YOU CAN HANDLE. Once there, you can implement a MAIL PROCESSOR that do whatever you want anytime a mail that MEET CERTAIN CONDITIONS arrives.
Hope that helps,
You can try this:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using EAGetMail; //add EAGetMail namespace
namespace receiveemail
{
class Program
{
static void Main(string[] args)
{
// Create a folder named "inbox" under current directory
// to save the email retrie enter code here ved.
string curpath = Directory.GetCurrentDirectory();
string mailbox = String.Format("{0}\\inbox", curpath);
// If the folder is not existed, create it.
if (!Directory.Exists(mailbox))
{
Directory.CreateDirectory(mailbox);
}
// Gmail IMAP4 server is "imap.gmail.com"
MailServer oServer = new MailServer("imap.gmail.com",
"gmailid#gmail.com", "yourpassword", ServerProtocol.Imap4 );
MailClient oClient = new MailClient("TryIt");
// Set SSL connection,
oServer.SSLConnection = true;
// Set 993 IMAP4 port
oServer.Port = 993;
try
{
oClient.Connect(oServer);
MailInfo[] infos = oClient.GetMailInfos();
for (int i = 0; i < infos.Length; i++)
{
MailInfo info = infos[i];
Console.WriteLine("Index: {0}; Size: {1}; UIDL: {2}",
info.Index, info.Size, info.UIDL);
// Download email from GMail IMAP4 server
Mail oMail = oClient.GetMail(info);
Console.WriteLine("From: {0}", oMail.From.ToString());
Console.WriteLine("Subject: {0}\r\n", oMail.Subject);
// Generate an email file name based on date time.
System.DateTime d = System.DateTime.Now;
System.Globalization.CultureInfo cur = new
System.Globalization.CultureInfo("en-US");
string sdate = d.ToString("yyyyMMddHHmmss", cur);
string fileName = String.Format("{0}\\{1}{2}{3}.eml",
mailbox, sdate, d.Millisecond.ToString("d3"), i);
// Save email to local disk
oMail.SaveAs(fileName, true);
// Mark email as deleted in GMail account.
oClient.Delete(info);
}
// Quit and purge emails marked as deleted from Gmail IMAP4 server.
oClient.Quit();
}
catch (Exception ep)
{
Console.WriteLine(ep.Message);
}
}
}
}
I write a "email client" program to check and read mail.
I had download source-code of many author (in codeproject)but they program was loading very long and when i restart program must download it again.
I have idea to save mail we have downloaded and only download only new mail.
How can i save mail? I can use XML or SQL?
I using POP3 and IMAP.
Check out Limisoft library.
Here is the sample of code:
using LumiSoft.Net.IMAP;
using LumiSoft.Net.IMAP.Client;
using LumiSoft.Net;
...
using (IMAP_Client client = new IMAP_Client())
{
client.Connect("imap.gmail.com", 993, true);
client.Login("your.username#gmail.com", "your_cool_password");
client.SelectFolder("INBOX");
IMAP_SequenceSet sequence = new IMAP_SequenceSet();
//sequence.Parse("*:1"); // from first to last
IMAP_Client_FetchHandler fetchHandler = new IMAP_Client_FetchHandler();
fetchHandler.NextMessage += new EventHandler(delegate(object s, EventArgs e)
{
Console.WriteLine("next message");
});
fetchHandler.Envelope += new EventHandler<EventArgs<IMAP_Envelope>>(delegate(object s, EventArgs<IMAP_Envelope> e){
IMAP_Envelope envelope = e.Value;
if (envelope.From != null && !String.IsNullOrWhiteSpace(envelope.Subject))
{
Console.WriteLine(envelope.Subject);
}
});
// the best way to find unread emails is to perform server search
int[] unseen_ids = client.Search(false, "UTF-8", "unseen");
Console.WriteLine("unseen count: " + unseen_ids.Count().ToString());
// now we need to initiate our sequence of messages to be fetched
sequence.Parse(string.Join(",", unseen_ids));
// fetch messages now
client.Fetch(false, sequence, new IMAP_Fetch_DataItem[] { new IMAP_Fetch_DataItem_Envelope() }, fetchHandler);
// uncomment this line to mark messages as read
// client.StoreMessageFlags(false, sequence, IMAP_Flags_SetType.Add, IMAP_MessageFlags.Seen);
}
Bit complicated, but works fine. Limisoft library is not perfect, so be sure you test it well.
Messages on the server have a UID (at least for IMAP.) By definition the UID will only increase. Meaning if you have a UID of 321, the next UID has to be 322 or higher. So you could store the "Last UID" in your DB, and then get the highest UID from the server. If it's higher than your last one, load the new ones.