Jump to content
Ian Branch

TIdSNTP.SyncTime ??

Recommended Posts

Hi Team,

D10.4.1, Indy as comes with D10.4, 32 bit App.  Tested on Win 10 & Win 2012 R2 server.

I have the following code in my App in the form create procedure with IdSNTP in the uses..

var
  SNTPClient: TIdSNTP;
begin
  //
  SNTPClient := TIdSNTP.Create(nil);
  try
    //
    SNTPClient.Host := 'time.windows.com';
    //
    ShowMessage(DateTimeToStr(SNTPClient.DateTime));
    //
    if SNTPClient.SyncTime then
    ShowMessage('Time sync worked.')
    else
    ShowMessage('Time Sync didnt work.');
    //
  finally
    SNTPClient.Free;
  end;
  //

When run, the initial showmessage shows the correct date/time but I get the "didn't work" message after the .SyncTime.

I manually changed my PC clock out of sync and ran the routine again, it didn't adjust the clock.

I seem to recall many moons ago that this did work, possibly with D10.3, I don't exactly recall.  My original code was created in Nov'19.

What have I missed please???

 

Regards & TIA,

Ian

 

Edited by Ian Branch

Share this post


Link to post

TIdSNTP.SyncTime() uses the Win32 SetLocalTime() function, which requires the calling process to have the SE_SYSTEMTIME_NAME privilege present in its user token (even if it is not enabled, it just needs to be present - SetLocalTime() will enable it for the duration of the call).  By default, only an elevated admin has that privilege present in its token.  So, you will have to either run your whole app as an elevated user, or at least split out your sync code into a separate process or service that runs as an elevated admin or the SYSTEM account.

Edited by Remy Lebeau

Share this post


Link to post

Ah Ha!  Thanks Remy, appreciated.

Is there an alternative?

my goal is to embed it into an existing App for a Pacific Customer who is notorious for not maintaining his server & wkstn clocks time. :-(

Regards,

Ian

Share this post


Link to post
Guest
4 hours ago, Ian Branch said:

Is there an alternative?

There is.

 

Because time is mission critical from DB to any logging you are doing, i would suggest better approach, and that is use the Task Scheduler, the idea that instead of supply your customer with PowerShell script instead of an app, the script will be ran once with elevated privileges, creating a task to execute another script to synchronize time ( like once per day).

Now if you don't want another script, then simply use these command lines

Quote

net start w32time
W32tm /resync /force

The first line to ensure Windows Time service is running but because w32tm can't run the Service if it is stopped when configured to Manual StartUp.

These commands will not work if the WT service is disabled.

These commands are not for PowerShell, to use PS there is different commands like "Start-Service" etc..

 

Even you can create the task using command line instead of the PS script, the point is use the OS Task Scheduler is easier and more accurate, in fact there is an OS task to do so, you script is to disable that OS task or change it, and make sure to set the right time zone.

 

Now this should not be happening to begin with, i mean you configure time and forget about it, so my two cents here is your customer server is running on Virtual Machine, means when you sync the time you are not solving the problem as it will revert back to the host machine time, to solve this make sure the host machine is configured right (correct Time and Time Zone), then make sure the Guest machine has the right Time Zone, not the time itself.

Share this post


Link to post

HI Kas,

Thanks for that.  I will give it a go.  I'll try it on my PC first and if OK will set it up on the Clients.

 

Regards,

Ian

Share this post


Link to post
14 hours ago, Ian Branch said:

Is there an alternative?

my goal is to embed it into an existing App for a Pacific Customer who is notorious for not maintaining his server & wkstn clocks time. 😞

If you don't want to run the whole app elevated, and don't want to use a separate elevated process for the sync code, you could separate the sync code into a COM object, and then the main app can run unelavated and load the COM object elevated when needed by using the COM Elevation Moniker.  This way, everything is kept in a single process.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×