我不能使用C#和Interop(P / Invoke)让SetSystemTime在Windows Vista中工作

我很难让SetSystemTime在我的C#代码中工作。 SetSystemtime是一个kernel32.dll函数。 我正在使用P / invoke(interop)来调用它。 SetSystemtime返回false,错误为“Invalid Parameter”。 我已经发布了以下代码。 我强调GetSystemTime工作正常。 我已经在Vista和Windows 7上对此进行了测试。根据一些新闻组post,我看到我关闭了UAC。 没有不同。 我已经做了一些搜索这个问题。 我找到了这个链接: http : //groups.google.com.tw/group/microsoft.public.dotnet.framework.interop/browse_thread/thread/805fa8603b00c267

报告问题但似乎没有找到解决方案。 请注意,还提到了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); } } } } 

有一种.Net方法来设置时间; 它默认情况下在C#中不可用。 如果您向项目添加对Microsoft.VisualBasic的引用,那么您只需编写:

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

您不能只在秒字段中添加3000。 您需要指定0到60之间的秒数。您需要调整秒,分钟,小时等字段,以便它们都在有效范围内。

编辑最简单的方法实际上是调用SystemTimeToFileTime然后将numSeconds * 10000添加到它返回的值,然后调用FileTimeToSystemTime转换回SystemTime。