Изменить системное время программно с помощью datetimepeaker
Я пытаюсь изменить системную дату и время, используя следующий код C#. Но в результате systemdate не происходит никаких изменений (также не выдается никакой ошибки). Я попытался, раскомментировав закомментированную часть кода тоже. Но никакого эффекта.:(После этого я попытался изменить время из командной строки.(Не используя C#) Затем он показал "Требуемая привилегия не удерживается клиентом." Я знаю, что это сообщение может не иметь никакого отношения к коду, но я добавляю его чтобы прояснить мою ситуацию.
[StructLayout(LayoutKind.Sequential)]
public struct Systemtime
{
public ushort Year;
public ushort Month;
public ushort DayOfWeek;
public ushort Day;
public ushort Hour;
public ushort Minute;
public ushort Second;
public ushort Millisecond;
}
/*
[DllImport("kernel32.dll", EntryPoint = "GetSystemTime", SetLastError = true)]
[return: MarshalAsAttribute(UnmanagedType.Bool)]
public static extern bool Win32GetSystemTime([InAttribute]ref Systemtime sysTime);
*/
[DllImport("kernel32.dll", EntryPoint = "SetSystemTime", SetLastError = true)]
[return: MarshalAsAttribute(UnmanagedType.Bool)]
public static extern bool Win32SetSystemTime([InAttribute]ref Systemtime sysTime);
private void DateTimeSelectedButton_Click(object sender, EventArgs e)
{
//var neededtime = MonthChangePhenomenonDateTimePicker.Value - TimeSpan.FromHours(5)-TimeSpan.FromMinutes(30);
// Set system date and time
Systemtime updatedTime = new Systemtime();
updatedTime.Year = (ushort)MonthChangePhenomenonDateTimePicker.Value.Year;
updatedTime.Month = (ushort)MonthChangePhenomenonDateTimePicker.Value.Month;
updatedTime.Day = (ushort)MonthChangePhenomenonDateTimePicker.Value.Day;
// UTC time; it will be modified according to the regional settings of the target computer so the actual hour might differ
updatedTime.Hour = (ushort)MonthChangePhenomenonDateTimePicker.Value.Hour;
updatedTime.Minute = (ushort)MonthChangePhenomenonDateTimePicker.Value.Minute;
updatedTime.Second = (ushort)MonthChangePhenomenonDateTimePicker.Value.Second;
// Call the unmanaged function that sets the new date and time instantly
Win32SetSystemTime(ref updatedTime);
MessageBox.Show(@"You Have Current System Time: " + updatedTime);
}
Пожалуйста, помогите мне узнать, что происходит не так. Заранее спасибо.:)
2 ответа
Далее приводится консольное приложение C# для поднятия SE_SYSTEMTIME_NAME на основе сообщения " C# - Как включить SeDebugPrivilege?" В блоге Tri Nguyen, протестированного на моем 64-битном ноутбуке с Windows 7. Пожалуйста, не забудьте оставить комментарий к этому блогу.
using System;
using System.Runtime.InteropServices;
namespace ConsoleApplication1
{
class Program
{
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr GetCurrentProcess();
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool CloseHandle(IntPtr hHandle);
[StructLayout(LayoutKind.Sequential)]
public struct LUID
{
public UInt32 LowPart;
public Int32 HighPart;
}
[StructLayout(LayoutKind.Sequential)]
public struct TOKEN_PRIVILEGES
{
public UInt32 PrivilegeCount;
public LUID Luid;
public UInt32 Attributes;
}
[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool OpenProcessToken(IntPtr ProcessHandle,
UInt32 DesiredAccess, out IntPtr TokenHandle);
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool LookupPrivilegeValue(string lpSystemName, string lpName,
out LUID lpLuid);
// Use this signature if you do not want the previous state
[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool AdjustTokenPrivileges(IntPtr TokenHandle,
[MarshalAs(UnmanagedType.Bool)]bool DisableAllPrivileges,
ref TOKEN_PRIVILEGES NewState,
UInt32 Zero,
IntPtr Null1,
IntPtr Null2);
private static uint TOKEN_QUERY = 0x0008;
private static uint TOKEN_ADJUST_PRIVILEGES = 0x0020;
public const UInt32 SE_PRIVILEGE_ENABLED = 0x00000002;
public const string SE_SYSTEMTIME_NAME = "SeSystemtimePrivilege";
static void Main(string[] args)
{
IntPtr hToken;
string sSEPrivilegeName = SE_SYSTEMTIME_NAME;
LUID luidSEPrivilegeNameValue;
TOKEN_PRIVILEGES tkpPrivileges;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, out hToken))
{
Console.WriteLine("OpenProcessToken() failed, error = {0}. {1} is not available", Marshal.GetLastWin32Error(), sSEPrivilegeName);
return;
}
else
{
Console.WriteLine("OpenProcessToken() successfully");
}
if (!LookupPrivilegeValue(null, SE_SYSTEMTIME_NAME, out luidSEPrivilegeNameValue))
{
Console.WriteLine("LookupPrivilegeValue() failed, error = {0}. {1} is not available", Marshal.GetLastWin32Error(), sSEPrivilegeName);
CloseHandle(hToken);
return;
}
else
{
Console.WriteLine("LookupPrivilegeValue() successfully");
}
tkpPrivileges.PrivilegeCount = 1;
tkpPrivileges.Luid = luidSEPrivilegeNameValue;
tkpPrivileges.Attributes = SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges(hToken, false, ref tkpPrivileges, 0, IntPtr.Zero, IntPtr.Zero))
{
Console.WriteLine("LookupPrivilegeValue() failed, error = {0}. {1} is not available", Marshal.GetLastWin32Error(), sSEPrivilegeName);
}
else
{
Console.WriteLine("{0} is now available", sSEPrivilegeName);
}
CloseHandle(hToken);
Console.ReadLine();
}
}
}
Перед вызовом функции SetSystemTime вы должны повысить привилегию SE_SYSTEMTIME_NAME с помощью функции AdjustTokenPrivileges. Эта функция находится в Advapi32.dll.