Search code examples
c#wpfmvvmtrial

Show application Registration dialog on first run and after trial expired


I am creating a WPF Application implementing trial period by using this library Application Trial Maker this library writing Registration data on SystemFile but when I implement it in my project, it shows the registration dialog on every application run.
What I want is to show registration Dialog only in 2 scenarios:
1- first Run: after the user setup my application. I found these 2 questions check first run and show message and show dialog on first start of application the answers in both are using the Application.Setting and add a bool variable there, but in my case I want to make use of my Trial Maker library also I can't use Setting.Default[] inside my main because it is non-static and am not calling specific view model. I am just calling App.Run as you will see below.
2- when trial period or runs expired.

Here is My App.xaml.cs class :

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using SoftwareLocker;
using System.Globalization;
using System.Threading;

namespace PharmacyManagementSystem
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
    /// <summary>
    /// Application Entry Point.
    /// </summary>
    [System.STAThreadAttribute()]
    [System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "4.0.0.0")]
    public static void Main()
    {

        CultureInfo ci = CultureInfo.CreateSpecificCulture(CultureInfo.CurrentCulture.Name);
        ci.DateTimeFormat.ShortDatePattern = "yyyy-MM-dd";
        ci.DateTimeFormat.LongTimePattern = "HH:mm:ss";
        Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture = ci;

        TrialMaker t = new TrialMaker("Pharmacy Management System",
        System.AppDomain.CurrentDomain.BaseDirectory + "\\RegFile.reg",
        Environment.GetFolderPath(Environment.SpecialFolder.System) +
        "\\TMSetp.dbf",
        "Mobile: +249 914 837664",
        15, 1000, "745");

        byte[] MyOwnKey = { 97, 250,  1,  5,  84, 21,   7, 63,
                     4,  54, 87, 56, 123, 10,   3, 62,
                     7,   9, 20, 36,  37, 21, 101, 57};
        t.TripleDESKey = MyOwnKey;


        bool is_trial;
        TrialMaker.RunTypes RT = t.ShowDialog();
        if (RT != TrialMaker.RunTypes.Expired)
        {
            if (RT == TrialMaker.RunTypes.Full)
                is_trial = false;
            else
                is_trial = true;

            PharmacyManagementSystem.App app = new PharmacyManagementSystem.App();
            app.InitializeComponent();
            /// as i said am just calling App.Run 
            app.Run();
        }
    }
}
}

and here is TrialMaker.cs :

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Win32;
using System.IO;
using Microsoft.VisualBasic;
using System.Windows.Forms;

namespace SoftwareLocker
{
// Activate Property
public class TrialMaker
{
    #region -> Private Variables 

    private string _BaseString;
    private string _Password;
    private string _SoftName;
    private string _RegFilePath;
    private string _HideFilePath;
    private int _DefDays;
    private int _Runed;
    private string _Text;
    private string _Identifier;

    #endregion

    #region -> Constructor 

    /// <summary>
    /// Make new TrialMaker class to make software trial
    /// </summary>
    /// <param name="SoftwareName">Name of software to make trial</param>
    /// <param name="RegFilePath">File path to save password(enrypted)</param>
    /// <param name="HideFilePath">file path for saving hidden information</param>
    /// <param name="Text">A text for contacting to you</param>
    /// <param name="TrialDays">Default period days</param>
    /// <param name="TrialRunTimes">How many times user can run as trial</param>
    /// <param name="Identifier">3 Digit string as your identifier to make password</param>
    public TrialMaker(string SoftwareName,
        string RegFilePath, string HideFilePath,
        string Text, int TrialDays, int TrialRunTimes,
        string Identifier)
    {
        _SoftName = SoftwareName;
        _Identifier = Identifier;

        SetDefaults();

        _DefDays = TrialDays;
        _Runed = TrialRunTimes;

        _RegFilePath = RegFilePath;
        _HideFilePath = HideFilePath;
        _Text = Text;
    }

    private void SetDefaults()
    {
        SystemInfo.UseBaseBoardManufacturer = false;
        SystemInfo.UseBaseBoardProduct = true;
        SystemInfo.UseBiosManufacturer = false;
        SystemInfo.UseBiosVersion = true;
        SystemInfo.UseDiskDriveSignature = true;
        SystemInfo.UsePhysicalMediaSerialNumber = false;
        SystemInfo.UseProcessorID = true;
        SystemInfo.UseVideoControllerCaption = false;
        SystemInfo.UseWindowsSerialNumber = false;

        MakeBaseString();
        MakePassword();
    }

    #endregion

    // Make base string (Computer ID)
    private void MakeBaseString()
    {
        _BaseString = Encryption.Boring(Encryption.InverseByBase(SystemInfo.GetSystemInfo(_SoftName), 10));
    }

    private void MakePassword()
    {
        _Password = Encryption.MakePassword(_BaseString, _Identifier);
    }

    /// <summary>
    /// Show registering dialog to user
    /// </summary>
    /// <returns>Type of running</returns>
    public RunTypes ShowDialog()
    {
        // check if registered before
        if (CheckRegister() == true)
            return RunTypes.Full;

        frmDialog PassDialog = new frmDialog(_BaseString, _Password, DaysToEnd(), _Runed, _Text);

        MakeHideFile();

        DialogResult DR = PassDialog.ShowDialog();

        if (DR == System.Windows.Forms.DialogResult.OK)
        {
            MakeRegFile();
            return RunTypes.Full;
        }
        else if (DR == DialogResult.Retry)
            return RunTypes.Trial;
        else
            return RunTypes.Expired;
    }

    // save password to Registration file for next time usage
    private void MakeRegFile()
    {
        FileReadWrite.WriteFile(_RegFilePath, _Password);
    }

    // Control Registeration file for password
    // if password saved correctly return true else false
    private bool CheckRegister()
    {
        string Password = FileReadWrite.ReadFile(_RegFilePath);

        if (_Password == Password)
            return true;
        else
            return false;
    }

    // from hidden file
    // indicate how many days can user use program
    // if the file does not exists, make it
    private int DaysToEnd()
    {
        FileInfo hf = new FileInfo(_HideFilePath);
        if (hf.Exists == false)
        {
            MakeHideFile();
            return _DefDays;
        }
        return CheckHideFile();
    }

    // store hidden information to hidden file
    // Date,DaysToEnd,HowManyTimesRuned,BaseString(ComputerID)
    private void MakeHideFile()
    {
        string HideInfo;
        HideInfo = DateTime.Now.Ticks + ";";
        HideInfo += _DefDays + ";" + _Runed + ";" + _BaseString;
        FileReadWrite.WriteFile(_HideFilePath, HideInfo);
    }

    // Get Data from hidden file if exists
    private int CheckHideFile()
    {
        string[] HideInfo;
        HideInfo = FileReadWrite.ReadFile(_HideFilePath).Split(';');
        long DiffDays;
        int DaysToEnd;

        if (_BaseString == HideInfo[3])
        {
            DaysToEnd = Convert.ToInt32(HideInfo[1]);
            if (DaysToEnd <= 0)
            {
                _Runed = 0;
                _DefDays = 0;
                return 0;
            }
            DateTime dt = new DateTime(Convert.ToInt64(HideInfo[0]));
            DiffDays = DateAndTime.DateDiff(DateInterval.Day,
                dt.Date, DateTime.Now.Date,
                FirstDayOfWeek.Saturday,
                FirstWeekOfYear.FirstFullWeek);

            DaysToEnd = Convert.ToInt32(HideInfo[1]);
            _Runed = Convert.ToInt32(HideInfo[2]);
            _Runed -= 1;

            DiffDays = Math.Abs(DiffDays);

            _DefDays = DaysToEnd - Convert.ToInt32(DiffDays);
        }
        return _DefDays;
    }

    public enum RunTypes
    {
        Trial = 0,
        Full,
        Expired,
        UnKnown
    }

    #region -> Properties 

    /// <summary>
    /// Indicate File path for storing password
    /// </summary>
    public string RegFilePath
    {
        get
        {
            return _RegFilePath;
        }
        set
        {
            _RegFilePath = value;
        }
    }

    /// <summary>
    /// Indicate file path for storing hidden information
    /// </summary>
    public string HideFilePath
    {
        get
        {
            return _HideFilePath;
        }
        set
        {
            _HideFilePath = value;
        }
    }

    /// <summary>
    /// Get default number of days for trial period
    /// </summary>
    public int TrialPeriodDays
    {
        get
        {
            return _DefDays;
        }
    }

    /// <summary>
    /// Get default number of runs for trial period
    /// i modified here by adding this getter
    /// </summary>
    public int TrialPeriodRuns
    {
        get
        {
            return _Runed;
        }
    }

    /// <summary>
    /// Get or Set TripleDES key for encrypting files to save
    /// </summary>
    public byte[] TripleDESKey
    {
        get
        {
            return FileReadWrite.key;
        }
        set
        {
            FileReadWrite.key = value;
        }
    }

    #endregion

    #region -> Usage Properties 

    public bool UseProcessorID
    {
        get
        {
            return SystemInfo.UseProcessorID;
        }
        set
        {
            SystemInfo.UseProcessorID = value;
        }
    }

    public bool UseBaseBoardProduct
    {
        get
        {
            return SystemInfo.UseBaseBoardProduct;
        }
        set
        {
            SystemInfo.UseBaseBoardProduct = value;
        }
    }

    public bool UseBaseBoardManufacturer
    {
        get
        {
            return SystemInfo.UseBiosManufacturer;
        }
        set
        {
            SystemInfo.UseBiosManufacturer = value;
        }
    }

    public bool UseDiskDriveSignature
    {
        get
        {
            return SystemInfo.UseDiskDriveSignature;
        }
        set
        {
            SystemInfo.UseDiskDriveSignature = value;
        }
    }

    public bool UseVideoControllerCaption
    {
        get
        {
            return SystemInfo.UseVideoControllerCaption;
        }
        set
        {
            SystemInfo.UseVideoControllerCaption = value;
        }
    }

    public bool UsePhysicalMediaSerialNumber
    {
        get
        {
            return SystemInfo.UsePhysicalMediaSerialNumber;
        }
        set
        {
            SystemInfo.UsePhysicalMediaSerialNumber = value;
        }
    }

    public bool UseBiosVersion
    {
        get
        {
            return SystemInfo.UseBiosVersion;
        }
        set
        {
            SystemInfo.UseBiosVersion = value;
        }
    }

    public bool UseBiosManufacturer
    {
        get
        {
            return SystemInfo.UseBiosManufacturer;
        }
        set
        {
            SystemInfo.UseBiosManufacturer = value;
        }
    }

    public bool UseWindowsSerialNumber
    {
        get
        {
            return SystemInfo.UseWindowsSerialNumber;
        }
        set
        {
            SystemInfo.UseWindowsSerialNumber = value;
        }
    }

    #endregion
}
}  

I have added the getter for TrialPeriodRuns to make use of it.
In other scenarios I want my application Run directly without the Dialog for Registering. Other scenarios are when it is full version or when it is un-expired trial not running for first time.
Any ideas how I can achieve this ??


Solution

  • Thanks to the above discussion with @Akram Mashni. I come up with this Solution which work fine for my scenarios.
    I modified the DaysToEnd() Method to public so i can call it with instance of the TrialMaker class from anywhere else (My Main() for example):

    public int DaysToEnd()
    {
        FileInfo hf = new FileInfo(_HideFilePath);
        if (hf.Exists == false)
        {
            MakeHideFile();
            return _DefDays;
        }
        return CheckHideFile();
    }  
    

    Then I make use of it in my Main() method to check my scenarios. When I call DaysToEnd() it will update the info stored on the SystemFile by calling CheckHideFile() inside it.
    I called DaysToEnd() first so i can update the info in the SystemFile
    DaysToEnd() will return int value representing days remain in trial period. Also I called get for TrialPeriodRuns which I added earlier to the library and it represent the remaining runs in the trial period.

    Also I implemented nested if-else statements to check my scenarios:

            int daystoend = t.DaysToEnd();
            int trialperiodruns = t.TrialPeriodRuns;
            /// Check if it is first run here 
            if (dte == 15 && tpr == 1000)
            {
                bool is_trial;
                /// then show the Registration dialog
                TrialMaker.RunTypes RT = t.ShowDialog();
                if (RT != TrialMaker.RunTypes.Expired)
                {
                    if (RT == TrialMaker.RunTypes.Full)
                        is_trial = false;
                    else
                        is_trial = true;
    
                    PharmacyManagementSystem.App app = new PharmacyManagementSystem.App();
                    app.InitializeComponent();
                    app.Run();
                }
            }
            /// Check if it is trial but not first run
            /// no Registration Dialog will show in this case
            else if (dte > 0 && tpr > 0)
            {
                PharmacyManagementSystem.App app = new PharmacyManagementSystem.App();
                app.InitializeComponent();
                app.Run();
            }
            /// Check if it is expired trial
            else if (dte == 0 || tpr == 0)
            {
                bool is_trial;
                /// then show the Registration Dialog here
                TrialMaker.RunTypes RT = t.ShowDialog();
                if (RT != TrialMaker.RunTypes.Expired)
                {
                    if (RT == TrialMaker.RunTypes.Full)
                        is_trial = false;
                    else
                        is_trial = true;
    
                    PharmacyManagementSystem.App app = new PharmacyManagementSystem.App();
                    app.InitializeComponent();
                    app.Run();
                }
            }
            /// the full version scenario remain and it comes here 
            /// no need to show Registration Dialog
            else
            {
                bool is_trial;
                TrialMaker.RunTypes RT = t.ShowDialog();
                if (RT != TrialMaker.RunTypes.Expired)
                {
                    if (RT == TrialMaker.RunTypes.Full)
                        is_trial = false;
                    else
                        is_trial = true;
    
                    PharmacyManagementSystem.App app = new PharmacyManagementSystem.App();
                    app.InitializeComponent();
                    app.Run();
                }
            }  
    

    And finally it works like a charm for me
    thanks again @Akram Mashni for inspiring me