代码之家  ›  专栏  ›  技术社区  ›  Dave

我无法让setSystemTime在Windows Vista中使用c with interop(p/invoke)工作。

  •  0
  • Dave  · 技术社区  · 15 年前

    我很难让SetSystemTime在我的C代码中工作。setsystemtime是kernel32.dll函数。我正在使用p/invoke(interop)来调用它。setSystemTime返回false,错误为“无效参数”。我已经发布了下面的代码。我强调GetSystemTime工作得很好。我在Vista和Windows7上测试过。根据我看到的一些新闻组帖子,我关闭了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);
                }
            }
        }
    }
    
    2 回复  |  直到 14 年前
        1
  •  6
  •   Gabe Timothy Khouri    15 年前

    有一个.NET方法来设置时间;默认情况下,它在C中不可用。如果添加引用 Microsoft.VisualBasic 对于你的项目,你只需写:

    Microsoft.VisualBasic.DateAndTime.TimeOfDay = DateTime.Now.AddSeconds(3000).AddMilliseconds(80);
    
        2
  •  0
  •   Dean Harding    15 年前

    不能只在秒字段中添加3000。您需要指定一个介于0和60之间的秒数。您需要调整秒、分钟、小时等字段,使它们都在有效范围内。

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