C# Windows Forms App Code Query !

Category: c# general

Question

Enhance Technology on Tue, 15 Oct 2019 12:14:53


Hi,

I have a code in C# which have set expiry date as 15 Oct 2019, after this date code will stop working but problem is there if user manually change system date before 15 Oct 2019 then code will start.

Please suggest how can i fix that problem ?

Thanks 

Replies

Kareninstructor on Tue, 15 Oct 2019 13:16:36


Hello,

What does the current code look like in regards to expire date?

Is the app producing a income for you?

In the mean time.

The following is in a button click event to show how to use this solution.

private async void button1_Click(object sender, EventArgs e)
{
    var results = await DateTimeGenerator.Instance.GetNTPTime();
    if (results.Month != DateTime.Now.Month && results.Day != DateTime.Now.Day)
    {
        // Decide how to handle incorrect date
    }
}

Class

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;

namespace WindowsFormsApp1
{
    /// <summary>
    /// https://www.codeproject.com/Articles/1068854/Get-Time-from-NTP-Server-using-Csharp
    /// https://github.com/HansHinnekint/EncryptionLib/blob/master/EncryptionLibrary/DateTimeGenerator.cs
    /// </summary>
    public class DateTimeGenerator
    {
        private static DateTimeGenerator generatorInstance;

        //-------------------------------------------------------------------------------------------------
        //--- Singleton, make sure that only 1 Instance of the class exists
        //-------------------------------------------------------------------------------------------------
        public static DateTimeGenerator Instance
        {
            get
            {
                if (generatorInstance == null)
                {
                    generatorInstance = new DateTimeGenerator();
                }

                return generatorInstance;
            }
        }

        //-------------------------------------------------------------------------------------------------
        //--- Private constructor to initialise the internal variables
        //-------------------------------------------------------------------------------------------------
        private DateTimeGenerator()
        {
        }

        //-------------------------------------------------------------------------------------------------
        //--- Get the UTC time from a public NTP server
        //-------------------------------------------------------------------------------------------------
        public async Task<DateTime> GetNTPTime()
        {
            const string myNTPServer = "pool.ntp.org";
            DateTime TheNetworkTime;

            // NTP message size - 16 bytes of the digest (RFC 2030)
            var myNTPDataArray = new byte[48];

            //Setting the Leap Indicator, Version Number and Mode values
            myNTPDataArray[0] = 0x1B; //LI = 0 (no warning), VN = 3 (IPv4 only), Mode = 3 (Client Mode)

            try
            {

                var myAddresses = Dns.GetHostEntry(myNTPServer).AddressList;

                //The UDP port number assigned to NTP is 123
                var myIPEndPoint = new IPEndPoint(myAddresses[0], 123);
                //NTP uses UDP
                using (var mySocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
                {
                    await Task.Run(() =>
                    {
                        mySocket.Connect(myIPEndPoint);

                        //Stops code hang if NTP is blocked
                        mySocket.ReceiveTimeout = 5000;

                        mySocket.Send(myNTPDataArray);
                        mySocket.Receive(myNTPDataArray);
                    }
                    );
                    mySocket.Close();
                }

                TheNetworkTime = ParseNetworkTime(myNTPDataArray);
            }
            catch (Exception ex)
            {
                TheNetworkTime = DateTime.UtcNow;
            }

            return TheNetworkTime;
        }


        //-------------------------------------------------------------------------------------------------
        //--- Helper Internal methods
        //-------------------------------------------------------------------------------------------------
        private DateTime ParseNetworkTime(byte[] TheByteArray)
        {
            DateTime TheNetworkTime;
            //Offset to get to the "Transmit Timestamp" field (time at which the reply 
            //departed the server for the client, in 64-bit timestamp format."
            const byte TheServerReplyTime = 40;

            //Get the seconds part
            ulong TheIntPart = BitConverter.ToUInt32(TheByteArray, TheServerReplyTime);

            //Get the seconds fraction
            ulong TheFractPart = BitConverter.ToUInt32(TheByteArray, TheServerReplyTime + 4);

            //Convert From big-endian to little-endian
            TheIntPart = SwapEndianness(TheIntPart);
            TheFractPart = SwapEndianness(TheFractPart);

            var TheMilliseconds = (TheIntPart * 1000) + ((TheFractPart * 1000) / 0x100000000L);

            //**UTC** time
            TheNetworkTime = (new DateTime(1900, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)).AddMilliseconds((long)TheMilliseconds);

            //Adapt for empty ByteArray
            if (DateTime.Equals(TheNetworkTime, new DateTime(1900, 1, 1)))
                TheNetworkTime = DateTime.UtcNow;

            return TheNetworkTime;
        }



        // stackoverflow.com/a/3294698/162671
        private uint SwapEndianness(ulong x)
        {
            return (uint)(((x & 0x000000ff) << 24) +
                           ((x & 0x0000ff00) << 8) +
                           ((x & 0x00ff0000) >> 8) +
                           ((x & 0xff000000) >> 24));
        }



    }
}


Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

NuGet BaseConnectionLibrary for database connections.

StackOverFlow
profile for Karen Payne on Stack Exchange


Tim Roberts on Tue, 15 Oct 2019 17:45:23


There is a serious cost/benefit analysis to be done here.  Anything you do can be subverted by a sufficiently motivated hacker.  Nothing is foolproof.  It's just a question of how much you are willing to spend to make it harder on the hackers.

What you are doing now will keep honest people honest, and in most cases that's enough.  No serious user is going to set their whole system clock back just to use one piece of software.

The NTP suggestion from Karen is a nice one.  You can also have the app "phone home" to your web site and pass a validation key that your web site checks.   Both of those require Internet access, of course, and you have to decide what to do if there is no net access.

Simple Samples on Tue, 15 Oct 2019 19:23:34


Thousands of other developers before you have attempted to implement software licensing methods. You can benefit from their experience instead of trying to re-invent something that has been done thousands of times before.

Kareninstructor on Tue, 15 Oct 2019 20:03:25


Good points on Tim's and Simple's replies to consider.


Xingyu Zhao on Wed, 16 Oct 2019 02:47:46


Hi Enhance Technology, 

Thank you for posting here.

As Kareninstructor suggested, NTP is a good choice.

A network time protocol (NTP) server is a machine dedicated as the time sync server for all client computers. If your computer is set to sync with a time server on the network, your clock will show the same time as the server. When the administrator changes the time (for daylight savings), all client machines on the network will also update. This is beneficial for administrators who need to keep clocks in sync for applications and other desktop processes.

Here’s a reference you can refer to.

How to Query an NTP Server using C#?

Best Regards,

Xingyu Zhao

Enhance Technology on Wed, 16 Oct 2019 03:40:13


Hello,

This is the current code !         

Client is not using NTP server/client also not have a internet connection ?

How can i implement your solution along with code ?

One more query 1 tcp port should be generated once this application start ...


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Windows.Forms;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Configuration;

namespace Project_1116_Version_1._0._0._1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            string mac = "B0D1C220A480"; //ENHANCE100
            string machinemac = GetMACAddress();
            if (mac != machinemac)
            {
                MessageBox.Show("Ask Your Administrator");
                this.Close();
            }
            DateTime dt1 = DateTime.Now;
            DateTime dt2 = DateTime.Parse("10/25/2019");
            int tim = 0;
            if (dt1.Date > dt2.Date)
            {
                MessageBox.Show("Your Application is Expire");
                this.Close();
            }
            button1.Enabled = false;
            out_1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
            textBox_search.Enabled = false;
            button4.Enabled = false;
        }
        string final_file = "";
        int pline = 0;
        private void button1_Click(object sender, EventArgs e)
        {
            timer1.Start();
            button3.Enabled = false;
            button4.Enabled = false;
        }
        private void button2_Click(object sender, EventArgs e)
        {
            button3.Enabled = true;
            button1.Enabled = false;
            button4.Enabled = false;
            timer1.Stop();
        }
        private void button3_Click(object sender, EventArgs e)
        {
            file_1.ShowDialog();
            string str = file_1.FileName;
            string str1;
            button4.Enabled = true;
            button1.Enabled = false;
        }
        private void button4_Click(object sender, EventArgs e)
        {
            out_1.ShowDialog();
            File.WriteAllText(out_1.FileName, final_file);
            textBox_search.Enabled = true; 
        }
        private void Form1_Load(object sender, EventArgs e)
        {

        }
        public string GetMACAddress()
        {
            NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
            String sMacAddress = string.Empty;
            foreach (NetworkInterface adapter in nics)
            {
                if (sMacAddress == String.Empty)// only return MAC Address from first card  
                {
                    IPInterfaceProperties properties = adapter.GetIPProperties();
                    sMacAddress = adapter.GetPhysicalAddress().ToString();
                }
            }
            return sMacAddress;
        }
        private void timer1_Tick(object sender, EventArgs e)
        {
            DateTime dt1 = DateTime.Now;
            DateTime dt2 = DateTime.Parse("10/25/2019");
            int tim = 0;
            if (dt1.Date > dt2.Date)
            {
                MessageBox.Show("Your Application is Expire");
            }
            tim = progressBar1.Value;
            if (tim == 100)
                progressBar1.Value = 0;
            String path1 = file_1.FileName;
            String newFilePath = out_1.FileName;
            final_file = "";
            string[] split = textBox_search.Text.Split(',');
            string[] lines = File.ReadAllLines(file_1.FileName);
            if (pline < lines.Count())
            {
                for(int i=pline;i<lines.Count();i++)
                {
                    foreach (string code in split)
                    {
                        if (lines[i].Contains(code))
                            final_file += lines[i] + "\n";
                    }
                }
                if (File.Exists(newFilePath))
                {
                    // Create a file to write to.
                    using (StreamWriter sw = File.AppendText(newFilePath))
                    {
                        sw.WriteLine(final_file);
                    }
                }
                pline = lines.Count();
            }  
                progressBar1.PerformStep(); 
        }
        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }
        private void textBox_search_TextChanged(object sender, EventArgs e)
        {
            if(textBox_search.Text.Length>0)
                button1.Enabled = true;
            else
                button1.Enabled = false;
        }

        private void label1_Click(object sender, EventArgs e)
        {

        }
    }
}




Kareninstructor on Wed, 16 Oct 2019 11:11:46


Hello,

This is the current code !         

Client is not using NTP server/client also not have a internet connection ?

How can i implement your solution along with code ?




Seems very odd for anyone today that does not have a Internet connection. If that is the case I recommend using a third party library (I'm not recommending one as there are plenty to find via a Google search).

Now if they had a Internet connection this is how my recommendation would be implemented which requires C# 7.x as per this page.

Change Program.cs to the following and change the Form1 to the name of your starting form for the project and the namespace from WindowsFormsApp2 to your namespace for your project.

using System;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp2
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static async Task Main()
        {
            Application.EnableVisualStyles();
            var results = await DateTimeGenerator.Instance.GetNTPTime();
            if (results.Month == DateTime.Now.Month && results.Day == DateTime.Now.Day)
            {
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new Form1());
            }
            else
            {
                MessageBox.Show(
                    "Program has expired, please contact the author.");
            }
        }
    }
}
Note I check for month and day but may want to add year to the assertion.


Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

NuGet BaseConnectionLibrary for database connections.

StackOverFlow
profile for Karen Payne on Stack Exchange



CoolDadTx on Wed, 16 Oct 2019 13:55:44


You can't. Using time based code checks isn't sufficient. You need to do something that doesn't rely on the user's machine. One option is to query a time server on the internet. However that means the user would need to allow the call through the firewall and you'd need to know where they are at relative to there.

I would personally recommend that you use a third party licensing library as they have some approaches that are harder to break.

Enhance Technology on Thu, 17 Oct 2019 08:56:00


Thank you so much for your suggestion.

Enhance Technology on Fri, 18 Oct 2019 08:10:04


Hello,

once user start this application 1 define tcp port should be generated avoid to starting duplicate application ?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Windows.Forms;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Configuration;
using System.Globalization;
using System.Net;
using System.Net.Cache;

namespace Project_1116_Version_1._0._0._1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            string mac = "B0D1C220A480"; //ENHANCE100
            string machinemac = GetMACAddress();
            if (mac != machinemac)
            {
                MessageBox.Show("Ask Your Administrator");
                this.Close();
            }
            DateTime dt1 = GetNetworkTime();
            DateTime dt2 = DateTime.Parse("10/27/2019");
            int tim = 0;
            if (dt1.Date > dt2.Date)
            {
                MessageBox.Show("Your Application is Expire");
                this.Close();
            }
            button1.Enabled = false;
            out_1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
            textBox_search.Enabled = false;
            button4.Enabled = false;
        }
        string final_file = "";
        int pline = 0;
        private void button1_Click(object sender, EventArgs e)
        {
            timer1.Start();
            button3.Enabled = false;
            button4.Enabled = false;
        }
        private void button2_Click(object sender, EventArgs e)
        {
            button3.Enabled = true;
            button1.Enabled = false;
            button4.Enabled = false;
            timer1.Stop();
        }
        private void button3_Click(object sender, EventArgs e)
        {
            file_1.ShowDialog();
            string str = file_1.FileName;
            string str1;
            button4.Enabled = true;
            button1.Enabled = false;
        }
        private void button4_Click(object sender, EventArgs e)
        {
            out_1.ShowDialog();
            File.WriteAllText(out_1.FileName, final_file);
            textBox_search.Enabled = true; 
        }
        private void Form1_Load(object sender, EventArgs e)
        {

        }
        public string GetMACAddress()
        {
            NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
            String sMacAddress = string.Empty;
            foreach (NetworkInterface adapter in nics)
            {
                if (sMacAddress == String.Empty)// only return MAC Address from first card  
                {
                    IPInterfaceProperties properties = adapter.GetIPProperties();
                    sMacAddress = adapter.GetPhysicalAddress().ToString();
                }
            }
            return sMacAddress;
        }
        private void timer1_Tick(object sender, EventArgs e)
        {
            DateTime dt1 = GetNetworkTime();
            DateTime dt2 = DateTime.Parse("10/27/2019");
            int tim = 0;
            if (dt1.Date > dt2.Date)
            {
                MessageBox.Show("Your Application is Expire");
            }
            tim = progressBar1.Value;
            if (tim == 100)
                progressBar1.Value = 0;
            String path1 = file_1.FileName;
            String newFilePath = out_1.FileName;
            final_file = "";
            string[] split = textBox_search.Text.Split(',');
            string[] lines = File.ReadAllLines(file_1.FileName);
            if (pline < lines.Count())
            {
                for(int i=pline;i<lines.Count();i++)
                {
                    foreach (string code in split)
                    {
                        if (lines[i].Contains(code))
                            final_file += lines[i] + "\n";
                    }
                }
                if (File.Exists(newFilePath))
                {
                    // Create a file to write to.
                    using (StreamWriter sw = File.AppendText(newFilePath))
                    {
                        sw.WriteLine(final_file);
                    }
                }
                pline = lines.Count();
            }  
                progressBar1.PerformStep(); 
        }
        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }
        private void textBox_search_TextChanged(object sender, EventArgs e)
        {
            if(textBox_search.Text.Length>0)
                button1.Enabled = true;
            else
                button1.Enabled = false;
        }

        private void label1_Click(object sender, EventArgs e)
        {

        }
        public static DateTime GetNetworkTime()
        {
            const string ntpServer = "in.pool.ntp.org";
            var ntpData = new byte[48];
            ntpData[0] = 0x1B; //LeapIndicator = 0 (no warning), VersionNum = 3 (IPv4 only), Mode = 3 (Client Mode)
            Random rnd = new Random();
            int ip = rnd.Next(0, 4);
            var addresses = Dns.GetHostEntry(ntpServer).AddressList;
            var ipEndPoint = new IPEndPoint(addresses[ip], 123);
            var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

            socket.Connect(ipEndPoint);
            socket.Send(ntpData);
            socket.Receive(ntpData);
            socket.Close();

            ulong intPart = (ulong)ntpData[40] << 24 | (ulong)ntpData[41] << 16 | (ulong)ntpData[42] << 8 | (ulong)ntpData[43];
            ulong fractPart = (ulong)ntpData[44] << 24 | (ulong)ntpData[45] << 16 | (ulong)ntpData[46] << 8 | (ulong)ntpData[47];

            var milliseconds = (intPart * 1000) + ((fractPart * 1000) / 0x100000000L);
            var networkDateTime = (new DateTime(1900, 1, 1)).AddMilliseconds((long)milliseconds);

            return networkDateTime;
        }

    }
}

            

Kareninstructor on Fri, 18 Oct 2019 09:37:57


Check the following under project properties

Enhance Technology on Fri, 18 Oct 2019 14:07:37


Unable to find setting in VS 2017 Version 15.9.17

Kareninstructor on Fri, 18 Oct 2019 14:27:00


Unable to find setting in VS 2017 Version 15.9.17

I took the screenshot using VS2017 15.9.17 under project properties.

Enhance Technology on Sat, 19 Oct 2019 02:43:03


Unable to visible in my application.

{

i am trying to posting image but unable to post ??

Error : Body text cannot contain images or links until we are able to verify your account

please help

}