我正在使用C#应用程序来监视从特定文件夹启动的进程,并且我正在使用WMI进行监视。我的WMI查询就像如何防止WMI配额溢出?
SELECT * FROM __InstanceCreationEvent WITHIN 5 WHERE TargetInstance ISA 'Win32_Process' AND TargetInstance.ExecutablePath LIKE '{0}%'
其中我将参数替换为文件夹的路径,而该文件夹用于进行扇区间隔。 WMI查询工作正常,我正在订阅事件通知,以便在特定文件夹的进程出现时执行一些额外的处理。监控工具运行良好几个小时后,我开始在我的应用程序中获得WMI QuotaViolation
例外。一旦发生这种情况,我需要重新启动Windows Management Instrumentation
服务才能正常工作。 我最初使用
`SELECT * FROM __InstanceCreationEvent WITHIN 5 WHERE TargetInstance ISA 'Win32_Process'`
查询,然后检查事件通知的过程文件夹,在查询修改做希望它会减少结果集,因此防止违反配额的情况。
是否有任何方法定期刷新WMI配额或其他方法来防止QuotaViolation?处理QuotaViolation情况的最佳方式是什么?
编辑: 这是我的过程监控器对象:
public class ProcessWatcher : ManagementEventWatcher
{
private string folder = "";
// Process Events
public event ProcessEventHandler ProcessCreated; //notifies process creation
//add any more event notifications required here
// WMI WQL process query strings
static readonly string WMI_OPER_EVENT_QUERY = @"SELECT * FROM __InstanceCreationEvent WITHIN 5 WHERE TargetInstance ISA 'Win32_Process'";
static readonly string WMI_OPER_EVENT_QUERY_WITH_PROC =
WMI_OPER_EVENT_QUERY + " and TargetInstance.Name = '{0}'";
public ProcessWatcher(string basepath)
{
folder = basepath;
Init(string.Empty);
}
public ProcessWatcher(string processName, string basepath)
{
folder = basepath;
Init(processName);
}
private void Init(string processName)
{
this.Query.QueryLanguage = "WQL";
if (string.IsNullOrEmpty(processName))
{
this.Query.QueryString = string.Format(WMI_OPER_EVENT_QUERY + @" AND TargetInstance.ExecutablePath LIKE '{0}%'", folder.Replace(@"\",@"\\")) ;
}
else
{
this.Query.QueryString =
string.Format(WMI_OPER_EVENT_QUERY_WITH_PROC, processName);
}
this.EventArrived += new EventArrivedEventHandler(watcher_EventArrived);
}
private void watcher_EventArrived(object sender, EventArrivedEventArgs e)
{
try
{
ManagementBaseObject mObj = e.NewEvent["TargetInstance"] as ManagementBaseObject;
if (mObj != null)
{
Win32_Process proc = new Win32_Process(mObj);
if (proc != null)
{
folder = folder.ToLower() ?? "";
string exepath = (string.IsNullOrEmpty(proc.ExecutablePath)) ? "" : proc.ExecutablePath.ToLower();
if (!string.IsNullOrEmpty(folder) && !string.IsNullOrEmpty(exepath) && exepath.Contains(folder))
{
if (ProcessCreated != null) ProcessCreated(proc);
}
}
proc.Dispose();
}
mObj.Dispose();
}
catch(Exception ex) { throw; }
finally
{
e.NewEvent.Dispose();
}
}
我在应用程序启动创建ProcessWatcher
对象,在视图模型构造,如:
watch = new ProcessWatcher(BasePath);
watch.ProcessCreated += new ProcessEventHandler(procWatcher_ProcessCreated);
watch.Start();
开始通话是哪里如果我尝试第二次启动它而不重新启动WMI,则会引发QuotaViolation
。 在应用程序退出时,我处置掉ProcessWatcher
对象,如:
watch.Stop();
watch.Dispose();
的相关堆栈跟踪:
异常的InnerException [System.Management.ManagementException:配额违反
在System.Management .ManagementException.ThrowWithExtendedInfo(ManagementStatus errorCode)
at System.Management.ManagementEventWatcher.Start()
在App.ProcessTabViewModel1..ctor()
听起来像是你缺少物/关闭通话的地方... – 2014-10-07 09:40:24
@SoMoS我的事件观察仍然在整个应用程序的生命周期当应用程序关闭时我正在处理它们。但是这是在应用程序的一次运行中发生的。这种方法有什么问题吗? – jester 2014-10-07 12:07:27
您做错了的可能性很高,我需要查看异常的片段和堆栈跟踪。预期的文件,当你难以解释系统错误。 – 2014-10-10 09:42:29