首页 > 解决方案 > 如何在 .Net/C# Windows 服务停止时触发 Python 或 C# 脚本运行?

问题描述

我们有 ac#/.net Windows 服务,它为我们解析大日志文件并在这样做时更新元表。问题是每当您需要停止服务或(服务,我们有多个正在运行)时,必须手动删除本地文件夹中正在解析的文件,并更新它跟踪的队列 DB 表要处理的文件。

我想自动化这个。理想情况下,我对python更加熟悉,它将是一个python脚本而不是.net。是否可以有一个脚本在服务停止时触发?如何做到这一点?

我曾尝试在 .net 服务内部执行此操作,但由于它是多线程的,因此文件不会被整齐地清理。总是有一个“无法停止服务,因为另一个进程正在使用它”。就像调用 Onstop() 方法时服务在尝试删除文件时卡住了一样。这就是我尝试在服务内部执行此操作的方式:

protected override void OnStop()
        {
            ProducerConsumerQueue.Dispose();

            Logger.Info($"{ProducerConsumerQueue.Count()} logs will be canceled");

            CancellationTokenSource.Cancel();

            FileUtil.DeleteFilesInProgress(Constants.ODFS_STAGING);

            MetadataDbContext.UpdateServiceEntriesOnServiceReset();

            //look into some staging directory, delete all files. 

            Logger.Info($"{ProducerConsumerQueue.Count()} logs canceled");
        }


 public static void DeleteFilesInProgress(string directory)
        {
            var constantsutil = new ConstantsUtil();
            constantsutil.InitializeConfiguration();
            try
            {
                System.IO.DirectoryInfo di = new DirectoryInfo(directory);
                foreach (FileInfo file in di.GetFiles())
                {
                    file.Delete();
                }
            }
            catch(Exception ex)
            {
                Logger.Error(ex.Message);
                string subject = Constants.GENERAL_EMAIL_SUBJECT;
                string body = "The following error occured in Client.Util.ConstantsUtil:";
                string error = ex.ToString();  //ex.ToString makes it more verbose so you can trace it.
                var result = EmailUtil.Emailalert(subject, body, error);

            }
        }


public static int UpdateServiceEntriesOnServiceReset()
        {
            int rowsAffected = 0;

            try
            {
                string connectionString = GetConnectionString();

                using (SqlConnection connection = new SqlConnection())
                {
                    connection.ConnectionString = connectionString;

                    SqlCommand cmd = new SqlCommand();
                    cmd.CommandType = CommandType.Text;
                    cmd.CommandText = $"UPDATE {Constants.SERVICE_LOG_TBL} SET STATUS = '0'";

                    cmd.Connection = connection;

                    connection.Open();
                    rowsAffected = cmd.ExecuteNonQuery();
                }
            }
            catch (Exception ex)
            {
                Logger.Error($"{ex.Message.ToString()}");
                string subject = Constants.GENERAL_EMAIL_SUBJECT;
                string body = "The following error occured in Client.MetadatDbContext while Parser was processing:";
                string error = ex.ToString();  //ex.ToString makes it more verbose so you can trace it.
                var result = EmailUtil.Emailalert(subject, body, error);
            }

            return rowsAffected;
        }

标签: pythonc#.netpython-3.x

解决方案


您可以从以下位置运行脚本OnStop

using System.Diagnostics;

Process.Start("python yourscript.py"); 
// or whatever the command for executing your python script is on your system.

pywin32然后使用's之类的东西win32service来找出启动脚本的服务的状态,然后等待它死亡并释放对文件的持有。

然后擦拭它们。


推荐阅读