2009-12-22 25 views
6

मेरे पिछले प्रश्न में "फ्लैश डिवाइस का अद्वितीय सीरियल नंबर कैसे खोजें?" मैं ड्राइव पत्र प्राप्त करने के लिए एक रास्ता मांगने के लिए समाप्त हो गया। वह समस्या हल हो गई है।हमेशा हटाने योग्य डिवाइस का पता लगाने का सबसे अच्छा तरीका

हालांकि, मेरे प्रारंभिक प्रश्न का उत्तर नहीं दिया गया है। मैं हटाने योग्य उपकरणों (यूएसबी ड्राइव, एसडी कार्ड, (बाहरी एचडीडी?) इत्यादि को बताने में सक्षम होना चाहता था) अलग-अलग होते हैं और हमेशा दोबारा कनेक्ट होने पर उन्हें पहचानने में सक्षम होते हैं। यह किसी भी अन्य कंप्यूटर पर भी संभव होना चाहिए। सौभाग्य से, मुझे प्रारूपित किए जाने वाले ड्राइव (यदि/जब वे हैं, तो उन्हें मेरे प्रोग्राम में नए ड्राइव के रूप में माना जाता है) की परवाह नहीं है, तो क्या मैं अपनी पहचान के एक हिस्से के रूप में विभाजन और वॉल्यूम आईडी का उपयोग कर सकता हूं? मैं इसे पीएनपीडीवाइसिस के रूप में पूछ रहा हूं अद्वितीय है। मैंने पाया है कि यह हार्डवेयर इसे पढ़ने पर निर्भर करता है, चित्र नीचे देखें:

alt text http://i48.tinypic.com/28uofmc.png

alt text http://i46.tinypic.com/rk5tv6.jpg

तो, मैं क्या तलाश कर रहा हूँ पता लगाने और उपयोग कर किसी भी कंप्यूटर पर किसी भी हटाने योग्य डिवाइस की पहचान करने के लिए एक रास्ता है निम्नलिखित: Win32_DiskDrive, Win32_DiskPartition, Win32_LogicalDisk। मैं मूल कोड के लिए RRUZ शुक्रिया अदा कर रहा हूँ:

program GetWMI_USBConnectedInfo; 

{$APPTYPE CONSOLE} 

uses 
    Windows, 
    Classes, 
    ActiveX, 
    Variants, 
    SysUtils, 
    WbemScripting_TLB in '..\..\Documents\RAD Studio\5.0\Imports\WbemScripting_TLB.pas'; 

procedure GetUSBDiskDriveInfo; 
var 
    WMIServices : ISWbemServices; 
    Root,a,b  : ISWbemObjectSet; 
    Item,Item2 : Variant; 
    i,ii,iii,iiii: Integer; 
    start,stop,freq:Int64; 
begin 
    QueryPerformanceFrequency(freq); 
    QueryPerformanceCounter(start); 

    WMIServices := CoSWbemLocator.Create.ConnectServer('.', 'root\cimv2','', '', '', '', 0, nil); 
    Root := WMIServices.ExecQuery('Select * From Win32_DiskDrive','WQL', 0, nil); 
    for i := 0 to Root.Count - 1 do 
    begin 
    Item := Root.ItemIndex(i); 
    for ii := VarArrayLowBound(Item.Capabilities, 1) to VarArrayHighBound(Item.Capabilities, 1) do if (Item.Capabilities[ii] = 7) then begin 
     Writeln('Caption  '+VarToStr(Item.Caption)); 
     Writeln('Name   '+VarToStr(Item.Name)); 
     Writeln('DeviceID  '+VarToStr(Item.DeviceID)); 
     Writeln('Partitions '+VarToStr(Item.Partitions)); 
     Writeln('PNPDeviceID '+VarToStr(Item.PNPDeviceID)); 
     Writeln('SerialNumber '+VarToStr(Item.SerialNumber)); 
     Writeln('Signature '+VarToStr(Item.Signature)); 

     a := WMIServices.ExecQuery('ASSOCIATORS OF {Win32_DiskDrive.DeviceID=''' + VarToStr(Item.DeviceID) + '''} WHERE AssocClass = Win32_DiskDriveToDiskPartition','WQL', 0, nil); 
     for iiii := 0 to a.Count - 1 do begin 
     b := WMIServices.ExecQuery('ASSOCIATORS OF {Win32_DiskPartition.DeviceID=''' + VarToStr(Variant(a.ItemIndex(iiii)).DeviceID) + '''} WHERE AssocClass = Win32_LogicalDiskToPartition','WQL', 0, nil); 
     for iii := 0 to b.Count - 1 do begin 
      Item2 := b.ItemIndex(iii); 
      Writeln('Drive = ' + Item2.Caption); 
     end; 
     end; 
     Writeln; 
     Writeln; 
    end; 
    end; 
    QueryPerformanceCounter(stop); 
    if (freq > 0) then 
    Writeln('Time took: ' + FloatToStr((stop-start)/freq)) 
    else 
    Writeln('Unable to measure time!'); 
end; 

begin 
    try 
    CoInitialize(nil); 
    GetUSBDiskDriveInfo; 
    Readln; 
    CoUninitialize; 
    except 
    on E:Exception do 
    Begin 
     CoUninitialize; 
     Writeln(E.Classname, ': ', E.Message); 
     Readln; 
    End; 
    end; 
end. 

संपादित
मुझे लगता है कि कोड ड्राइव का पता लगाने के लिए जब वे डाला जाता है पहले से ही काम कर रहा है, हालांकि यह केवल मुझे ड्राइव अक्षर देता जोड़ना चाहिए। मैं डब्ल्यूएमआई से अन्य सभी जानकारी प्राप्त करने के लिए उस ड्राइव अक्षर का उपयोग करता हूं।

अंतिम संपादित
मैंने पढ़ा है कि डेवलपर्स को सुरक्षित रूप से मान्यता के लिए विभाजन/मात्रा आईडी का उपयोग कर सकते हैं। क्या मैं उस पर भरोसा कर सकता हूँ?

समाधान: एक अनूठा साथ ड्राइव पर एक छिपा फ़ाइल

  1. सहेजें:
    तो, "अद्वितीय" आईडी के पढ़ने एक व्यवहार्य समाधान नहीं है के बाद से, वहाँ इस के आसपास पाने के लिए दो तरीके हैं आईडी कि प्रोग्राम पहचान सकता है (स्थानीय डेटाबेस की तुलना में)।
  2. ड्राइव ड्राइव से संबंधित सभी चीज़ों को सहेजें पर एक छिपी हुई सेटिंग्स फ़ाइल के रूप में सहेजें। मैंने इस दृष्टिकोण को लिया क्योंकि कार्यक्रम में स्वयं की कोई सेटिंग नहीं है। सभी सेटिंग्स प्रति विभाजन हैं। यह सेटिंग/प्रोग्राम पोर्टेबल भी बनाता है।

उत्तर

2

आपको कुल डिस्क आकार और वॉल्यूम नाम के साथ जोड़ा गया वॉल्यूम आईडी का उपयोग करने में सक्षम होना चाहिए यह निर्धारित करने के लिए कि डिस्क एक जैसी है या नहीं, हालांकि वॉल्यूम आईडी स्वयं ही पर्याप्त होनी चाहिए।

एकमात्र समस्या बड़े पैमाने पर उत्पादित मीडिया हो सकती है। कुछ मामलों में वॉल्यूम आईडी, डिस्क आकार और वॉल्यूम नाम सभी प्रतियों के लिए मेल खाता है।

EDIT मुझे यकीन नहीं है कि क्या आप सामान्य रूप से सभी उपकरणों के लिए इसे पूरी तरह से प्राप्त कर सकते हैं। प्रत्येक विक्रेता से हार्डवेयर अलग होता है, और विनिर्देश व्याख्या के लिए होते हैं, यही कारण है कि कुछ उपकरणों के लिए सीरियल नंबर शून्य है, कुछ इसके लिए नहीं। आपकी एकमात्र उम्मीद या तो खुद को हार्डवेयर की आपूर्ति करना होगा या विशिष्ट हार्डवेयर की आवश्यकता होगी जो अनुमानित तरीके से व्यवहार करे।

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

+0

यहाँ मिलियन डॉलर सवाल है? मैं उपयोगकर्ता को डिवाइस का नाम बदलने और पहचान के लिए इसका उपयोग करने के लिए कह सकता हूं। –

+0

उत्कृष्ट। हटाने योग्य डिवाइस पर एक GUID सहेजना और उसे स्थानीय डेटाबेस से तुलना करना (पढ़ना: आईएनआई फ़ाइल) जहां GUID और वॉल्यूम/विभाजन आईडी सहेजी जाती है, यह सुनिश्चित करना चाहिए कि डिवाइस पहचाना जाएगा और भले ही फ़ाइल को वॉल्यूम/विभाजन आईडी मिस्चैच की प्रतिलिपि बनाई गई हो प्रोग्राम को गलत तरीके से पहचानने से प्रोग्राम को रोकना चाहिए। आपका चेकमार्क यहाँ है! –

2

यूएसबी उपकरणों के लिए एक अद्वितीय आईडी होना आवश्यक है। मैंने पहले से ही एक .NET ऐप से सफलतापूर्वक उपयोग किया है, और इसे डेल्फी ऐप में समान रूप से अच्छी तरह से काम करना चाहिए।

आप टाइप लाइब्रेरी संपादक का उपयोग करके डेल्फी में डब्लूएमआई COM ऑब्जेक्ट्स आयात करने में सक्षम होना चाहिए, इस तरह आप वेरिएंट के चरण में प्रारंभिक बाध्यकारी का उपयोग कर सकते हैं।

यदि आपको वास्तविक नमूना की आवश्यकता है, तो मुझे सी # कोड देखने की आवश्यकता होगी। अगर आपको इसकी ज़रूरत है तो मुझे एक निजी संदेश या ईमेल छोड़ दें।

बस यह एक त्वरित रूप से देखा गया था कि आप इसे .NET में कैसे करते हैं: आप Management Strongly Typed Class Generator (Mgmtclassgen.exe) का उपयोग करते हैं जो मूल दुनिया में उपलब्ध नहीं है।

मैं गैर-यूएसबी उपकरणों के बारे में इतना निश्चित नहीं हूं। आप उम्मीद करेंगे कि पीएनपी आईडी डिवाइस के लिए समान हो, लेकिन आप बताते हैं कि वे नहीं हैं, हालांकि मुझे आपके उदाहरण में अलग-अलग डिवाइसों के साथ एक ही पीएनपी आईडी नहीं दिखाई दे रही है (यदि कोर्स मैं यहां कुछ स्पष्ट रूप से अनदेखा कर सकता हूं)।

--jeroen

यूएसबी उपकरणों में एक अद्वितीय आईडी है।

मिले सी # कोड है कि सभी USB उपकरणों की सूची के कुछ भागों:

public static List<DiskDrive> GetUsbDiskDrives() 
    { 
     DiskDrive.DiskDriveCollection diskDrives = DiskDrive.GetInstances("InterfaceType = 'USB'"); 
     return DiskDriveList(diskDrives); 
    } 

    public static List<DiskDrive> DiskDriveList(DiskDrive.DiskDriveCollection diskDrives) 
    { 
     List<DiskDrive> result = new List<DiskDrive>(); 
     foreach (DiskDrive diskDrive in diskDrives) 
     { 
      result.Add(diskDrive); 
     } 
     return result; 
    } 

    public static string Serial(DiskDrive diskDrive) 
    { 
     // pick the last portion of diskDrive.PNPDeviceID: 
     string[] splitted = diskDrive.PNPDeviceID.Split('\\'); // note this becomes one backslash 
     string result = splitted[splitted.Length - 1]; 
     return result; 
    } 

ऊपर टुकड़े नेट System.Collections.Generic नाम स्थान उपयोग करें ताकि आप एक सामान्य सूची हो सकता है।

diskdrive सी # फ़ाइल में Win32.WMI नाम स्थान इस आदेश द्वारा उत्पन्न में है: कैसे (किसी भी हैक की अनुमति दी) मुझे लगता है कि समस्या को हल करने में सक्षम होगा:

MgmtClassGen.exe Win32_DiskDrive /oWin32.WMI 
+0

वास्तविक अद्वितीय आईडी का नाम क्या होगा, यदि वह डब्लूएमआई के साथ उपलब्ध है? –

+0

मुझे लगता है कि यह पीएनपीडीवाइसिस है, लेकिन मुझे सत्यापित करने के लिए टीएफएस से सी # कोड प्राप्त करने की आवश्यकता है। –

+0

PNPDeviceID डिवाइसों को अलग करने के लिए अच्छा है और शायद उन्हें उसी कंप्यूटर पर भी उसी हार्डवेयर पर पहचान सकता है (शायद एक ही यूएसबी स्लॉट)। लेकिन उस PNPDeviceID से परे कोई उपयोग नहीं है, क्योंकि यह हार्डवेयर के दूसरे टुकड़े के साथ उपयोग किए जाने पर बदलता है। –

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

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