我尝试了一段时间,最后放弃了尝试使用 SSIS WMI Event Watcher 任务,只是在脚本任务中编写了等效项。挑战的问题是让 WMI 事件观察器使用我想从配置部分获取的特定用户凭据进行远程连接(而不是硬编码到包中)。
使不使用脚本变得困难的第二个问题是将网络共享简单地转换为服务器上的本地路径名,这是事件观察器所需要的。您会从下面的脚本中看到,一切都是以最少的努力完成的。
请注意,请确保在 ReadOnlyVariables 中包含脚本使用的 DTS.Variables(正常情况下)。下面的代码需要三个 DTS 变量,例如,如果您尝试监视以下位置 \copernicus\dropoff\SAP\Import 中的文件,那么您将设置变量,如下所示:
-
User::ServerName - 共享所在服务器的主机名
(哥白尼)
-
User::ShareName - 网络共享的名称
(下车)
-
User::ImportPath - 目录的目录路径
留意 (/SAP/Import) 中的新文件
public void Main()
{
string localPath = "";
try
{
ConnectionOptions connection = new ConnectionOptions();
connection.Username = "<valid username here>";
connection.Password = "<password here>";
connection.Authority = "ntlmdomain:<your domain name here>";
ManagementScope scope = new ManagementScope(@"\\" + Dts.Variables["User::FileServerName"].Value.ToString() + @"\root\CIMV2", connection);
scope.Connect();
/// Retrieve the local path of the network share from the file server
///
string queryStr = string.Format("SELECT Path FROM Win32_Share WHERE Name='{0}'", Dts.Variables["User::ShareName"].Value.ToString());
ManagementObjectSearcher mosLocalPath = new ManagementObjectSearcher(scope, new ObjectQuery(queryStr));
foreach (ManagementObject elements in mosLocalPath.Get())
{
localPath = elements["Path"].ToString();
}
queryStr = string.Format(
"SELECT * FROM __InstanceCreationEvent WITHIN 10 WHERE Targetinstance ISA 'CIM_DirectoryContainsFile' and TargetInstance.GroupComponent=\"Win32_Directory.Name='{0}{1}'\"",
localPath.Replace(@"\", @"\\"),
Dts.Variables["User::ImportPath"].Value.ToString().Replace(@"\", @"\\")); // query requires each seperator to be a double back slash
ManagementEventWatcher watcher = new ManagementEventWatcher(scope, new WqlEventQuery(queryStr));
ManagementBaseObject eventObj = watcher.WaitForNextEvent();
// Cancel the event subscription
watcher.Stop();
Dts.TaskResult = (int)ScriptResults.Success;
}
catch (ManagementException err)
{
Dts.Events.FireError((int)err.ErrorCode, "WMI File Watcher", "An error occurred while trying to receive an event: " + err.Message, String.Empty, 0);
Dts.TaskResult = (int)ScriptResults.Failure;
}
catch (System.UnauthorizedAccessException unauthorizedErr)
{
Dts.Events.FireError((int)ManagementStatus.AccessDenied, "WMI File Watcher", "Connection error (user name or password might be incorrect): " + unauthorizedErr.Message, String.Empty, 0);
Dts.TaskResult = (int)ScriptResults.Failure;
}
}