2009-03-06 10 views
50

का उपयोग कर एक यूएसबी वितरित बनाने की संभावना में देख रहे हैं आवेदन
कि जब छड़ी को निकालने में एक यूएसबी स्टिक और शट डाउन की प्रविष्टि पर autostart जाएगा
यूएसबी ड्राइव प्रविष्टि का पता लगा रहा और हटाने खिड़कियों सेवा और ग #

नेट का उपयोग करेंगे और सी#।
सुझाव के लिए खोज रहे हैं कि सी # का उपयोग करके इसका उपयोग कैसे करें?


अद्यतन: सेवा के रूप में इसे लागू करने के दो संभावित समाधान।
- ManagementEventWatcher

+1

अच्छा प्रश्न है। मेरा पहला विचार यह है कि आपको अपनी सेवा को "डेस्कटॉप से ​​बातचीत करने की अनुमति" के रूप में चिह्नित करना होगा और फिर एक छिपी हुई विंडो बनाएं। सुरक्षित विकल्प शायद एक विंडोज ऐप बनाने के लिए है जो स्टार्टअप पर चलता है - यह विंडो बना सकता है और फिर svc –

+0

से संवाद कर सकता है संबंधित: http: // stackoverflow।कॉम/प्रश्न/6003822/कैसे-टू-डिटेक्ट-ए-यूएसबी-ड्राइव-है-प्लग-इन – DuckMaestro

उत्तर

44

आप डब्लूएमआई का उपयोग कर सकते हैं, यह आसान है और यह सेवाओं के साथ डब्ल्यूडब्ल्यूप्रोक समाधान से काफी बेहतर काम करता है।

यहाँ एक सरल उदाहरण है:

using System.Management; 

ManagementEventWatcher watcher = new ManagementEventWatcher(); 
WqlEventQuery query = new WqlEventQuery("SELECT * FROM Win32_VolumeChangeEvent WHERE EventType = 2"); 
watcher.EventArrived += new EventArrivedEventHandler(watcher_EventArrived); 
watcher.Query = query; 
watcher.Start(); 
watcher.WaitForNextEvent(); 

और बस हो गया :)

+4

यह ठीक काम करता है लेकिन मैं सम्मिलित यूएसबी के ड्राइव अक्षर कैसे प्राप्त कर सकता हूं? –

+0

[यह आलेख] (http://www.ravichaganti.com/blog/monitoring-volume-change-events-in-powershell-using-wmi/) पावरहेल में यह जानकारी प्राप्त कर रहा है। सी # में अनुवाद करने के लिए बहुत कठिन नहीं होना चाहिए। – VitalyB

+3

आपके ईवेंट हैंडलर में, 'e.NewEvent.Properties ["DriveName"]। Value.ToString() ' – lambinator

4

साथ WMI क्वेरी का उपयोग WM_CHANGEDEVICE से निपटने का प्रयास करें - WndProc
या
ओवरराइड।

5

आप सम्मिलन घटनाओं का पता लगाने के लिए WMI का भी उपयोग कर सकते हैं। यह WM_CHANGEDEVICE संदेशों की निगरानी करने से थोड़ा अधिक जटिल है, लेकिन इसे एक विंडो हैंडल की आवश्यकता नहीं है जो उपयोगी हो सकता है यदि आप पृष्ठभूमि में सेवा के रूप में चल रहे हैं।

+2

@ जॉन कॉनराड: +1 डब्लूएमआई एक अच्छी पसंद है। इस पर एक एसओ विषय भी मिला: http://stackoverflow.com/questions/39704/wmi-and-win32devicechangeevent-wrong-event-type-returned –

+0

असल में डब्ल्यूएमआई बहुत आसान समाधान है। मैं इसे एक और समाधान के रूप में नीचे पोस्ट कर रहा हूं। – VitalyB

4

यहाँ हम एक WPF अनुप्रयोग के तहत सी # नेट 4.0 के साथ किया था। हम अभी भी "कैसे बताने के लिए जो डिवाइस प्रकार डाला/हटा दिया गया था" का उत्तर खोज रहे हैं, लेकिन यह एक शुरुआत है:

using System.Windows.Interop; 
... 
public partial class MainWindow : Window 
{ 
    ... 
    public MainWindow() 
    { 
    ... 
    } 

    //============================================================ 
    // WINDOWS MESSAGE HANDLERS 
    // 

    private const int WM_DEVICECHANGE = 0x0219; // int = 537 
    private const int DEVICE_NOTIFY_ALL_INTERFACE_CLASSES = 0x00000004; 

    /// <summary> 
    /// 
    /// </summary> 
    /// <param name="e"></param> 
    protected override void OnSourceInitialized(EventArgs e) 
    { 
     base.OnSourceInitialized(e); 
     HwndSource source = PresentationSource.FromVisual(this) as HwndSource; 
     source.AddHook(WndProc); 
    } 

    private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) 
    { 
     if (msg == WM_DEVICECHANGE) 
     { 
      ReadDongleHeader(); 
     } 
     return IntPtr.Zero; 
    } 

} 
+2

यह पता लगाने के लिए कि कौन सा डिवाइस डाला गया था? – Kcvin

+0

@ केविन इसे आसानी से डिवाइसों की सूची प्राप्त करने के लिए कहीं और मिल सकता है। यहां एक पूर्ण समाधान है जो मुझे पहले मिला। केवल WM_DEVICECHANGE मेरे लिए निकाल दिया गया है। https://social.msdn.microsoft.com/Forums/vstudio/en-US/ea183afd-d070-4abd-8e00-a1784fdfedc5/detecting-usb-device-insertion-and-removal?forum=csharpgeneral – CularBytes

19

VitalyB पद को जोड़ना।

एक घटना जहां किसी भी USB डिवाइस डाला जाता है बढ़ाने के लिए, निम्न का उपयोग करें:

var watcher = new ManagementEventWatcher(); 
var query = new WqlEventQuery("SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 2"); 
watcher.EventArrived += new EventArrivedEventHandler(watcher_EventArrived); 
watcher.Query = query; 
watcher.Start(); 

यह एक घटना है जब भी USB डिवाइस प्लग किया गया है बढ़ा देंगे। यह एक राष्ट्रीय उपकरण डीएक्यू के साथ भी काम करता है जिसे मैं स्वतः पहचानने की कोशिश कर रहा हूं।

+0

@ ली टेलर ठीक काम करता है लेकिन मैं सम्मिलित यूएसबी के ड्राइव अक्षर कैसे प्राप्त कर सकता हूं? –

+0

@NeverQuit - मैंने केवल सवाल संपादित किया, @Syn से पूछो! इसके अलावा, यदि आपके पास कोई नया प्रश्न है तो एक को बनाने में संकोच न करें। –

+0

@Syn यह ठीक काम करता है लेकिन मैं सम्मिलित यूएसबी के ड्राइव अक्षर कैसे प्राप्त कर सकता हूं? –

29

यह मेरे लिए अच्छा काम करता है, साथ ही आप डिवाइस के बारे में अधिक जानकारी प्राप्त कर सकते हैं।

using System.Management; 

private void DeviceInsertedEvent(object sender, EventArrivedEventArgs e) 
{ 
    ManagementBaseObject instance = (ManagementBaseObject)e.NewEvent["TargetInstance"]; 
    foreach (var property in instance.Properties) 
    { 
     Console.WriteLine(property.Name + " = " + property.Value); 
    } 
} 

private void DeviceRemovedEvent(object sender, EventArrivedEventArgs e) 
{ 
    ManagementBaseObject instance = (ManagementBaseObject)e.NewEvent["TargetInstance"]; 
    foreach (var property in instance.Properties) 
    { 
     Console.WriteLine(property.Name + " = " + property.Value); 
    } 
}    

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
{ 
    WqlEventQuery insertQuery = new WqlEventQuery("SELECT * FROM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_USBHub'"); 

    ManagementEventWatcher insertWatcher = new ManagementEventWatcher(insertQuery); 
    insertWatcher.EventArrived += new EventArrivedEventHandler(DeviceInsertedEvent); 
    insertWatcher.Start(); 

    WqlEventQuery removeQuery = new WqlEventQuery("SELECT * FROM __InstanceDeletionEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_USBHub'"); 
    ManagementEventWatcher removeWatcher = new ManagementEventWatcher(removeQuery); 
    removeWatcher.EventArrived += new EventArrivedEventHandler(DeviceRemovedEvent); 
    removeWatcher.Start(); 

    // Do something while waiting for events 
    System.Threading.Thread.Sleep(20000000); 
} 
+0

पूरी तरह से काम करता है। सम्मिलन/निष्कासन पर कुछ अन्य उत्तरों जैसे कई कार्यक्रमों को आग नहीं लगाता है। यह स्वीकार्य उत्तर होना चाहिए। – samuelesque

+0

मैं @ सैमुएल एंड द के साथ सहमत हूं, यह सबसे अच्छा अपमान लगता है। यदि आप हार्ड ड्राइव में परिवर्तनों का पता लगाने की तलाश में हैं और न केवल यूएसबी ड्राइव्स आप 'Win32_DiskDrive' वर्ग –

+0

'निजी शून्य पृष्ठभूमि Worker1_DoWork (ऑब्जेक्ट प्रेषक, DoWorkEventArgs ई) 'का उपयोग कर सकते हैं, तो आपके पास' (ऑब्जेक्ट प्रेषक, DoWorkEventArgs e क्यों है)) '??? (मैंने इसके लिए एक संपादन सुझाव दिया है।) – Turtle

11

विटालीबी का जवाब डिवाइस को हटाने का कवर नहीं करता है। मैंने ईवेंट को ट्रिगर करने के लिए थोड़ा सा बदल दिया जब मीडिया और हटा दिया गया और डालने वाले मीडिया के ड्राइव अक्षर को प्राप्त करने के लिए कोड भी हटा दिया गया।

using System; 
using System.Management; 

namespace MonitorDrives 
{ 
    class Program 
    { 
     public enum EventType 
     { 
      Inserted = 2, 
      Removed = 3 
     } 

     static void Main(string[] args) 
     { 
      ManagementEventWatcher watcher = new ManagementEventWatcher(); 
      WqlEventQuery query = new WqlEventQuery("SELECT * FROM Win32_VolumeChangeEvent WHERE EventType = 2 or EventType = 3"); 

      watcher.EventArrived += (s, e) => 
      { 
       string driveName = e.NewEvent.Properties["DriveName"].Value.ToString(); 
       EventType eventType = (EventType)(Convert.ToInt16(e.NewEvent.Properties["EventType"].Value)); 

       string eventName = Enum.GetName(typeof(EventType), eventType); 

       Console.WriteLine("{0}: {1} {2}", DateTime.Now, driveName, eventName); 
      }; 

      watcher.Query = query; 
      watcher.Start(); 

      Console.ReadKey(); 
     } 
    } 
} 
+0

यह बहुत अच्छा है, लेकिन किसी कारण से जब भी मैं डिवाइस को प्लग या आउट करता हूं तो यह कई बार घटना को फायर कर रहा है - क्या आप जानते हैं कि यह क्यों हो सकता है और इसे कैसे रोकें? – colmde

+0

जैसा कि आपने अपना कोड बताने के लिए कठिन नहीं लिखा है, लेकिन हो सकता है कि आप ईवेंट को एक से अधिक बार जोड़ रहे हों। –

+0

यह *** पूर्ण *** कोड नहीं है !!! तो आपको इसके लिए VitalyB के जवाब की कई पंक्तियों को प्रतिस्थापित करने की आवश्यकता है। – Turtle

2

सब से ऊपर जवाब पर थोड़ा सा संपादित करें: सेवा इस घटना को फँसाने पर

using System.Management; 

public partial class MainForm : Form 
{ 
    public MainForm() 
    { 
     InitializeComponent(); 

     bgwDriveDetector.DoWork += bgwDriveDetector_DoWork; 
     bgwDriveDetector.RunWorkerAsync(); 
    } 

    private void DeviceInsertedEvent(object sender, EventArrivedEventArgs e) 
    { 
     string driveName = e.NewEvent.Properties["DriveName"].Value.ToString(); 
     MessageBox.Show(driveName + " inserted"); 
    } 

    private void DeviceRemovedEvent(object sender, EventArrivedEventArgs e) 
    { 
     string driveName = e.NewEvent.Properties["DriveName"].Value.ToString(); 
     MessageBox.Show(driveName + " removed"); 
    } 

    void bgwDriveDetector_DoWork(object sender, DoWorkEventArgs e) 
    { 
     var insertQuery = new WqlEventQuery("SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 2"); 
     var insertWatcher = new ManagementEventWatcher(insertQuery); 
     insertWatcher.EventArrived += DeviceInsertedEvent; 
     insertWatcher.Start(); 

     var removeQuery = new WqlEventQuery("SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 3"); 
     var removeWatcher = new ManagementEventWatcher(removeQuery); 
     removeWatcher.EventArrived += DeviceRemovedEvent; 
     removeWatcher.Start(); 
    } 
} 
संबंधित मुद्दे