Question

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;
    }
}
Was it helpful?

Solution

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
}

OTHER TIPS

From the StreamWriter documentation:

A good practice is to use these objects in a using statement so that the unmanaged resources are correctly disposed. The using statement automatically calls Dispose on the object when the code that is using it has completed.

They are IDisposable so should be wrapped in using. Dispose should call close as well.

Have you ever close the filestream after you finished writing things into it?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top