2017-06-02 3 views
1

Je crée une application POS qui ne peut pas communiquer avec mon imprimante fiscale. J'ai donc décidé de stocker un reçu dans un fichier texte en tant qu'objet JSON et de créer une application Windows Service avec FileSystemWatch pour vérifier les mises à jour de fichiers et les transférer vers l'imprimante. J'utilise une bibliothèque tierce pour communiquer avec l'imprimante. Voici un code du service:Windows Service avec FileSystemWatcher démarre et s'arrête immédiatement après

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

Le problème est le fait qu'après l'installation, lorsque j'essaie d'exécuter le service, il démarre et s'arrête immédiatement lorsque l'avertissement apparaît. Comment puis-je faire fonctionner le service et regarder le fichier pour les changements?

+0

Avez-vous vérifié le journal des événements de Windows? Une exception doit être enregistrée. De plus, avez-vous débogué le service? –

+0

Quelle est la raison pour laquelle vous mettez manuellement à jour le statut du service? Tout ce travail devrait être fait pour vous automatiquement. –

Répondre

0

Le problème est peut-être que le service par défaut s'exécute sous le compte système. Ainsi, le dossier utilisateur n'est pas ce que vous attendez et il n'y a pas de fichier là.

Habituellement, lorsque le service ne peut pas être démarré, il doit y avoir une erreur avec exception dans le journal des événements. Veuillez le poster ici pour plus d'aide.

+0

Merci, c'était en fait un problème. Le service a recherché un fichier dans un mauvais répertoire car il était en cours d'exécution sous le compte système. Ce dossier était juste un endroit d'essai mais c'était une leçon pour moi de ne pas choisir les emplacements si négligemment! –