我正在使用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