【问题标题】:My .NET Windows service will not start我的 .NET Windows 服务无法启动
【发布时间】:2016-01-04 13:37:04
【问题描述】:

我编写了这个 .NET Windows 服务应用程序,它基本上是一个文件观察器。该服务将监控传入的 .csv 文件,从中解析数据,并将数据添加到电子表格中。我在服务器上安装了该服务并尝试启动它。我收到警告,“服务启动然后停止。如果某些服务没有被其他服务或程序使用,它们会自动停止。”在调试尝试中,我删除了所有代码,只有一个裸服务,它启动/停止正常。所以我添加了文件观察器对象,它再次弹出警告。接下来,我将服务更改为使用本地管理帐户而不是“LocalService”帐户运行,然后它就可以工作了。我添加了我的其余代码,它工作了一段时间。我完成了开发并添加了 EventLog 对象,然后我又回到了警告中。我删除了 EventLog 对象,但仍然收到警告。我只是不知道是什么导致它无法启动。这是我的服务:

using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using OfficeOpenXml;
using System.Linq;
using System.ServiceProcess;
using System.Text;

namespace COD_Automation
{
public partial class COD_AUTO : ServiceBase
{
    FileSystemWatcher eWatcher;
    String remoteSrc;
    public static String filePath;
    public static String fileName;
    public static Boolean fileCheck;
    public static String modifiedDT;
    public static String remodifiedDT;
    public static String SampNum;
    public static String SampDate;
    public static String AnalysisInitials;
    public static int SampResult;
    public static double Dilution;
    public static FileInfo efile;
    public int rowIndex = 8;
    public int filterID = 1;

    public COD_AUTO()
    {
        InitializeComponent();

        if (!System.Diagnostics.EventLog.SourceExists("COD_Automation"))
        {
            System.Diagnostics.EventLog.CreateEventSource(
                "COD_Automation", "COD Automation Log");
        }

        serviceLog.Source = "COD_Automation";
        serviceLog.Log = "COD Automation Log";
    }

    protected override void OnStart(string[] args)
    {
        serviceLog.WriteEntry("COD Automation Service has started.");

        //Define the remote folder location to watch
        remoteSrc = "\\\\mkfiler01\\ops\\Envcom\\EXEC\\ENVCOM\\LAB\\COD\\Exports\\DataLog";

        //Create a new FileSystemWatcher and set its properties
        eWatcher = new FileSystemWatcher(remoteSrc, "*.csv");

        //Add event handler
        eWatcher.Created += new FileSystemEventHandler(eWatcher_Created);

        //Begin watching
        eWatcher.EnableRaisingEvents = true;
    }

    protected override void OnStop()
    {
        serviceLog.WriteEntry("COD Automation Service has stopped.");
        eWatcher.EnableRaisingEvents = false;
    }

    private void eWatcher_Created(object source, FileSystemEventArgs e)
    {
        filePath = e.FullPath;
        fileName = e.Name;
        ParseData(filePath);
        FileCheck(fileName);
        CreateExcelFile(fileCheck);
        AddSample(SampNum, SampDate, AnalysisInitials, SampResult, Dilution);
    }

    public void ParseData(String filePath)
    {
        //Create a dictionary collections with int keys (rowNums) and String values (each line of Strings)
        Dictionary<int, String> eachCSVLine = new Dictionary<int, string>();

        //String array that holds the contents of the specified row
        String[] lineContent;

        int rowNum = 1;

        foreach (string line in File.ReadLines(filePath))
        {
            eachCSVLine.Add(rowNum, line);
            rowNum++;
        }

        //Get the required line and split it by "," into an array
        String reqLine = eachCSVLine[5];
        lineContent = reqLine.Split(',');

        //Get the required values(index 2 for parsed Operator ID, index 4 for parsed Sample Number, index 11 for Sample Result)
        AnalysisInitials = lineContent.GetValue(2).ToString();
        SampNum = lineContent.GetValue(3).ToString();      //sample number            

        String result = lineContent.GetValue(11).ToString();
        String dilute = lineContent.GetValue(8).ToString();
        Dilution = Double.Parse(dilute);
        SampResult = Int32.Parse(result);    //sample result
    }

    public void AddSample(String SampleNum, String SampleDate, String AnalysisInitials, int SampleResult, double Diluted)
    {
        try
        {
            using (ExcelPackage excelPackage = new ExcelPackage(efile))
            {
                ExcelWorksheet worksheet = excelPackage.Workbook.Worksheets[1];
                var cell = worksheet.Cells;

                //check to see if this is the first sample added --if true, add the first sample --if false, increment rowindex & filterID then add the sample to next available row
                if (cell["A8"].Value == null)
                {
                    cell["B5"].Value = SampleDate;
                    cell["B6"].Value = AnalysisInitials;
                    cell[rowIndex, 1].Value = filterID;  //Filter ID
                    cell[rowIndex, 2].Value = SampleNum;   //Sample Number
                    cell[rowIndex, 3].Value = Dilution;   //Dilution
                    cell[rowIndex, 4].Value = SampleResult;   //Meter Reading
                }
                else
                {
                    while (!(cell["A8"].Value == null))
                    {
                        rowIndex++;
                        filterID++;
                        if (cell[rowIndex, 1].Value == null)  //ensures that the new row is blank so the loop can break to continue adding the sample
                        { break; }
                    }

                    //add the sample to the next empty row
                    cell[rowIndex, 1].Value = filterID;  //Filter ID
                    cell[rowIndex, 2].Value = SampleNum;   //Sample Number
                    cell[rowIndex, 3].Value = Dilution;   //Dilution
                    cell[rowIndex, 4].Value = SampleResult;   //Meter Reading
                }
                excelPackage.Save();
            }
        }
        catch (Exception e)
        {
            serviceLog.WriteEntry("Sample could not be added to the spreadsheet because of the following error: " + e.Message + ".");
        }
    }

    public Boolean FileCheck(String fileName)
    {
        //Get the date of the .csv file
        String[] fNames = fileName.Split('_');
        String fDate = fNames.ElementAt(3);
        DateTime dt = Convert.ToDateTime(fDate);

        //format the file date into the proper format and convert to a string
        modifiedDT = dt.ToString("MMddyy");

        //modify the "modifiedDT to get the sample date to insert into spreadsheet            
        String mdate = modifiedDT.Insert(2, "/");
        remodifiedDT = mdate.Insert(5, "/");
        SampDate = remodifiedDT;         //sample date           

        //assign an excel filename
        String exFile = @"\\mkfiler01\ops\Envcom\EXEC\ENVCOM\LAB\COD\Imports\" + modifiedDT + "COD-" + AnalysisInitials + ".xlsx";

        //check for file existence
        if (File.Exists(exFile))
        { fileCheck = true; }
        else
        { fileCheck = false; }

        return fileCheck;
    }

    public void CreateExcelFile(Boolean fileCheck)
    {
        if (fileCheck)
        {
            efile = new FileInfo(@"\\mkfiler01\ops\Envcom\EXEC\ENVCOM\LAB\COD\Imports\" + modifiedDT + "COD-" + AnalysisInitials + ".xlsx");

            using (ExcelPackage excelPackage = new ExcelPackage(efile))
            {
                //Read the existing file to see if the Analysis Initials match the AnalysisInitial variable value
                ExcelWorksheet worksheet = excelPackage.Workbook.Worksheets[1];
                String initials = worksheet.Cells["B6"].Value.ToString();

                //If initials = AnalysisIntials then assign the existing file the WB variable, else create a new file for the different AnalysisInitials
                if (initials.Equals(AnalysisInitials))
                {
                    excelPackage.Save();
                }
                else
                {
                    try
                    {
                        //Excel COD Template to use to create new Excel spreadsheet
                        FileInfo template = new FileInfo(@"\\mkfiler01\ops\Envcom\EXEC\ENVCOM\LAB\COD\COD TEMPLATE.xlsx");

                        //The new Excel spreadsheet filename
                        FileInfo newFile = new FileInfo(@"\\mkfiler01\ops\Envcom\EXEC\ENVCOM\LAB\COD\Imports\" + modifiedDT + "COD-" + AnalysisInitials + ".xlsx");

                        // Using the template to create the newfile
                        using (ExcelPackage excelPackage1 = new ExcelPackage(newFile, template))
                        {
                            // save the new Excel spreadsheet                                
                            excelPackage1.Save();
                        }
                    }
                    catch (Exception ex)
                    {
                        serviceLog.WriteEntry("Excel file could not be created because " + ex.Message);
                    }
                }
            }
        }
        else
        {
            try
            {
                efile = new FileInfo(@"\\mkfiler01\ops\Envcom\EXEC\ENVCOM\LAB\COD\Imports\" + modifiedDT + "COD-" + AnalysisInitials + ".xlsx");

                //Excel COD Template to use to create new Excel spreadsheet
                FileInfo template = new FileInfo(@"\\mkfiler01\ops\Envcom\EXEC\ENVCOM\LAB\COD\COD TEMPLATE.xlsx");

                //The new Excel spreadsheet filename
                FileInfo newFile = new FileInfo(@"\\mkfiler01\ops\Envcom\EXEC\ENVCOM\LAB\COD\Imports\" + modifiedDT + "COD-" + AnalysisInitials + ".xlsx");

                // Using the template to create the newfile
                using (ExcelPackage excelPackage = new ExcelPackage(newFile, template))
                {
                    // save the new Excel spreadsheet                        
                    excelPackage.Save();
                }
            }
            catch (Exception ex)
            {
                serviceLog.WriteEntry("Excel file could not be created because " + ex.Message);
            }
        }

    }        
}

}

【问题讨论】:

  • 打开EventViewer,你会看到异常详情。阅读/发布这些细节
  • 嗯,这不是一个玩笑,但是...您是否在调试模式下构建您的服务?在我意识到选择了错误的构建配置之前,我遇到了同样的问题并挣扎了一段时间
  • Andrew 我在活动(调试)配置中有它。但这是一个很好的建议,因为起初我在阅读您的回复时认为它确实处于调试模式
  • cFrozenDeath 我检查了 EventViewer,它给了我关于 EventLog 对象的 Source 和 Log 属性的 ArgumentException。这些属性必须根据细节匹配。我会检查我的陈述,看看我是否发现了问题。我会告诉你的。
  • 以下是 EventViewer 的详细信息:无法启动服务。 System.ArgumentException:源“COD_Automation”未在日志“COD 自动化日志”中注册。 (注册在日志'Application'中。) " Source 和 Log 属性必须匹配,也可以将 Log 设置为空字符串,它会自动匹配 Source 属性。

标签: c# .net service


【解决方案1】:

我的 EventViewer 显示了有关 EventLog 对象的 Source 和 Log 属性的 ArgumentException 的详细信息。我更改了以下代码:

if (!System.Diagnostics.EventLog.SourceExists("COD_Automation"))
    {
        System.Diagnostics.EventLog.CreateEventSource(
            "COD_Automation", "COD Automation Log");
    }

    serviceLog.Source = "COD_Automation";
    serviceLog.Log = "COD Automation Log";

进入以下代码:

if (!EventLog.SourceExists("COD_Automation"))
        {
            EventLog.CreateEventSource("COD_Automation", "Application");
        }

        serviceLog.Source = "COD_Automation";
        serviceLog.Log = "Application";

这解决了我的问题。我最初试图在不存在的 COD_Automation 日志中注册 COD_Automation 源。所以我将 Log 属性设置为“Application”的正确日志。

【讨论】:

  • 感谢大家的建议。这是我创建的第一个服务,我完全迷失了。
【解决方案2】:

LocalService 帐户将无法访问像 \\mkfiler01 这样的 UNC 共享。我的猜测是,您在尝试访问该文件共享时遇到了拒绝访问错误。

将服务设置为在有权访问该共享的域帐户下运行。

【讨论】:

  • 我已将其更改为域帐户,并且得到相同的结果。我检查了 EventViewer,它给了我关于 EventLog 对象的 Source 和 Log 属性的 ArgumentException。
  • 阅读错误信息,它可能准确地告诉您日志配置设置有什么问题。您还可以添加一个System.Diagnostics.Debugger.Launch() 调用,这将允许您在服务启动时将调试器附加到给定的代码行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-03
相关资源
最近更新 更多