0

I want to configure my C# Windows Form application such that before running the application, it identifies match the current machine's hard-drive serial number. If the hard-drive serial number matches with the configured serial number, it runs the application otherwise do nothing.

I want to make it run only on a single machine to prevent redistribution of the application because this is a custom application developed only for a client with some special requirements.

The following code gets the current machine's hard-drive serial number, model and interface type.

ManagementObjectSearcher moSearcher = new ManagementObjectSearcher("select * from Win32_DiskDrive");
            foreach (ManagementObject wmi_HDD in moSearcher.Get())
            {
                HardDrive hdd = new HardDrive();

                hdd.Model = wmi_HDD["Model"].ToString();
                hdd.SerialNo = wmi_HDD["SerialNumber"].ToString();
                hdd.Type = wmi_HDD["InterfaceType"].ToString();

                HDDArrayList.Add(wmi_HDD);

                txtHDDModel.Text = hdd.Model;
                txtHDDSerialNo.Text = hdd.SerialNo;
                txtHDDType.Text = hdd.Type;
            }

This code is currently running on a button click. I want it to run before the main method it can get the current machine hard-drive serial number and compares it with my target serial number (the one I want to allow).

Is there any better approach for this as well as for the comparison process?

teccraft
  • 75
  • 8
  • I don't think you can run anything before main. Just make your method return a bool, call the method from main, and if it is false, return. – Terry Tyson Jun 14 '19 at 15:42
  • 1
    Double click on the form in the designer mode, it will create a load event function just paste the code in it. The function name should be something like `Form1_Load` – Amine Messaoudi Jun 14 '19 at 15:43
  • @TerryTyson I agree with this approach. Is it really possible to call another method from the main method and also do some comparison operation there? As per your comment, it is possible. But may I have some clue about this? – teccraft Jun 14 '19 at 15:51
  • @AmineMessaoudi I have tried calling the code in my `form_load event`, where I compared the current machine's hard-drive serial number with a string and it doesn't work for me. – teccraft Jun 14 '19 at 15:52
  • duplicate question https://stackoverflow.com/questions/19147/what-is-the-correct-way-to-create-a-single-instance-wpf-application – pasha goroshko Jun 14 '19 at 15:54
  • @pashagoroshko That question is talking about a single process on any computer, not restricting the application to a single computer. – itsme86 Jun 14 '19 at 15:55
  • 1
    @pashagoroshko Your comment and the suggested question are both irrelevant as compare to my question. Both these cases are completely different. – teccraft Jun 14 '19 at 15:59
  • @teccraft you need something like a license key – pasha goroshko Jun 14 '19 at 16:02
  • Whats the reason to run before main if i may ask? it can still be the first thing you do before anything else – nalnpir Jun 14 '19 at 16:09
  • @teccraft you can do that verifying the mac address of a computer. Saving it to a file hiding that information somewhere and verifying if is the mac address of the first app running. – Mikev Jun 14 '19 at 16:19
  • suppose you use obfuscator otherwise decompilation would be easy ... And it`s probably better to use RSA physical key instead to give user access from every PC and secure, although even that gives no guarantee against hack – Vladimir Jun 14 '19 at 21:28

1 Answers1

2

This should work for you:

    static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        if (ValidHD() != true)
        {
            return;
        }
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }

    private static bool ValidHD()
    {
        string hdSN = String.Empty;
        ManagementObjectSearcher moSearcher = new ManagementObjectSearcher("select * from Win32_DiskDrive");
        foreach (ManagementObject wmi_HDD in moSearcher.Get())
        {
            hdSN = wmi_HDD["SerialNumber"].ToString();
        }

        if (hdSN == "Your_SN_Here")
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}

To restrict usage by username you could use this:

    static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        if (ValidUser() != true)
        {
            return;
        }
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }

    private static bool ValidUser()
    {
        if (System.Environment.UserName == "Your_Username_Here")
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}

Hope this helps.

Terry Tyson
  • 629
  • 8
  • 18
  • The solution works for me. However, I am somehow not able to get the current machine's hdd serial number in the correct way. It is not matching somehow – teccraft Jun 14 '19 at 16:34
  • I don't understand what you are saying. Are you trying to log other machines that try to use the program? – Terry Tyson Jun 14 '19 at 16:50
  • No, I actually prevent other machines from using this application. So, I want to use the serial number of machine (which I want to allow this application for) as a string and compare it within the code (like you did that for me). But the code that I have used `hdSN = wmi_HDD["SerialNumber"].ToString();` doesn't get the serial number, somehow. The rest of the approach is perfect, and I have accepted it as an answer for me. – teccraft Jun 14 '19 at 17:13
  • @teccraft I'm not sure why it isn't working for you since this object goes all the way back to .Net 1.1. I've updated my answer to include using the username instead of the HD SN if that helps any. – Terry Tyson Jun 14 '19 at 19:36
  • Should there be any changes if I have SDD? I tried to run the code adding my laptop's serial key inside the quotation mark, but it threw an unhandled exception. Is there a way to solve that? @TerryTyson – Virtuall.Kingg Dec 17 '20 at 02:23
  • @Virtuall.Kingg I have been using SDD for years without issue. Perhaps you should start a new question, show your code, and the exact error message. No doubt someone will be able to help. – Terry Tyson Dec 21 '20 at 15:58