문제

원격 기계에서 원격으로 시간을 설정하는 가장 좋은 방법은 무엇입니까? 머신은 Windows XP를 실행 중이며 웹 서비스 호출을 통해 새로운 시간을 받고 있습니다. 목표는 원격 기계를 서버와 동기화하는 것입니다. 웹 서비스가 유일한 액세스가되도록 시스템이 잠겨 있으므로 각 원격 시스템에서 시간 서버를 사용할 수 없습니다.

도움이 되었습니까?

해결책

Windows 내장 인터넷 시간 능력을 사용합니다. 당신은 설정할 수 있습니다 시간 서버 서버에서 2 차 타임 서버에서 시간을 얻고 모든 클라이언트 머신이 시간을 보내도록하십시오.

나는 이전에 신청서-시스템 시간 도로를 내려 갔다.

다른 팁

시스템 시간 설정을위한 Win32 API 호출입니다.

[StructLayout(LayoutKind.Sequential)] 
public struct SYSTEMTIME { 
 public short wYear; 
 public short wMonth; 
 public short wDayOfWeek; 
 public short wDay; 
 public short wHour; 
 public short wMinute; 
 public short wSecond; 
 public short wMilliseconds; 
 } 
 [DllImport("kernel32.dll", SetLastError=true)] 
public static extern bool SetSystemTime(ref SYSTEMTIME theDateTime ); 

그래도 고객에게 해당 기능을 실행할 수 있도록 보안을 어떻게 해결할 것인지 잘 모르겠습니다.

시스템 시간 설정에 대한 자세한 내용을 얻을 수 있습니다. 핀 보크.

시스템 시간을 위해 네트워크 머신을 쿼리하는 방법은 netRemotetod.

다음은 Delphi에서 수행하는 코드입니다 (사용 예는 아래에 게시되어 있음).

Windows API 호출에 의존하므로 C#에서는 너무 다르지 않아야합니다.

unit TimeHandler;

interface

type
  TTimeHandler = class
  private
    FServerName : widestring;
  public
    constructor Create(servername : widestring);
    function RemoteSystemTime : TDateTime;
    procedure SetLocalSystemTime(settotime : TDateTime);
  end;

implementation

uses
  Windows, SysUtils, Messages;

function NetRemoteTOD(ServerName :PWideChar; var buffer :pointer) : integer; stdcall; external 'netapi32.dll';
function NetApiBufferFree(buffer : Pointer) : integer; stdcall; external 'netapi32.dll';

type
  //See MSDN documentation on the TIME_OF_DAY_INFO structure.
  PTime_Of_Day_Info = ^TTime_Of_Day_Info;
  TTime_Of_Day_Info = record
    ElapsedDate : integer;
    Milliseconds : integer;
    Hours : integer;
    Minutes : integer;
    Seconds : integer;
    HundredthsOfSeconds : integer;
    TimeZone : LongInt;
    TimeInterval : integer;
    Day : integer;
    Month : integer;
    Year : integer;
    DayOfWeek : integer;
  end;

constructor TTimeHandler.Create(servername: widestring);
begin
  inherited Create;
  FServerName := servername;
end;

function TTimeHandler.RemoteSystemTime: TDateTime;
var
  Buffer : pointer;
  Rek : PTime_Of_Day_Info;
  DateOnly, TimeOnly : TDateTime;
  timezone : integer;
begin
  //if the call is successful...
  if 0 = NetRemoteTOD(PWideChar(FServerName),Buffer) then begin
    //store the time of day info in our special buffer structure
    Rek := PTime_Of_Day_Info(Buffer);

    //windows time is in GMT, so we adjust for our current time zone
    if Rek.TimeZone <> -1 then
      timezone := Rek.TimeZone div 60
    else
      timezone := 0;

    //decode the date from integers into TDateTimes
    //assume zero milliseconds
    try
      DateOnly := EncodeDate(Rek.Year,Rek.Month,Rek.Day);
      TimeOnly := EncodeTime(Rek.Hours,Rek.Minutes,Rek.Seconds,0);
    except on e : exception do
      raise Exception.Create(
                             'Date retrieved from server, but it was invalid!' +
                             #13#10 +
                             e.Message
                            );
    end;

    //translate the time into a TDateTime
    //apply any time zone adjustment and return the result
    Result := DateOnly + TimeOnly - (timezone / 24);
  end  //if call was successful
  else begin
    raise Exception.Create('Time retrieval failed from "'+FServerName+'"');
  end;

  //free the data structure we created
  NetApiBufferFree(Buffer);
end;

procedure TTimeHandler.SetLocalSystemTime(settotime: TDateTime);
var
  SystemTime : TSystemTime;
begin
  DateTimeToSystemTime(settotime,SystemTime);
  SetLocalTime(SystemTime);
  //tell windows that the time changed
  PostMessage(HWND_BROADCAST,WM_TIMECHANGE,0,0);
end;

그리고 여기에 사용 예가 있습니다.

procedure TfrmMain.SynchLocalTimeWithServer;
var
  tod : TTimeHandler;
begin
  tod := TTimeHandler.Create(cboServerName.Text);
  try
    tod.SetLocalSystemTime(tod.RemoteSystemTime);
  finally
    FreeAndNil(tod);
  end;  //try-finally
end;

다음은 몇 년 동안 사용해 온 루틴입니다. DateTime 당사의 SQL Server (파일 시간 사용)에서 가치를 부여하여 SYSTEMTIME 그것은 PC에 설정됩니다.

이것은 PC 및 Windows 모바일 장치에서 작동합니다.

SQL 서버에 전화 할 때 언제든지 호출 할 수 있습니다.

public class TimeTool {

  private static readonly DateTime NODATE = new DateTime(1900, 1, 1);

#if PocketPC
  [DllImport("coredll.dll")]
#else
  [DllImport("kernel32.dll")]
#endif
  static extern bool SetLocalTime([In] ref SYSTEMTIME lpLocalTime);

  public struct SYSTEMTIME {
    public short Year, Month, DayOfWeek, Day, Hour, Minute, Second, Millisecond;
    /// <summary>
    /// Convert form System.DateTime
    /// </summary>
    /// <param name="time">Creates System Time from this variable</param>
    public void FromDateTime(DateTime time) {
      Year = (short)time.Year;
      Month = (short)time.Month;
      DayOfWeek = (short)time.DayOfWeek;
      Day = (short)time.Day;
      Hour = (short)time.Hour;
      Minute = (short)time.Minute;
      Second = (short)time.Second;
      Millisecond = (short)time.Millisecond;
    }

    public DateTime ToDateTime() {
      return new DateTime(Year, Month, Day, Hour, Minute, Second, Millisecond);
    }

    public static DateTime ToDateTime(SYSTEMTIME time) {
      return time.ToDateTime();
    }
  }

  // read SQL Time and set time on device
  public static int SyncWithSqlTime(System.Data.SqlClient.SqlConnection con) {
    SYSTEMTIME systemTime = new SYSTEMTIME();
    DateTime sqlTime = NODATE;
    string sql = "SELECT GETDATE() AS [CurrentDateTime]";
    using (System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand(sql, con)) {
      try {
        cmd.Connection.Open();
        System.Data.SqlClient.SqlDataReader r = cmd.ExecuteReader();
        while (r.Read()) {
          if (!r.IsDBNull(0)) {
            sqlTime = (DateTime)r[0];
          }
        }
      } catch (Exception) {
        return -1;
      }
    }
    if (sqlTime != NODATE) {
      systemTime.FromDateTime(sqlTime); // Convert to SYSTEMTIME
      if (SetLocalTime(ref systemTime)) { //Call Win32 API to set time
        return 1;
      }
    }
    return 0;
  }

}

아마도 일부 조합을 사용하여 배치 파일로 이것을 할 수도 있습니다.

TIME

시간을 설정하고

net time \\server_name

서버에서 시간을 검색합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top