2016-09-16 6 views
0

Я написал код WMI, который отлично работает на большинстве машин. Однако на некоторых машинах (почти на всех SSD-маках) этот код вызывает проблему с HUGE. Это приводит к тому, что процесс WMIPrvSe продолжает работать с I/O Other. Если вы запустите другое приложение, выполняющее одно и то же наблюдение, оно замедлит сканирование до такой степени, когда программное обеспечение становится непригодным.Проблемы с производительностью событий WMI Event

  System.Management.WqlEventQuery  queryIn; 
      System.Management.WqlEventQuery  queryOut; 
      System.Management.ManagementScope scope = new System.Management.ManagementScope("root\\CIMV2"); 
      scope.Options.EnablePrivileges  = true; 

      try 
      { 
       queryIn = new System.Management.WqlEventQuery(); 
       queryIn.EventClassName   = "__InstanceCreationEvent"; 
       queryIn.WithinInterval   = new TimeSpan(0, 0, 1); 
       //queryIn.GroupWithinInterval  = new TimeSpan(0, 0, 0); 
       queryIn.Condition    = @"TargetInstance ISA 'Win32_DiskDrive' AND TargetInstance.InterfaceType = 'USB'"; 
       mUSBWatcherIn = new System.Management.ManagementEventWatcher(scope, queryIn); 

       //adds event handler that’s is fired when the insertion event occurs 
       mUSBWatcherIn.EventArrived += new System.Management.EventArrivedEventHandler(USBInserted); 

       queryOut = new System.Management.WqlEventQuery(); 
       queryOut.EventClassName   = "__InstanceDeletionEvent"; 
       queryOut.WithinInterval   = new TimeSpan(0, 0, 1); 
       //queryOut.GroupWithinInterval = new TimeSpan(0, 0, 0); 
       queryOut.Condition    = @"TargetInstance ISA 'Win32_DiskDrive' AND TargetInstance.InterfaceType = 'USB'"; 
       mUSBWatcherOut = new System.Management.ManagementEventWatcher(scope, queryOut); 

       //adds event handler that’s is fired when the insertion event occurs 
       mUSBWatcherOut.EventArrived += new System.Management.EventArrivedEventHandler(USBRemoved); 

       mUSBWatcherIn.Start();//run the watcher 
       mUSBWatcherOut.Start(); 
      } 
      catch (Exception e) 
      { 
       System.Windows.Forms.MessageBox.Show(e.Message); 
       StopUSBWatcher(); 
      } 

Кто-нибудь знает, что может быть здесь? Если я удалю этот код, тогда он отлично работает. На других машинах он работает отлично. Это очень странно. Любые идеи чрезвычайно оценены!

ответ

0

поэтому я не определился с тем, что вызвало проблему, но теперь я реализовал идентичные функции с помощью WM_DEVICECHANGE.

Вот моя установка Interop:

[System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall)] 
    private static extern IntPtr RegisterDeviceNotification(IntPtr recipient, IntPtr notificationFilter, int flags); 

    [System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall)] 
    private static extern bool UnregisterDeviceNotification(IntPtr handle); 

    [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)] 
    static extern IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex); 

    [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)] 
    static extern int GetWindowLong(IntPtr hWnd, int nIndex); 

    [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)] 
    static extern IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr newLong); 

    [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)] 
    static extern int SetWindowLong(IntPtr hWnd, int nIndex, int newLong); 


    delegate IntPtr WndProcDelegate(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam); 

    [System.Runtime.InteropServices.DllImport("user32.dll")] 
    static extern IntPtr CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); 

    public const int    GWLP_WNDPROC = -4; 

    [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)] 
    private struct DevBroadcastDeviceinterface 
    { 
     internal int Size; 
     internal int DeviceType; 
     internal int Reserved; 
     internal Guid ClassGuid; 
     internal short Name; 
    } 

    const int DBT_DEVTYPVOLUME = 0x00000002; 
    const int DBT_DEVTYPDEVICEINTERFACE = 5; 

    static readonly Guid GuidDevinterfaceUSBDevice = new Guid("A5DCBF10-6530-11D2-901F-00C04FB951ED"); 

И фактический код настройки выглядит следующим образом:

 DevBroadcastDeviceinterface dbi = new DevBroadcastDeviceinterface 
      { 
       DeviceType = DBT_DEVTYPDEVICEINTERFACE,//DBT_DEVTYPVOLUME, 
       Reserved = 0, 
       ClassGuid = GuidDevinterfaceUSBDevice, 
       Name = 0 
      }; 

     dbi.Size = System.Runtime.InteropServices.Marshal.SizeOf(dbi); 
     IntPtr buffer = System.Runtime.InteropServices.Marshal.AllocHGlobal(dbi.Size); 
     System.Runtime.InteropServices.Marshal.StructureToPtr(dbi, buffer, true); 

     IntPtr i = RegisterDeviceNotification(Handle, buffer, 0); 

     System.Runtime.InteropServices.Marshal.FreeHGlobal(buffer); 

     if (IntPtr.Size == 4) 
     { 
      oldWndProc = new IntPtr(SetWindowLong(Handle, GWLP_WNDPROC, System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate(newWndProc).ToInt32())); 
     } 
     else 
     { 
      oldWndProc = SetWindowLongPtr(Handle, GWLP_WNDPROC, System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate(newWndProc)); 
     }