0

私はサービスを作成しましたが、それは私のコンピューターで問題なく動作しますが、実行するはずのサーバーに移動すると、想定どおりにファイルの読み取り/書き込みを行うたびにSystem.IndexOutOfRangeExceptionが出力されます。サーバー上でのみこれを実行しているのは奇妙だと思います。また、コンピューターとの動作がどのように異なるのかわからないので、助けていただければ幸いです。

説明:未処理の例外が原因でプロセスが終了しました。例外情報:System.IndexOutOfRangeExceptionスタック:emlService.emlService.runProc()at System.Threading.ThreadHelper.ThreadStart_Context(System.Object)at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext、System.Threading.ContextCallback、 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext、System.Threading.ContextCallback、System.Object、Boolean)at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext、System。 System.Threading.ThreadHelper.ThreadStart()のThreading.ContextCallback、System.Object)

コード

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
        string tempDrop = ConfigurationSettings.AppSettings["conf_drop"];
        DirectoryInfo drop = new DirectoryInfo(tempDrop);

        //Directory of the pickup location
        string tempPickup = ConfigurationSettings.AppSettings["conf_pickup"];
        string destpath = tempPickup;

        //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) 
        {
            //Reduces load on machine
            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);

                    try
                    {
                        //Gets each line of the original .eml into a string array
                        var lines = File.ReadAllLines(listfiles[j].FullName);
                        string[] linestring = lines.Select(c => c.ToString()).ToArray();

                        //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;

                        //Opens up steam and writer in the new dest, creates new .eml file
                        using (FileStream fs = new FileStream(destpath + listfiles[j].Name, FileMode.CreateNew))
                        using (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();

                            //Writes encoded string into buffer
                            writer.WriteLine(parserObject.EncodeTo64(encode));

                            //Writes buffer into .eml file
                            writer.Flush();
                        }

                        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;
            }
        }
    }
}
4

2 に答える 2

3

私が知る限り、あなたはlinestringどこの長さをチェックしていません。十分な情報が提供されていないため、確かなことは言えませんがlinestring.Length、17 未満であるparserObject.DecodeFrom64(linestring[17]);ため、例外がスローされる可能性があります。それがlinestring.Length12 未満である可能性もあり、それはその前の行です。

これを修正するには、 の長さを確認しlinestring、結果を適切に処理する必要があります。

string[] linestring = lines.Select(c => c.ToString()).ToArray();
if(linestring.Length <= 17)
{
    //handle malformed file
}
else
{
    //complete the processing
}

質問とは関係ありませんが、効果はどうなのか気になりますlines.Select(c => c.ToString()File.ReadAllLines()既に文字列配列を返しているため、`Select(c => c.ToString()) は冗長です。

于 2013-03-21T23:24:46.747 に答える
2

読んでいる行の 1 つで、ラインストリングが期待する長さではありません。

これは決して失敗しないと確信していますか?

linestring[17]

ファイルに空の行がある場合はどうなりますか?

于 2013-03-21T23:25:04.770 に答える