2013-04-19 4 views
5

मेरे पास एक ऐसा प्रोग्राम है जो सीपोर्ट का उपयोग करके एकाधिक धारावाहिक बंदरगाहों तक पहुंचता है।सीरियल (COM) बंदरगाहों का नाम या पहचान

कॉन्फ़िगर करने के लिए, अब तक मैंने चयन करने के लिए एक कंबोबॉक्स में सभी उपलब्ध कंप्यूटर्स सूचीबद्ध किए हैं, लेकिन (वर्चुअल) धारावाहिक इंटरफेस वाले ड्राइवरों की बढ़ती संख्या अंत उपयोगकर्ताओं को परेशान करने के लिए कॉन्फ़िगर करती है।

वर्तमान पहचान createfile() के साथ काम करती है, लेकिन इसमें समस्या है कि आप केवल अस्तित्व/nonexists और शायद "व्यस्त" जानकारी के रूप में हो।

हालांकि सुधार करने के लिए, मुझे प्रति COM पोर्ट की पहचान स्ट्रिंग की आवश्यकता है, जैसे हार्डवेयर डिवाइस/ड्राइवर (डिवाइस मैनेजर) यह भी जुड़ा हुआ है। यह उपयोगकर्ता को कंप्यूटर्स को सीमित करने के लिए आसान बनाता है (चूंकि हम सीरियल कार्ड की सीमित संख्या प्रदान करते हैं)

शायद यह डब्लूएमआई से उपलब्ध है, लेकिन यह काफी जंगल है, क्या एसबी में अधिक ठोस जानकारी है, या बेहतर है कोड?

(डेल्फी XE3, Win7 +, कोई समाधान नहीं है कि अतिरिक्त स्थापित करने या तैनाती कृपया की आवश्यकता है)

+0

संभावित डुप्लिकेट [यह निर्धारित करने के लिए कि मशीन को शारीरिक रूप से एक सीरियल पोर्ट है या नहीं?] (Http://stackoverflow.com/questions/5575372/how-to-determine-if-a-machine-physically-has-a -सियल-पोर्ट) –

+0

भी: http://stackoverflow.com/q/613166/327083 ... जेडीआई, आदि, घटक हैं जो इस कार्यक्षमता को उच्च स्तर पर प्रदान करते हैं, लेकिन यदि आप अपना खुद का रोल करना चाहते हैं तो मुझे लगता है कि या तो डब्लूएमआई या रजिस्ट्री आपका एकमात्र सहारा है। –

+0

जो आप खोज रहे हैं वह शायद अपने "मित्रवत नाम" सहित कॉम पोर्टों को गिनने का एक तरीका है? –

उत्तर

9

आप COM पोर्ट हो रही कोई दोस्ताना नाम आप SetupAPI और GUID_DEVINTERFACE_COMPORT डिवाइस इंटरफ़ेस वर्ग का उपयोग कर सकते करके बताना चाहते हैं।

इस नमूने का प्रयास करें

{$APPTYPE CONSOLE} 

{$R *.res} 

uses 
    Windows, 
    SysUtils, 
    JvSetupApi; 

const 
    GUID_DEVINTERFACE_COMPORT:TGUID='{86E0D1E0-8089-11D0-9CE4-08003E301F73}'; 

procedure EnumerateCOMPorts; 
var 
    cbRequired : DWORD; 
    hdev  : HDEVINFO; 
    idev  : Integer; 
    did  : TSPDeviceInterfaceData; 
    pdidd : PSPDeviceInterfaceDetailData; 
    PropertyBuffer : array[0..255] of Char; 
    DeviceInfoData: TSPDevInfoData; 
    PropertyRegDataType: DWORD; 
    RequiredSize: DWORD; 
begin 
    // enumerate the com ports 
    hdev := SetupDiGetClassDevs(@GUID_DEVINTERFACE_COMPORT, nil, 0, DIGCF_PRESENT OR DIGCF_DEVICEINTERFACE); 
    if (INVALID_HANDLE_VALUE <> THandle(hdev)) then 
    begin 
    try 
     idev:=0; 
     ZeroMemory(@did, SizeOf(did)); 
     did.cbSize := SizeOf(did); 
     repeat 
     if (SetupDiEnumDeviceInterfaces(hdev, nil, GUID_DEVINTERFACE_COMPORT, idev, did)) then 
     begin 
      cbRequired := 0; 
      SetupDiGetDeviceInterfaceDetail(hdev, @did, nil, 0, cbRequired, nil); 
      if (ERROR_INSUFFICIENT_BUFFER= GetLastError()) then 
      begin 
       pdidd:=AllocMem(cbRequired); 
       try 
       pdidd.cbSize := SizeOf(TSPDeviceInterfaceDetailData); 
       DeviceInfoData.cbSize:= SizeOf(DeviceInfoData); 
       RequiredSize:=0; 
       if (SetupDiGetDeviceInterfaceDetail(hdev, @did, pdidd, cbRequired, RequiredSize, @DeviceInfoData)) then 
       begin 

       PropertyRegDataType:=0; 
       RequiredSize:=0; 
       if SetupDiGetDeviceRegistryProperty(hdev, DeviceInfoData, SPDRP_FRIENDLYNAME, PropertyRegDataType, PBYTE(@PropertyBuffer[0]), SizeOf(PropertyBuffer), RequiredSize) then 
        Writeln(Format('Friendly Name - %s',[PropertyBuffer])); 

       if SetupDiGetDeviceRegistryProperty(hdev, DeviceInfoData, SPDRP_DEVICEDESC, PropertyRegDataType, PBYTE(@PropertyBuffer[0]), SizeOf(PropertyBuffer), RequiredSize) then 
        Writeln(Format('Description - %s',[PropertyBuffer])); 

       if SetupDiGetDeviceRegistryProperty(hdev, DeviceInfoData, SPDRP_LOCATION_INFORMATION, PropertyRegDataType, PBYTE(@PropertyBuffer[0]), SizeOf(PropertyBuffer), RequiredSize) then 
        Writeln(Format('Location  - %s',[PropertyBuffer])); 
       end 
       else 
       RaiseLastOSError; 
       finally 
       FreeMem(pdidd); 
       end; 
      end; 
     end 
     else 
     Break; 
     inc(idev); 
     until false; 
    finally 
     SetupDiDestroyDeviceInfoList(hdev); 
    end; 
    end; 
end; 

begin 
    try 
    if not LoadsetupAPI then exit; 
    EnumerateCOMPorts; 
    except 
    on E: Exception do 
     Writeln(E.ClassName, ': ', E.Message); 
    end; 
    readln; 
end. 

इस तरह तो

enter image description here

नोट कुछ वापस आ जाएगी: JvSetupApi इकाई JVCL पुस्तकालय का हिस्सा है।

+0

हाँ, यह भी अन्य संदर्भों से काम कर रहा है। हालांकि सभी बंदरगाहों को नहीं दिखाता है।मैं विभिन्न डब्ल्यूएमआई उदाहरणों के साथ खेल रहा हूं, लेकिन वे या तो इस तरह दिखाते हैं, या ऊंचाई की आवश्यकता होती है (और फिर भी मैं उन्हें सभी COM डिवाइस देखने के लिए नहीं मिल सकता) –

+1

ऐसा लगता है कि आपके कोड में कोई गलती है, क्योंकि यह केवल एक डिवाइस दिखाता है। आपको दोहराने वाले लूप के बाहर अपने 'प्रयास करें ... अंतिम रूप से' अनुभाग की आवश्यकता है, क्योंकि पहले दिखाए गए डिवाइस के बाद 'SetupDiDestroyDeviceInfoList (hdev) '' hdev' को नष्ट कर देगा और' SetupDiEnumDeviceInterfaces (hdev, nil, GUID_DEVINTERFACE_COMPORT, idev, did) के लिए अगली कॉल वापसी त्रुटि (6 - अवैध संभाल)। – AntonBazhal

+0

@ एंटोनबाज़ल, धन्यवाद। मैंने कोड को संपादित किया, आखिरकार कोशिश को अवरुद्ध कर दिया। – RRUZ

0

आप COMxx शैली के छोटे नामों के लिए HKEY_LOCAL_MACHINE \ Hardware \ DEVICEMAP \ SERIALCOMM का उपयोग कर सकते हैं। याद रखें कि व्यवस्थापक अधिकार/यूएसी आवश्यकता से बचने के लिए केवल पढ़ने के लिए उपयोग निर्दिष्ट करें। आप usb232 एडेप्टर और असली कॉम पोर्ट दोनों देख सकते हैं।

आप HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Enum \ रूट \ PORTS को भी चेक कर सकते हैं लेकिन यह थोड़ा मुश्किल लगता है।

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