2012-03-08 117 views
0

我正在學習C#,我需要幫助。 我的問題:如何知道USB磁盤是否已安裝/未安裝? 我找到了答案WndProd監控一個端口的USB,沒有WinForm,只有控制檯應用程序

const int WM_DEVICECHANGE   = 0x0219; 
    const int DBT_DEVICEARRIVAL   = 0x8000; 
    const int DBT_DEVICEREMOVECOMPLETE = 0x8004; 

    [StructLayout(LayoutKind.Sequential)] 
    public struct DEV_BROADCAST_HDR 
    { 
     public int dbch_size; 
     public int dbch_devicetype; 
     public int dbch_reserved; 
    } 

    protected override void WndProc(ref Message m) 
    { 
     if (m.Msg == WM_DEVICECHANGE) 
     { 
      int EventCode = m.WParam.ToInt32(); 
      Log(string.Format("WM_DEVICECHANGE. Код={0}", EventCode)); 

      switch (EventCode) 
      { 
       case DBT_DEVICEARRIVAL: 
       { 
        Log("Добавление устройства"); 
        break; 
       } 
       case DBT_DEVICEREMOVECOMPLETE: 
       { 
        Log("Удаление устройства"); 
        break; 
       } 
      } 
     } 
     base.WndProc (ref m); 

    } 

這個版本

public class WMIReceiveEvent 
    { 
     public WMIReceiveEvent() 
     { 
      try 
      { 
       WqlEventQuery query = new WqlEventQuery("SELECT * FROM Win32_DeviceChangeEvent"); 

       ManagementEventWatcher watcher = new ManagementEventWatcher(query); 
       Console.WriteLine("Waiting for an event..."); 

       watcher.EventArrived += new EventArrivedEventHandler(HandleEvent); 

       // Start listening for events 
       watcher.Start(); 

       // Do something while waiting for events 
       System.Threading.Thread.Sleep(20000); 

       // Stop listening for events 
       //watcher.Stop(); 
       //return; 
      } 
      catch (ManagementException err) 
      { 

      } 
     } 

     private void HandleEvent(object sender, EventArrivedEventArgs e) 
     { 
      Console.WriteLine("Win32_DeviceChangeEvent event occurred. "+ e.NewEvent.ClassPath.ClassName.ToString()); 
      Console.WriteLine("2_Win32_DeviceChangeEvent event occurred. " + e.NewEvent.Properties.ToString()); 
      Console.ReadLine(); 
     }    

    } 

但我想版本DBT_DEVICEARRIVALDBT_DEVICEREMOVECOMPLETE沒有WinForm的。因爲對於WndProc需要System.Windows.Form和Class必須是繼承人「:表格」 而對於WMIReceiveEvent不是我的任務的最佳解決方案。

回答

1

爲此編寫控制檯應用程序的問題是它沒有消息循環(至少,不是默認情況下;您必須自己編寫)。

更簡單的解決方案是創建一個Windows窗體項目,但只是不顯示任何窗體。你基本上會創建一個不顯示任何用戶界面的「背景」應用程序。 WinForms應用程序自動爲您提供一個消息泵,使您能夠捕捉到您感興趣的消息。

+0

非常感謝您的快速響應。以及如何自己寫一個消息循環?或如何在ConsoleApp中使用「背景」應用程序(如果它是後續的「:Form」)?謝謝 – 2012-03-08 08:47:57

-1

根據您的應用程序的要求,您不妨進行輪詢。爲您打造一個循環檢查所有可能的驅動器盤符像

System.IO.Directory.Exists(爲驅動器);

並將其與現有的驅動器號數組或結構或其他相比較。創建一個事件,只要他們不同。

這將是簡單的方法,雖然不是太棒了性能。但正如我所說,這取決於你的要求。

+0

非常感謝。你的例子非常有趣,很容易實現。 但我想獲得消息傳遞系統的經驗。但不幸的是網絡上的培訓材料很少 對於非經驗的 – 2012-03-08 09:11:22

2

您可以使用NativeWindow而不是Form並仍然使用WndProc(ref Message msg)。 這實際上是一種看不見的形式,請參閱示例:

[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")] 
public class MyMessageHandler : NativeWindow 
{ 
    private event EventHandler<MyEventArgs> messageReceived; 
    public event EventHandler<MyEventArgs> MessageReceived 
    { 
     add 
     { 
      if (messageReceived == null || !messageReceived.GetInvocationList().Contains(value)) 
       messageReceived += value; 
     } 
     remove 
     { 
      messageReceived -= value; 
     } 
    } 

    public MyMessageHandler() 
    { 
     var cp = new CreateParams(); 
     CreateHandle(cp); 
    } 

    [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")] 
    protected override void WndProc(ref Message msg) 
    { 
     var handler = messageReceived; 
     if (handler != null) 
      handler(this, new MyEventArgs(msg)); 

     base.WndProc(ref msg); 
    } 
} 
+1

可以理解,我真的希望這種技術能夠工作,但不幸的是控制檯應用程序只接收一些消息事件,而WM_DEVICECHANGE不是其中之一。 – 2013-11-01 19:51:02

相關問題