C# WMI在C中查询无效,但在wbemtest实用程序中工作
我正在尝试创建一个WQLEventQuery,以便在C小程序中运行,该程序在指定文件夹中创建新文件夹时触发。我以前使用过WMI,我很熟悉它的工作原理。在将新文件添加到特定文件夹时,我成功创建了相同类型的eventquery。奇怪的是,我在调试中运行小程序时遇到了一个异常,但是如果我从windows中内置的“wbemtest”实用程序中执行相同的查询,那么在删除INTERVICE子句时不会抛出任何“invalid query”。但是,如果我没有在C代码中对WQLEventQuery对象设置WithinInterval属性,则会引发与所需轮询间隔相关的另一个异常。以下是上下文的一些代码片段: FolderMonitor.csC# WMI在C中查询无效,但在wbemtest实用程序中工作,c#,.net,wmi,wmi-query,C#,.net,Wmi,Wmi Query,我正在尝试创建一个WQLEventQuery,以便在C小程序中运行,该程序在指定文件夹中创建新文件夹时触发。我以前使用过WMI,我很熟悉它的工作原理。在将新文件添加到特定文件夹时,我成功创建了相同类型的eventquery。奇怪的是,我在调试中运行小程序时遇到了一个异常,但是如果我从windows中内置的“wbemtest”实用程序中执行相同的查询,那么在删除INTERVICE子句时不会抛出任何“invalid query”。但是,如果我没有在C代码中对WQLEventQuery对象设置With
using System;
using System.Configuration;
using System.Management;
using MyProject.core.interfaces;
namespace MyProject.monitor.WmiEventMonitors
{
public class FolderMonitor : IWQLMonitor
{
private const string _eventClassName = "__InstanceCreationEvent";
private const string _isaType = "Win32_SubDirectory";
private readonly IEventListenerManager _eListenerManager;
private readonly IFileProcessService _fileProcessService;
public WqlEventQuery Query { get; }
public string Path { get; }
public FolderMonitor(string path, IEventListenerManager eListenerManager, IFileProcessService fileProcessService)
{
_eListenerManager = eListenerManager;
_fileProcessService = fileProcessService;
if (string.IsNullOrEmpty(path))
path = GetConfiguredDirectory();
Path = path;
var queryParamPath = path.Replace(@"\", @"\\");
//Query = new WqlEventQuery();
//Query.QueryString = $@"Select * From {_eventClassName} Within 1 Where TargetInstance Isa '{_isaType}' And TargetInstance.GroupComponent = 'Win32_Directory.Name={queryParamPath}'";
Query = new WqlEventQuery
{
EventClassName = _eventClassName,
Condition = $"TargetInstance isa '{_isaType}' And TargetInstance.GroupComponent = 'Win32_Directory.Name={queryParamPath}'"
WithinInterval = new TimeSpan(0,5,0)
};
}
public void HandleEvent(object sender, EventArrivedEventArgs e)
{
// when a new subfolder is created:
// 1) Log it somewhere?
// 2) Create a new WMI listener for that subfolder to detect file creation
string newDirPath = null;
try
{
foreach (PropertyData pd in e.NewEvent.Properties)
{
if (pd.Name != "TargetInstance") continue;
ManagementBaseObject mbo;
if ((mbo = pd.Value as ManagementBaseObject) != null)
{
using (mbo)
{
var newSubDir = mbo.Properties["PartComponent"];
var newDir = newSubDir.Value as ManagementBaseObject;
newDirPath = $"{newDir.Properties["Drive"].Value}{newDir.Properties["Path"].Value}";
}
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
throw;
}
if (!string.IsNullOrEmpty(newDirPath))
{
var newFileMonitorEvent = new FileMonitor(newDirPath, _fileProcessService);
_eListenerManager.Add(newFileMonitorEvent);
}
}
private static string GetConfiguredDirectory()
{
return ConfigurationManager.AppSettings["Directory"].Trim();
}
}
}
我的事件注册课
using System;
using System.Management;
using MyProject.monitor.WmiEventMonitors;
namespace MyProject.monitor
{
public interface IFileMonitorEventRegistrar
{
ManagementEventWatcher RegisterEventListener(IWQLMonitor newMonitorCandidate);
bool UnregisterEventListener(ManagementEventWatcher listener);
}
public class FileMonitorEventRegistrar : IFileMonitorEventRegistrar
{
public ManagementEventWatcher RegisterEventListener(IWQLMonitor newMonitorCandidate)
{
var scope = WmiUtility.GetConnectionScope();
ManagementEventWatcher watcher = null;
try
{
watcher = new ManagementEventWatcher(scope, newMonitorCandidate.Query);
watcher.EventArrived += new EventArrivedEventHandler(newMonitorCandidate.HandleEvent);
watcher.Start();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
throw;
}
return watcher;
}
public bool UnregisterEventListener(ManagementEventWatcher listener)
{
listener.Stop();
listener.Dispose();
return true;
}
}
}
我的WMI实用程序类
using System;
using System.Management;
namespace MyProject.monitor
{
public static class WmiUtility
{
private static ManagementScope _connectionScope;
private static ConnectionOptions _connectionOptions;
public static ManagementScope GetConnectionScope()
{
EstablishConnection(null, null, null, Environment.MachineName);
return _connectionScope;
}
private static ConnectionOptions SetConnectionOptions()
{
return new ConnectionOptions
{
Impersonation = ImpersonationLevel.Impersonate,
Authentication = AuthenticationLevel.Default,
EnablePrivileges = true
};
}
private static ManagementScope SetConnectionScope(string machineName, ConnectionOptions options)
{
ManagementScope connectScope = new ManagementScope();
connectScope.Path = new ManagementPath(@"\\" + machineName + @"\root\CIMV2");
connectScope.Options = options;
try
{
connectScope.Connect();
}
catch (ManagementException e)
{
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
throw;
}
return connectScope;
}
private static void EstablishConnection(string userName, string password, string domain, string machineName)
{
_connectionOptions = SetConnectionOptions();
if (domain != null || userName != null)
{
_connectionOptions.Username = domain + "\\" + userName;
_connectionOptions.Password = password;
}
_connectionScope = SetConnectionScope(machineName, _connectionOptions);
}
}
}
我的EventQuery管理器类
using System;
using System.Collections.Generic;
using System.Management;
using MyProejct.monitor.WmiEventMonitors;
namespace MyProject.monitor
{
public interface IEventListenerManager : IDisposable
{
IDictionary<string, ManagementEventWatcher> RegisteredEvents { get; }
bool Add(IWQLMonitor eListener);
bool Remove(string monitoredPath);
}
public class EventListenerManager : IEventListenerManager
{
private bool _disposed;
private readonly IFileMonitorEventRegistrar _eventRegistrar;
public IDictionary<string, ManagementEventWatcher> RegisteredEvents { get; }
public EventListenerManager(IFileMonitorEventRegistrar eventRegistrar)
{
_eventRegistrar = eventRegistrar;
RegisteredEvents = new Dictionary<string, ManagementEventWatcher>();
}
public bool Add(IWQLMonitor eListener)
{
RegisteredEvents.Add(eListener.Path, _eventRegistrar.RegisterEventListener(eListener));
return true;
}
public bool Remove(string monitoredPath)
{
if (RegisteredEvents.ContainsKey(monitoredPath))
{
_eventRegistrar.UnregisterEventListener(RegisteredEvents[monitoredPath]);
return RegisteredEvents.Remove(monitoredPath);
}
return true;
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
foreach (var item in RegisteredEvents)
{
Remove(item.Key);
}
}
_disposed = true;
}
}
public void Dispose()
{
Dispose(true);
}
}
}
因此,查询字符串本质上是
从1中的uu InstanceCreationEvent中选择*其中TargetInstance为“Win32_子目录”,TargetInstance.GroupComponent='Win32_目录。Name=C:\\MonitoredDocs'
如果获取该查询字符串并删除INTERNAIN子句,wbemtest将其作为有效的WMI查询接受。当INTERNAIN子句存在时,它表示这是一个无效的查询。我使用的是来自的答案。如果您能帮助我找出如何使用此WQL事件查询,我将不胜感激。因此,我更专注地阅读了我在上面发布的文章,并找到了一个实际可行的替代查询。查询字符串如下所示: 从1中的uu InstanceCreationEvent中选择*其中TargetInstance为'Win32_Directory',TargetInstance.Drive为'C',TargetInstance.Path为'\\Path\\to\\monitored\\Directory\' *一个可能令人困惑的细节是路径值必须包含尾随字符\\ 就代码而言,我修改过的FolderMonitor.cs类如下所示:用*!*标记的更改*
public class FolderMonitor : IWQLMonitor
{
private const string _eventClassName = "__InstanceCreationEvent";
*!*!*private const string _isaType = "Win32_Directory";*!*!*
private readonly IEventListenerManager _eListenerManager;
private readonly IFileProcessService _fileProcessService;
public WqlEventQuery Query { get; }
public string Path { get; }
public FolderMonitor(string path, IEventListenerManager eListenerManager, IFileProcessService fileProcessService)
{
_eListenerManager = eListenerManager;
_fileProcessService = fileProcessService;
if (string.IsNullOrEmpty(path))
path = GetConfiguredDirectory();
Path = path;
*!*!*var drive = Path.Substring(0, 2);*!*!*
*!*!*var queryPath = Path.Substring(2) + @"\";*!*!*
var queryParamPath = queryPath.Replace(@"\", @"\\");
Query = new WqlEventQuery
{
EventClassName = _eventClassName,
*!*!*Condition = $"TargetInstance Isa '{_isaType}' And TargetInstance.Drive = '{drive}' And TargetInstance.Path = '{queryParamPath}'",*!*!*
WithinInterval = new TimeSpan(0,0,1)
};
}
}
public class FolderMonitor : IWQLMonitor
{
private const string _eventClassName = "__InstanceCreationEvent";
*!*!*private const string _isaType = "Win32_Directory";*!*!*
private readonly IEventListenerManager _eListenerManager;
private readonly IFileProcessService _fileProcessService;
public WqlEventQuery Query { get; }
public string Path { get; }
public FolderMonitor(string path, IEventListenerManager eListenerManager, IFileProcessService fileProcessService)
{
_eListenerManager = eListenerManager;
_fileProcessService = fileProcessService;
if (string.IsNullOrEmpty(path))
path = GetConfiguredDirectory();
Path = path;
*!*!*var drive = Path.Substring(0, 2);*!*!*
*!*!*var queryPath = Path.Substring(2) + @"\";*!*!*
var queryParamPath = queryPath.Replace(@"\", @"\\");
Query = new WqlEventQuery
{
EventClassName = _eventClassName,
*!*!*Condition = $"TargetInstance Isa '{_isaType}' And TargetInstance.Drive = '{drive}' And TargetInstance.Path = '{queryParamPath}'",*!*!*
WithinInterval = new TimeSpan(0,0,1)
};
}
}