python - 如何在 .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;
}
解决方案
您可以从以下位置运行脚本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
来找出启动脚本的服务的状态,然后等待它死亡并释放对文件的持有。
然后擦拭它们。
推荐阅读
- r - 在频率表中搜索特定单词
- c++ - 将 octomap 转换为 .fbx 或 .obj
- mapr - 无法从 MapR Data Science Refinery docker 容器访问 HDFS
- google-cloud-platform - 如何使用 PUBSUB 作为触发器从 Google Cloud 函数返回 JSON?
- mpls - 在启用 mpls 的路由器上配置 LDP
- ios - 在视图出现之前,我可以在哪里将 contentOffset 设置为 UICollectionView 中的最后一项?
- mysql - 如何比较列并在表中计数
- cassandra - Cassandra 浮点精度
- c# - UWP 无法更改 C# 代码中的图像源
- java - 为什么 onReceivedError() 不适用于所有 Android 手机?