简体   繁体   中英

Running .NET Core console app as a service, or redo?

We have orders that come in from a third party encoded UTF-16 LE. Our ERP can only read UTF-8 encoding. So I've created the .NET Core console app that watches the directories the orders arrive in and writes them to where the ERP grabs the files. How do I let this run on our Windows Server 2016? Should I scrap it and write it as a Windows Service?

using System;
using System.IO;

public class RewriteUsingUTF8
{
    public static void Main()
    {
        string ordrstkPath = @"\\Rep-app\sftp_root\supplypro\ordrstk";
        string conrstkPath = @"\\Rep-app\sftp_root\supplypro\Conrstk";
        Watch(ordrstkPath);
        Watch(conrstkPath);
        Console.ReadLine();
    }

    private static void Watch(string path)
    {
        //initialize
        FileSystemWatcher watcher = new FileSystemWatcher();

        //assign parameter path
        watcher.Path = path;

        //create event
        watcher.Created += FileSystemWatcher_Created;
        watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName | NotifyFilters.Size | NotifyFilters.Attributes;

        //only look for csv
        watcher.Filter = "*.csv";

        // Begin watching.
        watcher.EnableRaisingEvents = true;
    }

    // method when event is triggered (file is created)
    private static void FileSystemWatcher_Created(object sender, FileSystemEventArgs e)

    {

        ReadWriteStream(e.FullPath, e.Name);

    }

    private static void ReadWriteStream(string path, string fileName)
    {

        FileStream originalFileStream = new FileStream(path, FileMode.Open, FileAccess.Read);

        //destination path by replacing SFTP user directory
        string destinationPath = path.Replace(@"\supplypro\", @"\ftpuser\");

        FileStream destinationFileStream = new FileStream(destinationPath, FileMode.Create, FileAccess.Write);

        StreamReader streamReader = new StreamReader(originalFileStream);

        StreamWriter streamWriter = new StreamWriter(destinationFileStream);

        string currentLine;

        try
        {
            currentLine = streamReader.ReadLine();
            while (currentLine != null)
            {
                streamWriter.WriteLine(currentLine);
                currentLine = streamReader.ReadLine();
            }

            //archive path
            string archivePath = path.Replace(fileName, @"\archive\" + fileName);

            //move to archive path
            File.Move(path, archivePath);
        }
        catch (Exception e)
        {
            //error path
            string errorPath = path.Replace(fileName, @"\error\" + fileName);

            //move to error path
            File.Move(path, errorPath);

            //need to write code for error to write to event viewer
            Console.WriteLine("Exception: " + e.Message);
        }
        finally
        {
            //dispose resources
            streamReader.Close();
            streamWriter.Close();
            originalFileStream.Close();
            destinationFileStream.Close();
        }

    }

}

I have looked at a few similar posts, but am unsure what direction I should take. Any direction would be greatly appreciated!

Sounds like we're working in very similar environments. We started off using console apps for our ERP integrations. Their main drawbacks are that they run on a user's desktop, so you have to RDP in as that user to manage them, and they don't restart automatically if the server reboots. I've been converting them all to Windows services. .NET Core makes it fairly easy.

Tim Corey has an excellent video about how to write Windows services in .NET Core 3 . He talks about deleting and recreating the service when deploying a new version, but I haven't found that to be necessary. Just RDP in, stop the service so none of the files are in use, deploy, and start it again. It's not as simple as redeploying a .NET Core web app, which manages all the stopping and restarting for you, but it's not too bad.

A crucial thing to know is that exceptions absolutely must not propagate out of Worker.ExecuteAsync . They will not be handled anywhere, and Windows will show your service as running when it's not. Whatever you do in ExecuteAsync , do it in a loop that catches all exceptions and keeps running.

File watchers are deceptively complicated. Make sure you're listening for error events. For example, if you're watching a network share and it becomes unavailable, the FileSystemWatcher will emit an error and will not resume working when the share comes back online. I haven't figured out the best way to handle errors, though. I think making it reliable requires replacing the FileSystemWatcher after any error.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM