目录监视服务控制 SSIS 包执行





5.00/5 (3投票s)
基于 WMI 的 DirectoryMonitor 触发 SSIS 包执行。
引言
让我介绍一个场景,如果我们将新文件添加到特定目录,我们需要触发一个 SSIS 包。 这里我们需要有一个监控服务始终运行并检测更改并触发包。 所以本文解释了如何实现这一点。
背景
本文是我另一篇文章 使用 SSIS 动态加载 Excel 文件的评论/问题的答案。
使用代码
让我们定义一下要完成的目标的一些重要方面
- 创建一个 Windows 服务并始终监控所需文件夹的更改。 所以这一步是 WMI 事件和 Windows 服务的组合。
- 基于步骤 1 中的事件触发一个包。
一些 与 Windows 服务相关的基本提示
安装
- 打开 Visual Studio 命令提示符(开始>所有程序> Vistal Studio 20xx> Visual Studio 工具> Visual Studio 命令提示符)。
- 在命令提示符下键入以下内容以安装服务
installutil "C:\Folder1\Folder2\Yourservice.exe"
卸载
- 打开 Visual Studio 命令提示符(开始>所有程序> Vistal Studio 20xx> Visual Studio 工具> Visual Studio 命令提示符)。
- 在命令提示符下键入以下内容以卸载该服务。
installutil /u "C:\Folder1\Folder2\Yourservice.exe"
启动/停止 Windows 服务
- 打开命令提示符(开始>运行类型在 cmd 中 将启动命令提示符)。
- 下一篇
- 启动服务
- 停止服务
net start Yourservicename
net stop Yourservicename
修改设置
任何动态设置修改(例如修改配置条目)只有在您停止并启动服务后才会反映出来。
制定 WMI 查询
让我们构建一个查询来监视任何文件创建(您也可以将文件复制到该位置)
string WMIQuery = "SELECT * FROM __InstanceCreationEvent WITHIN 10 "
+ " WHERE TargetInstance ISA \"CIM_DirectoryContainsFile\" and "
+ " TargetInstance.GroupComponent= "
+ " \"Win32_Directory.Name='C:\\Test\\MyFolderToMonitor'\"";
上面的 WMI 查询将捕获在指定文件夹中 10 秒内发生的任何文件创建事件。
从 C# 执行 SSIS
我们可以使用 Microsoft.SQLServer.ManagedDTS(通常位置是:C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies\Microsoft.SQLServer.ManagedDTS.dll)库从 C# 执行包。
让我们构建一个小类来做到这一点。 请看下面的类来了解它是如何工作的。 就这么简单 加载提供的路径中的包,并使用 Package 对象的 Execute 方法。
using Microsoft.SqlServer.Dts.Runtime;
namespace DirectoryMonitorService
{
public class PackageExecuter
{
Package pkg;
Application app;
DTSExecResult pkgResults;
public PackageExecuter()
{
}
public void Run()
{
app = new Application();
pkg = app.LoadPackage("PackagePath", null);
pkgResults = pkg.Execute();
}
}
}
如何使服务更灵活
您应该能够
- 更改/修改“要监视的目录”的路径
- 控制 WMI 查询间隔时间
- 控制 WMI 轮询线程睡眠时间
- 控制要执行的包
- 控制服务和包日志路径的位置
以上所有内容都可以通过以下简单配置文件进行控制
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="DirectoryToMonitor" value="C:\Test\DirMon">
<!--Set the directory path to be monitored by the service -->
</add>
<add key="WMIThreadSleepTimer" value="2">
<!--Set the value of the ThreadSleep in Seconds -->
</add>
<add key="WMISQueryInterval" value="2">
<!--Set the value of the WMI Query Interval in Seconds -->
</add>
<add key="ServiceLogSaveLocation" value="C:\Test\Logs">
<!--Set the path to save service log entries -->
</add>
<add key="EnableLogging" value="true">
<!--Set true or false to enable/disable logging -->
</add>
<add key="PackageToExecute" value="C:\test\KP\Package.dtsx">
<!--Set the path for SSIS package to be executed by the service -->
</add>
<add key="PackageLogSaveLocation" value="C:\Test\Logs">
<!--Set the directory path to be monitored by the service -->
</add>
<add key="SavePackageExecutionLog" value="true">
<!--Set true or false to enable/disable -->
</add>
</appSettings>
</configuration>
管理/处理配置
我们可以构建一个小类来管理配置并保持其准备就绪,以便随时使用,而无需再次进入配置。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Xml;
using System.Configuration;
using System.Collections.Specialized;
using System.Collections;
namespace DirectoryMonitorService
{
public class ConfigReader
{
const string DirectoryToMonitor = "DirectoryToMonitor";
const string WMIThreadSleepTimer = "WMIThreadSleepTimer";
const string ServiceLogSaveLocation = "ServiceLogSaveLocation";
const string WMISQueryInterval = "WMISQueryInterval";
const string EnableLogging = "EnableLogging";
const string SavePackageExecutionLog = "SavePackageExecutionLog";
const string PackageToExecute = "PackageToExecute";
const string PackageLogSaveLocation = "PackageLogSaveLocation";
const string PackageProperties = "/configuration/PackageProperties";
const string ServiceProperties = "/configuration/ServiceProperties";
private string _directoryPath = "";
public string DirectoryPath
{
get { return _directoryPath; }
set { _directoryPath = value; }
}
private string _configPath = "";
public string ConfigPath
{
get { return _configPath; }
set { _configPath = value; }
}
private bool _saveLog = false;
public bool SaveLog
{
get { return _saveLog; }
set { _saveLog = value; }
}
private string _logPath = "";
public string LogPath
{
get { return _logPath; }
set { _logPath = value; }
}
private int _threadSleep=2000;
public int ThreadSleep
{
get { return _threadSleep; }
set { _threadSleep = value; }
}
private int _queryInterval=10;
public int QueryInterval
{
get { return _queryInterval; }
set { _queryInterval = value; }
}
private string _packagePath = "";
public string PackagePath
{
get { return _packagePath; }
set { _packagePath = value; }
}
private bool _saveResults = false;
public bool SaveResults
{
get { return _saveResults; }
set { _saveResults = value; }
}
private string _packageExecutionResultSavePath = "";
public string PackageExecutionResultSavePath
{
get { return _packageExecutionResultSavePath; }
set { _packageExecutionResultSavePath = value; }
}
private Dictionary<string, string> execArgs;
public ConfigReader()
{
BuildConfiguration();
}
private void BuildConfiguration()
{
execArgs = new Dictionary<string, string>();
// Get the appSettings.
NameValueCollection appSettings = ConfigurationManager.AppSettings;
IEnumerator appSettingsEnum = appSettings.Keys.GetEnumerator();
int i = 0;
Console.WriteLine("App settings.");
while (appSettingsEnum.MoveNext())
{
string key = appSettings.Keys[i];
string value = appSettings[key];
execArgs.Add(key, value);
i += 1;
}
this.DirectoryPath = execArgs[DirectoryToMonitor];
this.SaveLog = bool.Parse(execArgs[EnableLogging]);
this.LogPath = execArgs[ServiceLogSaveLocation];
this.ThreadSleep = Int32.Parse(execArgs[WMIThreadSleepTimer]) * 1000;
this.QueryInterval = Int32.Parse(execArgs[WMISQueryInterval]);
this.PackagePath = execArgs[PackageToExecute];
this.SaveResults = bool.Parse(execArgs[SavePackageExecutionLog]);
this.PackageExecutionResultSavePath = execArgs[PackageLogSaveLocation];
}
}
}
入口点
让我们定义它具有完全的灵活性来记录事件
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Diagnostics;
using System.Configuration;
namespace DirectoryMonitorService
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
try
{
ConfigReader config = new ConfigReader();
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new DirectoryMonitorService(config)
};
ServiceBase.Run(ServicesToRun);
}
catch (Exception ex)
{
EventLog m_EventLog = new EventLog("");
m_EventLog.Source = "DirectoryMonitorService";
m_EventLog.WriteEntry(ex.ToString(), EventLogEntryType.Error);
}
}
}
}
请 查找附加的完全成熟的工作代码。