2012-05-11 17 views
5

मेरा सी # एप्लिकेशन COM बंदरगाहों का उपयोग करता है। मुझे कुछ कठिनाई हो रही है जो अधिकांश कार्यक्रमों के लिए आम होनी चाहिए। जब पोर्टनाम की सूची बदलती है तो मुझे एक ईवेंट प्राप्त करने की आवश्यकता होती है। मेरे पास एक चयन बॉक्स है जहां उपयोगकर्ता उपलब्ध पोर्ट नामों की टीएच सूची से चुन सकता है। क्या किसी के पास कोड का स्निपेट है? धन्यवाद।नया COM पोर्ट उपलब्ध घटना

+1

मुझे लगता है कि एक सामान्य 'नया यूएसबी डिवाइस' या 'नया पीएनपी डिवाइस' सिस्टम इवेंट है जिसे आप देख सकते हैं, लेकिन नए COM बंदरगाहों के सामने आने से पहले डिवाइस को शुरू करने के लिए आपको एक सेकंड का इंतजार करना पड़ सकता है। – Rup

+1

@Rup - आप सही हैं। डिवाइस अधिसूचना के बीच एक अंतराल है और जब System.IO.Ports.SerialPort.GetPortNames() परिवर्तन को प्रतिबिंबित करेगा। यही कारण है कि उस सूची को अद्यतन होने पर अधिसूचित होना वास्तव में अच्छा होगा। – GTAE86

उत्तर

2

COM बंदरगाह बदलना एक दुर्लभ घटना है, सामान्य नहीं है।

सबसे आसान तरीका एक टाइमर होना होगा और प्रत्येक 10-30 सेकंड COM बंदरगाहों की सूची का आकलन करेगा और यदि बदल गया है, तो सूची अपडेट करें।

अभी भी बेहतर है, एक "ताज़ा सूची" बटन प्रदान - सूची मूल रूप से केवल बदल जाएगा, तो उपयोगकर्ता के एक यूएसबी सीरियल एडाप्टर खामियों को दूर किया है

+2

http://www.codeproject.com/Articles/60579/A-USB-Library-to-Dectect-USB- डिवाइसेस आपको दिखाएंगे कि यूएसबी अटैच/डिटेच इवेंट्स को कैसे सुनें। इसके अलावा, उपयोगकर्ता के लिए 10-30 सेकंड शायद बहुत लंबा है, रीफ्रेश बटन के लिए +1 वोट दें। – Simon

2

एक सरल फार्म आवेदन बनाएँ और रूप में निम्न कोड डाल:।

protected override void WndProc(ref Message m) 
{ 
    switch (m.Msg) 
    { 
     case 537: //WM_DEVICECHANGE 
      var ports = SerialPort.GetPortNames().OrderBy(name => name); 

      foreach (var portName in ports) 
      { 
       Debug.Print(portName); 
      } 
      break; 
    } 
    base.WndProc(ref m); 
} 
+0

क्या यह विंडोज सेवा संदेश पंप के अंदर काम कर सकता है? ओएस: विन 7। यदि नहीं, तो कोई कामकाज? –

+0

@ एड्रियन सालाजार: पता नहीं, कभी कोशिश नहीं की। लेकिन मुझे कोई कारण नहीं दिख रहा है कि इसे क्यों काम नहीं करना चाहिए। बस इसे आज़माएं और यदि यह काम नहीं करता है, तो अपनी समस्या के साथ एक नया प्रश्न पूछें। – Oliver

+0

छोटे छोटे "ओवरराइड" कीवर्ड वह है जिसे मैं चिंतित करता हूं। Windows सेवा के अंदर कभी भी इस विशिष्ट विधि को कभी नहीं देखा, इसलिए, ओवरराइड करने के लिए नोट करना। –

4

यह भी "ManagementEventWatcher" की मदद से किया जा सकता है:

using System; 
using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using System.ComponentModel.Composition; 
using System.Linq; 
using System.Text; 
using System.Management; 
using System.IO.Ports; 
using System.Threading; 
using System.Threading.Tasks; 

namespace HmxFlashLoader 
{ 
/// <summary> 
/// Make sure you create this watcher in the UI thread if you are using the com port list in the UI 
/// </summary> 
[Export] 
[PartCreationPolicy(CreationPolicy.Shared)] 
public sealed class SerialPortWatcher : IDisposable 
{ 
    public SerialPortWatcher() 
    { 
     _taskScheduler = TaskScheduler.FromCurrentSynchronizationContext(); 
     ComPorts = new ObservableCollection<string>(SerialPort.GetPortNames().OrderBy(s => s)); 

     WqlEventQuery query = new WqlEventQuery("SELECT * FROM Win32_DeviceChangeEvent"); 

     _watcher = new ManagementEventWatcher(query);   
     _watcher.EventArrived += (sender, eventArgs) => CheckForNewPorts(eventArgs); 
     _watcher.Start();  
    } 

    private void CheckForNewPorts(EventArrivedEventArgs args) 
    { 
     // do it async so it is performed in the UI thread if this class has been created in the UI thread 
     Task.Factory.StartNew(CheckForNewPortsAsync, CancellationToken.None, TaskCreationOptions.None, _taskScheduler); 
    } 

    private void CheckForNewPortsAsync() 
    { 
     IEnumerable<string> ports = SerialPort.GetPortNames().OrderBy(s => s); 

     foreach (string comPort in ComPorts) 
     { 
      if (!ports.Contains(comPort)) 
      { 
       ComPorts.Remove(comPort); 
      } 
     } 

     foreach (var port in ports) 
     {   
      if (!ComPorts.Contains(port)) 
      { 
       AddPort(port); 
      } 
     } 
    } 

    private void AddPort(string port) 
    { 
     for (int j = 0; j < ComPorts.Count; j++) 
     { 
      if (port.CompareTo(ComPorts[j]) < 0) 
      { 
       ComPorts.Insert(j, port); 
       break; 
      } 
     } 

    } 

    public ObservableCollection<string> ComPorts { get; private set; } 

    #region IDisposable Members 

    public void Dispose() 
    { 
     _watcher.Stop();  
    } 

    #endregion 

    private ManagementEventWatcher _watcher; 
    private TaskScheduler _taskScheduler; 
} 

}

+0

बहुत साफ समाधान! धन्यवाद दोस्त! – Ian

+0

मुझे लगता है कि यह कोड एक अपवाद फेंक देगा जब कॉमपॉर्ट्स को कॉमपॉर्ट्स को फिर से चालू करते समय अद्यतन किया जाएगा .... – GTAE86

संबंधित मुद्दे