Introduction
I recently launched the Beta version of an application which I had been using for some time, and was somewhat alarmed when I was delivered a message advising that the Beta version's time had expired! This I had not been expecting, and I was in quite a spot as the project I was developing was not finished.
Clearly, the application had looked at the system clock, and I wondered if putting the clock back for the time being would enable me to continue using the application. I manually changed the year back to 2005, and found that the application now launched normally. Further, it continued to run normally even after I reset the clock.
Now, using a backdated system clock is no way to live, so I wondered if I could backdate the clock, launch the application, then reset the clock, all within one utility. The answer turns out to be yes, and it is quite straightforward, which is not to say that discovering how to achieve it was straightforward.
I ideally wanted to devise a console application, since there was no need for a form. I just wanted to launch the application by clicking an item on the Taskbar, as I had always done.
A working example
Launching an application from within another is easily done. Let us see if we can launch Solitaire from within a console application. The following code will do it (I copied SOL.EXE to C:\ to keep the source simple - be aware you must specify a fully qualified path to the application which you wish to launch):
Start up a new console application project, and paste the following:
using System;
using System.Diagnostics;
namespace ConsoleApplication_LaunchSolitaire
{
class Program
{
static void Main(string[] args)
{
Process.Start(@"C:\SOL.EXE");
}
}
}
When you run this application, you will see the DOS screen for a moment and Solitaire will launch.
That DOS screen is something of a nuisance, so we will need to get rid of it. But first, how would we set the clock back to 2005 before launching Solitaire? I found a lot of information (and mis-information!) on this matter, most of which was not very helpful, before coming across some definitive code at PINVOKE.NET. See SetLocalTime (kernel32).
Armed with this, we are now able to backdate the clock, launch Solitaire, then reset the clock. The full code is as follows (if you read Yuan Xiaohui's article first, the code should be self explanatory):
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace ConsoleApplication_LaunchSolitaire
{
class Program
{
[DllImport("Kernel32.dll")]
public static extern bool SetLocalTime(ref SYSTEMTIME Time);
public struct SYSTEMTIME
{
public ushort wYear;
public ushort wMonth;
public ushort wDayOfWeek;
public ushort wDay;
public ushort wHour;
public ushort wMinute;
public ushort wSecond;
public ushort wMilliseconds;
public void FromDateTime(DateTime time)
{
wYear = (ushort)time.Year;
wMonth = (ushort)time.Month;
wDayOfWeek = (ushort)time.DayOfWeek;
wDay = (ushort)time.Day;
wHour = (ushort)time.Hour;
wMinute = (ushort)time.Minute;
wSecond = (ushort)time.Second;
wMilliseconds = (ushort)time.Millisecond;
}
}
static void Main(string[] args)
{
int offset = DateTime.Now.Year - 2005;
SYSTEMTIME st = new SYSTEMTIME();
DateTime t2005 = DateTime.Now.AddYears( - offset );
st.FromDateTime(t2005);
SetLocalTime(ref st);
Process.Start(@"C:\SOL.EXE");
DateTime tCurrentYear = DateTime.Now.AddYears( + offset );
st.FromDateTime(tCurrentYear);
SetLocalTime(ref st);
}
}
}
Once this has been built, close down the project, and run the application from the Run menu, or via a shortcut which you will know how to construct. This will give you a better real time view of what is happening.
Two things remain to be done. Firstly, in the working example, Solitaire launches without the system clock being checked, and so it is quite safe to reset the clock immediately after the launch instruction is issued. Where the clock will be checked, however, as in the case of my Beta, it becomes necessary to introduce a delay before the clock is reset, to ensure the check is completed before the reset occurs. The following is all that is necessary to implement an arbitrary delay of 5 seconds:
System.Threading.Thread.Sleep(5000);
Now, secondly, how do we get rid of the intrusive DOS screen? Once you are satisfied your clock manipulation and launch are working correctly, look at the Project | Properties page. Change the Output Type from Console Application to Windows Application, and rebuild. This tip I came across by chance on one of the forums but I didn't note the author's name.
There being no Form, the application will run as a Form-less Windows application. Copy the shortcut to the Taskbar, or put a dummy item on the Taskbar and rename its target to, in this example, "C:\SOL.EXE", and Solitaire (or anything else you have nominated) will launch normally.
It is instructive to look at the system clock while the launch is under way. Get the clock up on the screen and run the application. You will see the year immediately change to 2005 as Solitaire launches, and then, 5 seconds later, the year changes back to the current year.
If you are unhappy about the clock manipulation introducing a small error between the change and reset, then consider using an NTP server to keep your clock up to date.
Most of the work done for this project was done by others. The only credit I am entitled to claim is the bringing together of the several elements in to a very simple and versatile utility.
An old assembly language programmer (8051 microcontroller) and a recent convert from Delphi. Retired ten years ago and rather enjoy writing C# code.