将 .Net 6 Windows 窗体应用程序作为 Windows 服务运行

问题描述 投票:0回答:1

我有一个 Windows 窗体应用程序,可以及时调用 Web 服务。我将其作为 Windows 窗体进行,因为跟踪通信和测试更简单。 但现在我需要它作为 Windows 服务运行,这样它就可以安装在 Windows 服务器中并在无人值守的情况下运行。 我见过的样本都是从工人服务项目开始的。但我想让我的 Windows 窗体应用程序作为服务运行。

使用.NET 4.5,我成功构建了一个像这样的服务启动项目:

static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        static void Main()
        {
            ServiceBase[] ServicesToRun;
            ServicesToRun = new ServiceBase[] 
            { 
                new CRDService() 
            };
            ServiceBase.Run(ServicesToRun);
        }
    }

还有像这样的服务加载器:

public partial class CRDService : ServiceBase
    {
        private int processId;
        private string filePath;

        public CRDService()
        {
            InitializeComponent();
        }

        public void Verify(string[] args)
        {
            this.OnStart(args);

            // do something here...  

            this.OnStop();
        }  

        protected override void OnStart(string[] args)
        {
            var location = new Uri(Assembly.GetEntryAssembly().CodeBase).LocalPath;
            var path = Path.GetDirectoryName(location);
            string appName = ConfigurationManager.AppSettings["AppName"];
            var serverPath = Path.Combine(path, appName);
            Process cmd = new Process();
            cmd.StartInfo.FileName = serverPath;
            cmd.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            using (var f = File.Create(Path.Combine(path, "TestFile.txt")))
            {
                filePath = f.Name;
                string msg = "Process started at " + DateTime.Now.ToString();
                f.Write(Encoding.ASCII.GetBytes(msg),0,msg.Length);
            }

            cmd.StartInfo.Arguments = filePath;
            cmd.Start();
            processId = cmd.Id;  
        }

        protected override void OnStop()
        {
            Process process = null;
            try
            {
                process = Process.GetProcessById((int)processId);
            }
            finally
            {
                if (process != null)
                {
                    process.Kill();
                    process.WaitForExit();
                    process.Dispose();
                }

                File.Delete(filePath);
            }  
        }
    }

但这不适用于.NET 6 和BackgroundService。

有人可以告诉我是否有办法在 .NET 6/7 中做到这一点?

windows forms .net-6.0 background-service
1个回答
0
投票

设法解决问题。 这是 .NET 6/7 的相同解决方案。

using GatewayATService;

IHost host = Host.CreateDefaultBuilder(args)
    .UseWindowsService(options =>
    {
        options.ServiceName = "GatewayAT Service";
    })
    .ConfigureServices(services =>
    {
        services.AddHostedService<Worker>();
    })
    .Build();

await host.RunAsync();
public class Worker : BackgroundService
    {
        private readonly ILogger<Worker> _logger;
        private readonly Task _completedTask = Task.CompletedTask;

        private int processId;
        private string filePath;

        public Worker(ILogger<Worker> logger)
        {
            _logger = logger;
        }

        public override Task StartAsync(CancellationToken cancellationToken)
        {
            _logger.LogInformation("GatewayAT Service is starting.");

            var location = new Uri(System.AppDomain.CurrentDomain.BaseDirectory).LocalPath;
            var path = Path.GetDirectoryName(location);
            //string appName = ConfigurationManager.AppSettings["AppName"];
            var builder = new ConfigurationBuilder()
                        .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
            IConfiguration config = builder.Build();
            string appName = config.GetValue<string>("AppName");

            var serverPath = Path.Combine(path, appName);
            Process cmd = new Process();
            cmd.StartInfo.FileName = serverPath;
            cmd.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            using (var f = File.Create(Path.Combine(path, "log.txt")))
            {
                filePath = f.Name;
                string msg = "Process started at " + DateTime.Now.ToString();
                f.Write(Encoding.ASCII.GetBytes(msg), 0, msg.Length);
            }

            cmd.StartInfo.Arguments = filePath;
            cmd.Start();
            processId = cmd.Id;

            return _completedTask;
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
                await Task.Delay(1000, stoppingToken);
            }
        }

        public override Task StopAsync(CancellationToken cancellationToken)
        {
            _logger.LogInformation("GatewayAT Service is stopping.");
            Process process = null;
            try
            {
                process = Process.GetProcessById((int)processId);
            }
            finally
            {
                if (process != null)
                {
                    process.Kill();
                    process.WaitForExit();
                    process.Dispose();
                }

                File.Delete(filePath);
            }
            return _completedTask;
        }
    }
``
`
© www.soinside.com 2019 - 2024. All rights reserved.