2010-03-21 1 views
0

내가 내 C# 코드에서 작업 SetSystemTime을 받고 힘든 시간을 보내고 있습니다와 C#을 사용 Windows Vista에서 동작하지 않습니다. SetSystemtime은 kernel32.dll 함수입니다. P/invoke (interop)를 사용하여 호출하고 있습니다. SetSystemtime은 false를 반환하고 오류는 "Invalid Parameter"입니다. 아래 코드를 게시했습니다. 나는 GetSystemTime이 잘 작동한다고 강조한다. 나는 이것을 Vista와 Windows 7에서 테스트했습니다. 일부 뉴스 그룹 게시를 기반으로 UAC를 해제 한 것을 보았습니다. 차이 없음. 나는이 문제에 대한 조사를 해왔다. 이 링크를 찾았습니다 : http://groups.google.com.tw/group/microsoft.public.dotnet.framework.interop/browse_thread/thread/805fa8603b00c267나는 SetSystemTime가 인터롭 (P/호출)

여기서 문제가보고되었지만 해결 방법이없는 것 같습니다. UAC도 언급되었지만 이것이 문제인지는 잘 모르겠다. 또한이 신사는 실제 Win32Error를 얻지 못합니다.

  1. 누군가가 XP에 내 코드를 사용해 볼 수 있습니까?
  2. 누군가 내가 뭘 잘못하고 어떻게 고치고 있는지 말해 줄 수 있습니까? 대답이 어떻게 든 프로그램 적으로 권한 설정을 변경한다면, 나는 예제가 필요하다. 나는 UAC를 끄면 그것을 커버해야한다고 생각했을 것이다.
  3. 이 특별한 방법 (SetSystemTime)을 사용할 필요는 없습니다. 난 그냥 스트레스 테스트 뭔가를 "시계 드리프트"를 소개하려고 해요. 그것을 할 수있는 다른 방법이 있다면 말해주십시오. 솔직하게 말해서 Interop을 사용하여 시스템 시간을 변경해야하는 것에 놀랐습니다. 나는 .NET 메소드가 있다고 생각했을 것이다.

어떤 도움이나 아이디어를 주셔서 대단히 감사합니다. 앤드류

코드 :

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Runtime.InteropServices; 

namespace SystemTimeInteropTest 
{ 
    class Program 
    { 
     #region ClockDriftSetup 
     [StructLayout(LayoutKind.Sequential)] 
     public struct SystemTime 
     { 
      [MarshalAs(UnmanagedType.U2)] 
      public short Year; 
      [MarshalAs(UnmanagedType.U2)] 
      public short Month; 
      [MarshalAs(UnmanagedType.U2)] 
      public short DayOfWeek; 
      [MarshalAs(UnmanagedType.U2)] 
      public short Day; 
      [MarshalAs(UnmanagedType.U2)] 
      public short Hour; 
      [MarshalAs(UnmanagedType.U2)] 
      public short Minute; 
      [MarshalAs(UnmanagedType.U2)] 
      public short Second; 
      [MarshalAs(UnmanagedType.U2)] 
      public short Milliseconds; 
     } 

     [DllImport("kernel32.dll")] 
     public static extern void GetLocalTime(
     out SystemTime systemTime); 

     [DllImport("kernel32.dll")] 
     public static extern void GetSystemTime(
     out SystemTime systemTime); 

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

     //[DllImport("kernel32.dll", SetLastError = true)] 
     //public static extern bool SetLocalTime(
     //ref SystemTime systemTime); 
     [System.Runtime.InteropServices.DllImportAttribute("kernel32.dll", EntryPoint = "SetLocalTime")] 
     [return: System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)] 
     public static extern bool SetLocalTime([InAttribute()] ref SystemTime lpSystemTime); 



     #endregion ClockDriftSetup 
     static void Main(string[] args) 
     { 
      try 
      { 
      SystemTime sysTime; 
      GetSystemTime(out sysTime); 
       sysTime.Milliseconds += (short)80; 
       sysTime.Second += (short)3000; 
       bool bResult = SetSystemTime(ref sysTime); 

       if (bResult == false) 
        throw new System.ComponentModel.Win32Exception(); 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine("Drift Error: " + ex.Message); 
      } 
     } 
    } 
} 
+0

는 끝으로, 당신은 코드와 같은 블록의 형식을 편집기에서 101,010 버튼을 사용할 수 있습니다. – itowlson

+0

초보자 추가 질문이 하나 더 있습니다. 내가 시계를 성공적으로 진전시킨 후 어느 시점에서 (시계가 어떻게 동작하는지에 대한 Gabe의 반응을보십시오), 시계는 정확한 시간으로 되돌아갑니다. 나는이 작업을 얼마나 오래 기다리는 지에 대한 데이터를 수집하고 있지만, 추측 컨대 네트워크 나 기타를 통해 업데이트되는 것으로 추측됩니다. 누구든지이 일을하는 Windows 프로그램/서비스가 있는지 알고 있습니까? 테스트 목적으로 해제 할 수 있습니까? 또는 선호하는 방식으로 네트워크 연결을 끊는 중입니까? 많은 감사합니다. 앤드류 – Dave

답변

6

시간을 설정하는 닷넷 방법이있다; 기본적으로 C#에서는 사용할 수 없습니다. 프로젝트에 Microsoft.VisualBasic에 대한 참조를 추가하는 경우 다음 당신은 쓸 수 있습니다 :

Microsoft.VisualBasic.DateAndTime.TimeOfDay = DateTime.Now.AddSeconds(3000).AddMilliseconds(80); 
+0

게이, 네 고마워. 그것은 나를 위해 일했다! – Dave

+0

한명의 초보자 추가 질문. 내가 시계를 성공적으로 진전시킨 후 어느 시점에서 (시계가 어떻게 동작하는지에 대한 Gabe의 반응을보십시오), 시계는 정확한 시간으로 되돌아갑니다.나는이 작업을 얼마나 오래 기다리는 지에 대한 데이터를 수집하고 있지만, 추측 컨대 네트워크 나 기타를 통해 업데이트되는 것으로 추측됩니다. 누구든지이 일을하는 Windows 프로그램/서비스가 있는지 알고 있습니까? 테스트 목적으로 해제 할 수 있습니까? 또는 선호하는 방식으로 네트워크 연결을 끊는 중입니까? 많은 감사합니다, Andrew – Dave

+0

확률이 높으면'w32time' 서비스를 중단해야합니다. – Gabe

0

그냥 초 필드에 3000을 추가 할 수 없습니다. 0과 60 사이의 초 수를 지정해야합니다. 초, 분, 시간 등의 필드를 모두 조정하여 유효한 범위 내에 있도록해야합니다.

편집 가장 간단한 방법은 실제로 다음 SYSTEMTIME로 다시 변환 FileTimeToSystemTime를 호출 한 후 다시 제공하는 값으로 numSeconds * 10000을 추가하고 SystemTimeToFileTime를 호출하는 것입니다.

+0

codeka, 응답 해 주셔서 감사합니다. 위의 코드를 수정해야 할 필요가 없습니다 (Gabe의 답변 참조). 즉, 나는 3600 초를 추가했고 시계는 1 시간 앞당겨지는 것처럼 보인다. 내가 너를 잘못 이해했는지 모르겠다. – Dave