c # - Er der virkelig nogen måde at identificere enhver computer overhovedet

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg ved, at der er en række lignende spørgsmål i stackoverflow som følgerne:



  • Hvad er en god måde at identificere en computer entydigt på?

  • Hvad er et godt unikt pc-id?

  • Unikt computer id C #

  • WIN32\_Processor :: Er ProcessorId Unik for alle computere

  • Hvordan identificerer du unikt computer ved hjælp af C #?



... og snesevis mere, og jeg har studeret dem alle.


Problemet er, at nogle af de accepterede svar har foreslået MAC-adresse som en unik identifikator, som er helt ukorrekt. Nogle andre svar har antydet at bruge en kombination af forskellige komponenter, der synes mere logiske. Men i tilfælde af brug af en kombination bør det overvejes, hvilken komponent der naturligvis ikke er sandsynligt, at det vil blive ændret ofte. For nogle dage siden udviklede vi en nøglegenerator til et software licens problem, hvor vi brugte kombinationen af ​​CPUID og MAC til at identificere en Windows pc unik og indtil praktisk testning vi troede vores tilgang var god nok. Ironisk nok, da vi gik testede det, fandt vi tre computere, der returnerede det samme id med vores nøglegenerator!


Så er der virkelig nogen måde at identificere en hvilken som helst computer entydigt? Lige nu skal vi bare gøre vores nøglegenerator til at arbejde på Windows pc. En eller anden måde (hvis muligt overhovedet) ved hjælp af c # ville være fantastisk, da vores system er udviklet på .net.


Opdatering:


Undskyld for at skabe nogle forvirringer og en tilsyneladende falsk alarm. Vi fandt ud af, at der var noget ukorrekt i vores metode til at hente HW info. Først og fremmest tænkte jeg på at slette dette spørgsmål som nu er min egen forvirring gået, og jeg tror, ​​at en kombination af to eller flere komponenter er god nok til at identificere en computer. Men så besluttede jeg at holde det, fordi jeg tror, ​​jeg burde klarlægge, hvad der forårsagede problemet, da det samme kunne skade en anden fyr i fremtiden.


Det var det, vi gjorde (med undtagelse af andre koder):


Vi brugte en getManagementInfo funktion til at hente MAC og Processor ID


private String getManagementInfo(String StrKey\_String, String strIndex)
    {
        String strHwInfo = null;
        try
        {
            ManagementObjectSearcher searcher = new ManagementObjectSearcher("select * from " + StrKey\_String);
            foreach (ManagementObject share in searcher.Get())
            {
                strHwInfo += share[strIndex];
            }
        }
        catch (Exception ex)
        {
            // show some error message
        }
        return strHwInfo;
    } 


Så hvor det var nødvendigt brugte vi den funktion til at hente MAC-adresse


string strMAC = getManagementInfo("Win32\_NetworkAdapterConfiguration", "MacAddress");


og at hente ProcessorID


string strProcessorId = getManagementInfo("Win32\_Processor", "ProcessorId");


På dette tidspunkt vil strMAC indeholde mere end en MAC-adresse, hvis der er mere end en. For at tage kun en tog vi bare de første 17 tegn (12 MAC-cifre og 5 kolon i mellem).


strMAC = strMAC.Length > 17 ? strMAC.Remove(17) : strMAC;


Det er her, vi lavede fejlen. Fordi getManagementInfo("Win32\_NetworkAdapterConfiguration", "MacAddress") returnerede en række ekstra MAC-adresser, der virkelig var i brug. For eksempel, da vi søgte efter MAC-adresser i kommandoprompten med getmac kommando, viste den en eller to MAC-adresser til hver pc, som var alle forskellige. Men getManagementInfo("Win32\_NetworkAdapterConfiguration", "MacAddress") returnerede fire til fem MAC-adresser, hvoraf nogle var ens for alle computere. Da vi lige tog den første MAC-adresse, som vores funktion returnerede i stedet for at kontrollere noget andet, blev de samme MAC-adresser taget i strMAC tilfældigt.


Følgende kode af Sowkot Osman gør tricket ved at returnere kun den første aktive/aktiverede MAC-adresse: [19]


private static string macId()
    {
        return identifier("Win32\_NetworkAdapterConfiguration", "MACAddress", "IPEnabled");
    }

private static string identifier(string wmiClass, string wmiProperty, string wmiMustBeTrue)
    {
        string result = "";
        System.Management.ManagementClass mc = new System.Management.ManagementClass(wmiClass);
        System.Management.ManagementObjectCollection moc = mc.GetInstances();
        foreach (System.Management.ManagementObject mo in moc)
        {
            if (mo[wmiMustBeTrue].ToString() == "True")
            {
                //Only get the first one
                if (result == "")
                {
                    try
                    {
                        result = mo[wmiProperty].ToString();
                        break;
                    }
                    catch
                    {
                    }
                }
            }
        }
        return result;
    }
    //Return a hardware identifier
    private static string identifier(string wmiClass, string wmiProperty)
    {
        string result = "";
        System.Management.ManagementClass mc = new System.Management.ManagementClass(wmiClass);
        System.Management.ManagementObjectCollection moc = mc.GetInstances();
        foreach (System.Management.ManagementObject mo in moc)
        {
            //Only get the first one
            if (result == "")
            {
                try
                {
                    result = mo[wmiProperty].ToString();
                    break;
                }
                catch
                {
                }
            }
        }
        return result;
    }


Men jeg havde helt rigtigt det samme Proces ID-problem. Alle tre returnerede samme Processor ID, når vi sætter wmic cpu get ProcessorId kommandoen i deres kommandoprompter.


Nu har vi besluttet at bruge bundkort serienummer i stedet for Processor ID for at kombinere MAC-adressen. Jeg tror, ​​at vores formål vil blive tjent på denne måde, og hvis det ikke er tilfældet, skal vi lade det gå i de få tilfælde.

Bedste reference


Faktummet ved at få et globalt unikt id er, kun MAC-adresse er det ID, der ikke vil ændre sig, hvis du opsætter dit system hele tiden. Hvis du genererer en nøgle til et bestemt produkt, er den bedste måde at gøre det på at tildele unikke id'er til produkter og kombinere produkt-id'et med MAC-adressen. Håber det hjælper.

Andre referencer 1


Hvad med at tilføje bundkortets serienummer, f.eks .:


using System.management;


//Code for retrieving motherboard's serial number
ManagementObjectSearcher MOS = new ManagementObjectSearcher("Select * From Win32\_BaseBoard");
foreach (ManagementObject getserial in MOS.Get())
{
textBox1.Text = getserial["SerialNumber"].ToString();
}

//Code for retrieving Processor's Identity
MOS = new ManagementObjectSearcher("Select * From Win32\_processor");
foreach (ManagementObject getPID in MOS.Get())
{
textBox2.Text = getPID["ProcessorID"].ToString();
}

//Code for retrieving Network Adapter Configuration
MOS = new ManagementObjectSearcher("Select * From Win32\_NetworkAdapterConfiguration");
foreach (ManagementObject mac in MOS.Get())
{
textBox3.Text = mac["MACAddress"].ToString();
}

Andre referencer 2


Jeg er helt enig med bare ovenstående kommentar.


For software licenser kan du bruge:


Computer MAC-adresse (alt om flere NIC-kort) + Din software produktkode


De fleste af den berømte telesælger bruger denne teknik.

Andre referencer 3



  Men jeg havde helt rigtigt samme identifikationsprocessor ID
  problem. Alle tre returnerede samme Processor ID, når vi sætter wmic cpu
  få ProcessorId kommandoen i deres kommandoprompter.



Processor ID vil være ens, hvis alle systemer kører som virtuelle maskiner på samme hypervisor.


MAC-ID virker fint. Kun ting er, at brugere skal have mulighed for at nulstille programmet, hvis MAC'en ændres.