I am making a windows service that in part of it makes a .eml/txt file using the FileStream and StreamWriter and it works perfectly, doing everything I need it to do. The only problem is that the new files it makes are for some reason still in use by the service afterwards, and I don't know why. Any clue? Fixes?
I figure that it must be something around lines to do with the FileStream and StreamWriter because they are the only things that touch the new files. Thanks in advance!
Service1.cs
public partial class emlService : ServiceBase
{
Boolean _isRunning;
public emlService()
{
InitializeComponent();
if (!System.Diagnostics.EventLog.SourceExists("emlServiceSource"))
{
System.Diagnostics.EventLog.CreateEventSource(
"emlServiceSource", "emlServiceLog");
}
eventLog1.Source = "emlSerivceSource";
eventLog1.Log = "emlServiceLog";
}
protected override void OnStart(string[] args)
{
eventLog1.WriteEntry("In OnStart");
Thread NewThread = new Thread(new ThreadStart(runProc));
_isRunning = true;
//Creates bool to start thread loop
if (_isRunning)
{
NewThread.Start();
}
}
protected override void OnStop()
{
eventLog1.WriteEntry("In OnStop");
_isRunning = false;
}
protected override void OnContinue()
{
}
public void runProc()
{
//Directory of the drop location
DirectoryInfo drop = new DirectoryInfo(@"C:\inetpub\mailroot\drop");
//Directory of the pickup location
string destpath = @"C:\inetpub\mailroot\pickup\";
//Inits ParserCommands and DropDirectory object
ParserCommands parserObject = new ParserCommands();
//Inits array to hold number of messages in drop location
FileInfo[] listfiles;
//Inits CFG
string conf_mailsender = ConfigurationSettings.AppSettings["conf_mailsender"];
string conf_rcpt = ConfigurationSettings.AppSettings["conf_rcpt"];
string conf_username_and_password = ConfigurationSettings.AppSettings["conf_username_and_password"];
string conf_sender = ConfigurationSettings.AppSettings["conf_sender"];
string conf_raport = ConfigurationSettings.AppSettings["conf_raport"];
//Loop that never ends
while (true)
{
Thread.Sleep(1000);
//Checks if there is a message waiting to be processed and begins processing if so
listfiles = drop.GetFiles();
if (listfiles.Length >= 1)
{
for (int j = 0; j <= (listfiles.Length - 1); j++)
{
//Gives it time to breathe
Thread.Sleep(250);
//Gets each line of the original .eml into a string array
try
{
//reader.
var lines = File.ReadAllLines(listfiles[j].FullName);
string[] linestring = lines.Select(c => c.ToString()).ToArray();
//Opens up steam and writer in the new dest, creates new .eml file
FileStream fs = new FileStream(destpath + listfiles[j].Name, FileMode.CreateNew);
StreamWriter writer = new StreamWriter(fs);
//Writes all .eml content into buffer
writer.WriteLine("x-sender: " + conf_mailsender);
writer.WriteLine("x-receiver: " + conf_rcpt);
writer.WriteLine(linestring[2]);
writer.WriteLine(linestring[3]);
writer.WriteLine(linestring[4]);
writer.WriteLine(linestring[5]);
writer.WriteLine(linestring[6]);
writer.WriteLine(linestring[7]);
writer.WriteLine(linestring[8]);
writer.WriteLine("From: " + conf_mailsender);
writer.WriteLine(linestring[10]);
writer.WriteLine("Reply-To: " + conf_mailsender);
writer.WriteLine("To: " + conf_rcpt);
writer.WriteLine("Subject: " + conf_username_and_password);
writer.WriteLine("Return-Path: " + conf_mailsender);
writer.WriteLine(linestring[15]);
writer.WriteLine();
//Seperates start of email from the rest and decode parameter_content
string parameter_to = parserObject.getReciever(linestring[12]);
string parameter_content = parserObject.DecodeFrom64(linestring[17]);
//Creates string ready for base64 encode
string encode = "from=" + conf_sender + "&to=" + parameter_to + "&raport=" + conf_raport + "&message=" + parameter_content;
//Writes encoded string into buffer
writer.WriteLine(parserObject.EncodeTo64(encode));
//Writes buffer into .eml file
writer.Flush();
fs.Flush();
fs = null;
writer = null;
lines = null;
}
catch (System.IO.IOException e)
{
Console.WriteLine("no");
}
//Deletes the file
File.Delete(listfiles[j].FullName);
}
//Sets the number of files needing sent to 0
listfiles = null;
}
}
}
}
Program.cs
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
//Starts the Service
System.ServiceProcess.ServiceBase[] ServicesToRun;
ServicesToRun = new System.ServiceProcess.ServiceBase[]
{ new emlService() };
System.ServiceProcess.ServiceBase.Run(ServicesToRun);
}
}
public class ParserCommands
{
/// <summary>
/// Seperates the address before @ from an email address
/// </summary>
/// <param name="email"> the email to be split </param>
/// <returns> everything before @ on an email address </returns>
public string getReciever(string email)
{
string[] Split = email.Split(new Char[] { '@' });
string Split2 = Split[0];
char[] chars = { 'T', 'o', ':', ' ' };
string FinalSplit = Split2.TrimStart(chars);
return FinalSplit;
}
/// <summary>
/// Decodes base64 into string
/// </summary>
/// <param name="encodedData"> the base64 encoded data</param>
/// <returns>decoded data as string</returns>
public string DecodeFrom64(string encodedData)
{
//Turns into bytes and then turns bytes into string
byte[] encodedDataAsBytes = System.Convert.FromBase64String(encodedData);
string returnValue = System.Text.Encoding.UTF8.GetString(encodedDataAsBytes);
return returnValue;
}
/// <summary>
/// Decodes base64 data
/// </summary>
/// <param name="toEncode"> data that nees to be decoded</param>
/// <returns> encoded data as string</returns>
public string EncodeTo64(string toEncode)
{
//Turns string into bytes and then encodes it
byte[] toEncodeAsBytes = System.Text.Encoding.UTF8.GetBytes(toEncode);
string returnValue = System.Convert.ToBase64String(toEncodeAsBytes);
return returnValue;
}
}
FileStream
and StreamWriter
are IDisposable
, so you should wrap them in using
statements to ensure they are closed when you're finished with them.
using (FileStream fs = new FileStream(destpath + listfiles[j].Name, FileMode.CreateNew))
using (StreamWriter writer = new StreamWriter(fs)) {
// .. your writing code here
}