使用FileSystemWatcher的Windows服务在之后立即启动和停止

时间:2017-06-02 08:13:04

标签: c# windows-services filesystemwatcher

我正在创建一个无法与我的财务打印机通信的pos应用程序。因此,我决定将收据存储在文本文件中作为Json对象,并使用FileSystemWatch制作Windows Service应用程序以检查文件更新并将其转发到打印机。我正在使用第三方库与打印机进行通信。这是服务的代码:

Program.cs的

static void Main(string[] args)
{
    var program = new Watcher();
    if (Environment.UserInteractive)
    {
        program.Start();
    }
    else
    {
        ServiceBase.Run(new ServiceBase[]
        {
            program
        });
    }
    //ServiceBase[] ServicesToRun;
    //ServicesToRun = new ServiceBase[]
    //{
    //    new Watcher()
    //};
    //ServiceBase.Run(ServicesToRun);
}

Watcher.cs

public partial class Watcher : ServiceBase
{

    [DllImport("advapi32.dll", SetLastError = true)]
    private static extern bool SetServiceStatus(IntPtr handle, ref ServiceStatus serviceStatus);

    public static OICFiscalPrinter printer { get; set; }

    [StructLayout(LayoutKind.Sequential)]
    public struct ServiceStatus
    {
        public long dwServiceType;
        public ServiceState dwCurrentState;
        public long dwControlsAccepted;
        public long dwWin32ExitCode;
        public long dwServiceSpecificExitCode;
        public long dwCheckPoint;
        public long dwWaitHint;
    };

    public enum ServiceState
    {
        SERVICE_STOPPED = 0x00000001,
        SERVICE_START_PENDING = 0x00000002,
        SERVICE_STOP_PENDING = 0x00000003,
        SERVICE_RUNNING = 0x00000004,
        SERVICE_CONTINUE_PENDING = 0x00000005,
        SERVICE_PAUSE_PENDING = 0x00000006,
        SERVICE_PAUSED = 0x00000007,
    }


    public Watcher()
    {
        InitializeComponent();

    }

    public void CheckReceipt(object e, FileSystemEventArgs args)
    {
        printer = new OICFiscalPrinter();
        var name = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
        string text = null;
        try
        {
            text = System.IO.File.ReadAllText(name + "\\Pictures\\test.txt");
            var BasketList = JsonConvert.DeserializeObject<List<ItemsOnFacture>>(text);
            printer.PortConfigString = "PortName=COM4;DataBits=8;Speed=9600;" +
                                       "Parity = N; StopBits = 1; FlowControl = X;" +
                                       "ReadTimeout = 6000;" +
                                       "WriteTimeout = 500; UseReadBuffer = 1";
            printer.Active = true;
            var t = printer.Open();
            if (!t) return;
            printer.OpenReceipt();
            foreach (var item in BasketList)
            {
                printer.ReceiptItem(item.ItemName, item.VatFee == 5 ? "B" : item.VatFee == 8 ? "A" : "D",
                    (decimal)item.PriceBrutto,
                    item.Amount, "unit", (decimal)item.PriceBruttoSum);
            }
            printer.CloseReceipt((decimal)BasketList.Sum(w => w.PriceBruttoSum),
                (decimal)BasketList.Sum(w => w.PriceBruttoSum));
            printer.Close();
            File.Delete(name + "\\Pictures\\test.txt");
        }
        catch
        {

        }

    }

    public void Start()
    {
        //Start Logic here
        var serviceStatus = new ServiceStatus
        {
            dwCurrentState = ServiceState.SERVICE_START_PENDING,
            dwWaitHint = 100000
        };


        this.fileSystemWatcher1 = new System.IO.FileSystemWatcher();
        ((System.ComponentModel.ISupportInitialize)(this.fileSystemWatcher1)).BeginInit();
        // 
        // fileSystemWatcher1
        // 
        this.fileSystemWatcher1.EnableRaisingEvents = true;
        var name = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
        fileSystemWatcher1 = new FileSystemWatcher(name + "\\Pictures", "test.txt")
        {
            EnableRaisingEvents = true,
            IncludeSubdirectories = false,
            NotifyFilter = NotifyFilters.DirectoryName
        };


        SetServiceStatus(this.ServiceHandle, ref serviceStatus);

        this.fileSystemWatcher1.Changed += new System.IO.FileSystemEventHandler(this.CheckReceipt);

        ((System.ComponentModel.ISupportInitialize)(this.fileSystemWatcher1)).EndInit();

        // Update the service state to Running.
        serviceStatus.dwCurrentState = ServiceState.SERVICE_RUNNING;
        SetServiceStatus(this.ServiceHandle, ref serviceStatus);
    }

    protected override void OnStart(string[] args)
    {
        Start();
    }

    protected override void OnContinue()
    {

    }

    protected override void OnStop()
    {

    }

    private FileSystemWatcher fileSystemWatcher1;

    /// <summary> 
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.IContainer components = null;
    /// <summary>
    /// Clean up any resources being used.
    /// </summary>
    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected override void Dispose(bool disposing)
    {
        if (disposing && (components != null))
        {
            components.Dispose();
        }
        base.Dispose(disposing);
    }

    #region Component Designer generated code

    /// <summary> 
    /// Required method for Designer support - do not modify 
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
        // 
        // Watcher
        // 
        components = new System.ComponentModel.Container();
        this.ServiceName = "WATTOFP";

    }

    #endregion
}

ProjectInstaller.cs

[RunInstaller(true)]
public class ProjectInstaller : System.Configuration.Install.Installer
{
    public ProjectInstaller()
    {
        InitializeComponent();
    }

    /// <summary>
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.IContainer components = null;

    /// <summary> 
    /// Clean up any resources being used.
    /// </summary>
    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected override void Dispose(bool disposing)
    {
        if (disposing && (components != null))
        {
            components.Dispose();
        }
        base.Dispose(disposing);
    }

    #region Component Designer generated code

    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
        this.serviceProcessInstaller1 = new System.ServiceProcess.ServiceProcessInstaller();
        this.serviceInstaller1 = new System.ServiceProcess.ServiceInstaller();
        // 
        // serviceProcessInstaller1
        // 
        this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
        this.serviceProcessInstaller1.Password = null;
        this.serviceProcessInstaller1.Username = null;
        // 
        // serviceInstaller1
        // 
        this.serviceInstaller1.Description = "WATTO Fiscal Printer";
        this.serviceInstaller1.DisplayName = "WATTO Fiscal Printer";
        this.serviceInstaller1.ServiceName = "WATTOFP";
        this.serviceInstaller1.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
        // 
        // ProjectInstaller
        // 
        this.Installers.AddRange(new System.Configuration.Install.Installer[] {
        this.serviceProcessInstaller1,
        this.serviceInstaller1});

    }

    #endregion

    private System.ServiceProcess.ServiceProcessInstaller serviceProcessInstaller1;
    private System.ServiceProcess.ServiceInstaller serviceInstaller1;
}

问题在于,安装完成后,当我尝试运行服务时,它会启动并在警告出现时立即停止。如何运行服务并观察文件以进行更改?

1 个答案:

答案 0 :(得分:0)

问题可能是默认情况下服务在系统帐户下运行。因此,用户文件夹不是您所期望的,并且没有文件。

通常在无法启动服务时,事件日志中应该出现异常错误。请在此处发布以获得进一步的帮助。