Я не могу заставить SetSystemTime работать в Windows Vista, используя C # с Interop (P / Invoke) - PullRequest
0 голосов
/ 21 марта 2010

Мне трудно заставить SetSystemTime работать в моем коде C #. SetSystemtime является функцией kernel32.dll. Я использую P / invoke (interop), чтобы вызвать его. SetSystemtime возвращает false, и ошибка «Неверный параметр». Я разместил код ниже. Я подчеркиваю, что GetSystemTime работает просто отлично. Я проверил это в Vista и Windows 7. На основании сообщений в новостных группах, которые я видел, я отключил 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.

Большое спасибо за любую помощь или идеи. Andrew

Код:

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 ]

6 голосов
/ 21 марта 2010

.Net метод для установки времени; это просто не доступно в C # по умолчанию. Если вы добавите ссылку на Microsoft.VisualBasic в свой проект, тогда вы можете просто написать:

Microsoft.VisualBasic.DateAndTime.TimeOfDay = DateTime.Now.AddSeconds(3000).AddMilliseconds(80);
0 голосов
/ 21 марта 2010

Вы не можете просто добавить 3000 в поле секунд. Вам необходимо указать количество секунд в диапазоне от 0 до 60. Необходимо настроить поля секунд, минут, часов и т. Д., Чтобы они все находились в допустимом диапазоне.

Редактировать На самом деле самый простой способ - вызвать SystemTimeToFileTime , затем добавить numSeconds * 10000 к возвращаемому значению, а затем вызвать FileTimeToSystemTime для преобразования обратно в SystemTime.

...