J'ai besoin que ma demande expire dans 30 jours à compter d'aujourd'hui. Je vais enregistrer la date du jour dans la configuration de l'application. Comment vérifier si la demande a expiré? Cela ne me dérange pas que l'utilisateur change l'horloge et que l'application fonctionne (utilisateur trop stupide pour le faire).
if (appmode == "Trial") {
????
}
string dateInString = "01.10.2009";
DateTime startDate = DateTime.Parse(dateInString);
DateTime expiryDate = startDate.AddDays(30);
if (DateTime.Now > expiryDate) {
//... trial expired
}
DateTime.AddDays
Est-ce que:
DateTime expires = yourDate.AddDays(30);
Je peux y répondre avec confiance!
DateTime expiryDate = DateTime.Now.AddDays(30);
Ou éventuellement - si vous voulez juste la date sans heure qui pourrait être plus appropriée:
DateTime expiryDate = DateTime.Today.AddDays(30);
DateTime.Now.Add (-30)
Vous donne la date dans 30 jours
DateTime _expiryDate = DateTime.Now + TimeSpan.FromDays(30);
Une solution possible serait, lors de la première utilisation, de créer un fichier contenant la date actuelle et de le placer dans IsolatedStorage. Pour les exécutions ultérieures, vérifiez le contenu du fichier et comparez-le à la date du jour. si la différence de date est supérieure à 30 jours, informez l'utilisateur et fermez l'application.
string[] servers = new string[] {
"nist1-ny.ustiming.org",
"nist1-nj.ustiming.org",
"nist1-pa.ustiming.org",
"time-a.nist.gov",
"time-b.nist.gov",
"nist1.aol-va.symmetricom.com",
"nist1.columbiacountyga.gov",
"nist1-chi.ustiming.org",
"nist.expertsmi.com",
"nist.netservicesgroup.com"
};
string dateStart, dateEnd;
void SetDateToday()
{
Random rnd = new Random();
DateTime result = new DateTime();
int found = 0;
foreach (string server in servers.OrderBy(s => rnd.NextDouble()).Take(5))
{
Console.Write(".");
try
{
string serverResponse = string.Empty;
using (var reader = new StreamReader(new System.Net.Sockets.TcpClient(server, 13).GetStream()))
{
serverResponse = reader.ReadToEnd();
Console.WriteLine(serverResponse);
}
if (!string.IsNullOrEmpty(serverResponse))
{
string[] tokens = serverResponse.Split(' ');
string[] date = tokens[1].Split(' ');
string time = tokens[2];
string properTime;
dateStart = date[2] + "/" + date[0] + "/" + date[1];
int month = Convert.ToInt16(date[0]), day = Convert.ToInt16(date[2]), year = Convert.ToInt16(date[1]);
day = day + 30;
if ((month % 2) == 0)
{
//MAX DAYS IS 30
if (day > 30)
{
day = day - 30;
month++;
if (month > 12)
{
month = 1;
year++;
}
}
}
else
{
//MAX DAYS IS 31
if (day > 31)
{
day = day - 31;
month++;
if (month > 12)
{
month = 1;
year++;
}
}
}
string sday, smonth;
if (day < 10)
{
sday = "0" + day;
}
if (month < 10)
{
smonth = "0" + month;
}
dateEnd = sday + "/" + smonth + "/" + year.ToString();
}
}
catch
{
// Ignore exception and try the next server
}
}
if (found == 0)
{
MessageBox.Show(this, "Internet Connection is required to complete Registration. Please check your internet connection and try again.", "Not connected", MessageBoxButtons.OK, MessageBoxIcon.Information);
Success = false;
}
}
J'ai vu ce code dans certaines parties d'un site Web. Faire l'exemple ci-dessus expose un problème: Le fait de changer l'heure et la date actuelles à la date de début prolongerait l'expiration de l'application.
La solution? Reportez-vous à un serveur de temps en ligne.
Une meilleure solution pourrait être d’introduire un fichier de licence avec un compteur. Ecrivez dans le fichier de licence la date d'installation de l'application (pendant l'installation). Ensuite, chaque fois que l'application est exécutée, vous pouvez éditer le fichier de licence et incrémenter le nombre de 1. Chaque fois que l'application démarre, il vous suffit de vérifier rapidement si les 30 utilisations de l'application ont été atteintes, c'est-à-dire.
if (LicenseFile.Counter == 30)
// go into expired mode
Cela résoudra également le problème si l’utilisateur a remis le compte à rebours du système car vous pouvez effectuer une simple vérification pour indiquer
if (LicenseFile.InstallationDate < SystemDate)
// go into expired mode (as punishment for trying to trick the app!)
Le problème avec votre configuration actuelle est que l'utilisateur devra utiliser l'application tous les jours pendant 30 jours pour obtenir sa version d'essai complète de 30 jours.
Pour ce faire, vous devez enregistrer la première heure d'exécution du programme. La manière dont je le ferais probablement utilise les paramètres d'application intégrés de Visual Studio. Créez-en une appelée InstallDate, qui est un paramètre utilisateur et dont la valeur par défaut est DateTime.MinValue ou quelque chose du genre (par exemple, 1/1/1900).
Ensuite, lorsque le programme est exécuté, la vérification est simple:
if (appmode == "trial")
{
// If the FirstRunDate is MinValue, it's the first run, so set this value up
if (Properties.Settings.Default.FirstRunDate == DateTime.MinValue)
{
Properties.Settings.Default.FirstRunDate = DateTime.Now;
Properties.Settings.Default.Save();
}
// Now check whether 30 days have passed since the first run date
if (Properties.Settings.Default.FirstRunDate.AddMonths(1) < DateTime.Now)
{
// Do whatever you want to do on expiry (exception message/shut down/etc.)
}
}
Les paramètres utilisateur sont stockés dans un emplacement assez étrange (quelque chose comme C:\Documents and Settings\Votre nom\Paramètres locaux\Données d'application), de sorte qu'il sera assez difficile pour un joe moyen de le trouver de toute façon. Si vous voulez être paranoïaque, il suffit de chiffrer la date avant de l'enregistrer dans les paramètres.
EDIT: Soupir, mal interprété la question, pas aussi complexe que je pensais>.>
Un peu tard à cette question, mais j'ai créé une classe avec toutes les méthodes pratiques nécessaires pour créer un essai chronométrique entièrement fonctionnel en C #. Plutôt que la configuration de votre application, j'écris l'heure d'expiration sur le chemin Windows Application Data, qui restera également persistante même après la fermeture du programme (il est également difficile de trouver le chemin pour l'utilisateur moyen).
Complètement documenté et simple à utiliser, j'espère que quelqu'un le trouvera utile!
public class TimeTrialManager
{
private long expiryTime=0;
private string softwareName = "";
private string userPath="";
private bool useSeconds = false;
public TimeTrialManager(string softwareName) {
this.softwareName = softwareName;
// Create folder in Windows Application Data folder for persistence:
userPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData).ToString() + "\\" + softwareName + "_prefs\\";
if (!Directory.Exists(userPath)) Directory.CreateDirectory(Path.GetDirectoryName(userPath));
userPath += "expiryinfo.txt";
}
// Use this method to check if the expiry has already been created. If
// it has, you don't need to call the setExpiryDate() method ever again.
public bool expiryHasBeenStored(){
return File.Exists(userPath);
}
// Use this to set expiry as the number of days from the current time.
// This should be called just once in the program's lifetime for that user.
public void setExpiryDate(double days) {
DateTime time = DateTime.Now.AddDays(days);
expiryTime = time.ToFileTimeUtc();
storeExpiry(expiryTime.ToString() );
useSeconds = false;
}
// Like above, but set the number of seconds. This should be just used for testing
// as no sensible time trial would allow the user seconds to test the trial out:
public void setExpiryTime(double seconds) {
DateTime time = DateTime.Now.AddSeconds(seconds);
expiryTime = time.ToFileTimeUtc();
storeExpiry(expiryTime.ToString());
useSeconds = true;
}
// Check for this in a background timer or whenever else you wish to check if the time has run out
public bool trialHasExpired() {
if(!File.Exists(userPath)) return false;
if (expiryTime == 0) expiryTime = Convert.ToInt64(File.ReadAllText(userPath));
if (DateTime.Now.ToFileTimeUtc() >= expiryTime) return true; else return false;
}
// This method is optional and isn't required to use the core functionality of the class
// Perhaps use it to tell the user how long he has left to trial the software
public string expiryAsHumanReadableString(bool remaining=false) {
DateTime dt = new DateTime();
dt = DateTime.FromFileTimeUtc(expiryTime);
if (remaining == false) return dt.ToShortDateString() + " " + dt.ToLongTimeString();
else {
if (useSeconds) return dt.Subtract(DateTime.Now).TotalSeconds.ToString();
else return (dt.Subtract(DateTime.Now).TotalDays ).ToString();
}
}
// This method is private to the class, so no need to worry about it
private void storeExpiry(string value) {
try { File.WriteAllText(userPath, value); }
catch (Exception ex) { MessageBox.Show(ex.Message); }
}
}
Voici une utilisation typique de la classe ci-dessus. Ça ne pourrait pas être plus simple!
TimeTrialManager ttm;
private void Form1_Load(object sender, EventArgs e)
{
ttm = new TimeTrialManager("TestTime");
if (!ttm.expiryHasBeenStored()) ttm.setExpiryDate(30); // Expires in 30 days time
}
private void timer1_Tick(object sender, EventArgs e)
{
if (ttm.trialHasExpired()) { MessageBox.Show("Trial over! :("); Environment.Exit(0); }
}
@Ed courtenay, @James, J'ai une question stupide . Comment tenir l'utilisateur à l'écart de ce fichier? (Fichier contenant la date d'expiration) . Si l'utilisateur dispose des droits d'installation, il est évident qu'il a accès afficher les fichiers également . Changer l'extension du fichier ne vous aidera pas… .. Alors, comment conserver ce fichier en lieu sûr et à l'abri des utilisateurs?