Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting the time programmatically in Windows 7

Tags:

c#

windows-7

I'm porting an application from Windows 2000 (don't ask) to Windows 7 and I need to replicate functionality that allows the user to set the time from a GUI. Previously this had been done with a call directly to 'time' using the command prompt, but it appears the user permissions have changed somewhat in Windows 7.

Having done some research, it appears that you can set the time using a call to the kernel32.dll method Win32SetSystemTime, but the same permissions issue arises. Reading MSDN I think I need to enable SE_SYSTEMTIME_NAME, however no matter what I try I can't seem to make this work.

Does anyone have some tested example code for Windows 7 to allow an API call to Win32SetSystemTime?

like image 834
Tim Joseph Avatar asked Oct 19 '10 00:10

Tim Joseph


3 Answers

Not sure why it's not working for you. The following code sets the time to today's date at 4:12 PM UTC. (Worked for me)

public class Program 
{
    public struct SystemTime
    {
        public ushort Year;
        public ushort Month;
        public ushort DayOfWeek;
        public ushort Day;
        public ushort Hour;
        public ushort Minute;
        public ushort Second;
        public ushort Millisecond;
    };

    [DllImport("kernel32.dll", EntryPoint = "SetSystemTime", SetLastError = true)]
    public extern static bool Win32SetSystemTime(ref SystemTime st);

    public static void Main(string[] args)
    {
        SystemTime st = new SystemTime
        {
            Year = 2010, Month = 10, Day = 18, Hour = 16, Minute = 12, DayOfWeek = 1
        };
    }
}

According to the docs:

The calling process must have the SE_SYSTEMTIME_NAME privilege. This privilege is disabled by default. The SetSystemTime function enables the SE_SYSTEMTIME_NAME privilege before changing the system time and disables the privilege before returning. For more information, see Running with Special Privileges.

So seems like that shouldn't be an issue.

like image 110
Kirk Woll Avatar answered Oct 17 '22 15:10

Kirk Woll


Well, if worst comes to worst, there is always

System.Diagnostics.Process.Start("CMD", "/C TIME 19:58");  // set time to 7:58PM
like image 6
I. J. Kennedy Avatar answered Oct 17 '22 16:10

I. J. Kennedy


Your app needs to be elevated to change the time (since changing the time could result in activity logs etc being untrue) but not to change the time zone. Put a manifest on your application with requireAdministrator and the app will elevate. (To test this before making the manifest, right-click your exe and Run As Adminstrator. This will elevate the app just the one time. Elevating is a different thing from being launched by someone who happens to be in the Administrators group. It's about choosing to use your powers.)

Chances are the user won't like the UAC prompt, so if the time-changing is rare, split it out into a separate exe, put a manifest on the main app with asInvoker and another on the time-changer with requireAdministrator, and launch the time-changer from the main app with ShellExecute. Ideally have a button or menu item to make this happen and put a shield icon on it so that the UAC prompt doesn't surprise the user. I decline UAC prompts I wasn't expecting.

like image 4
Kate Gregory Avatar answered Oct 17 '22 16:10

Kate Gregory