C#提升管理员权限修改本地Windows系统时间
在桌面应用程序开发过程中,需要对C盘下进行文件操作或者系统参数进行设置,例如在没有外网的情况下局域网内部自己的机制进行时间同步校准,这是没有管理员权限便无法进行设置。

1. 首先需要获得校准时间,两种方式:
通过可上网的电脑进行外部获取当前时间。
通过NTP实现
- //NTP消息大小摘要是16字节 (RFC 2030)
- byte[] ntpData = new byte[48];
- //设置跳跃指示器、版本号和模式值
- // LI = 0 (no warning), VN = 3 (IPv4 only), Mode = 3 (Client Mode)
- ntpData[0] = 0x1B;
- IPAddress ip = iPAddress;
- // NTP服务给UDP分配的端口号是123
- IPEndPoint ipEndPoint = new IPEndPoint(ip, 123);
- // 使用UTP进行通讯
- Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
- socket.Connect(ipEndPoint);
- socket.ReceiveTimeout = 3000;
- socket.Send(ntpData);
- socket.Receive(ntpData);
- socket?.Close();
- socket?.Dispose();
程序手动输入。
2. 转换为本地时间
- //传输时间戳字段偏移量,以64位时间戳格式,应答离开客户端服务器的时间
- const byte serverReplyTime = 40;
- // 获得秒的部分
- ulong intPart = BitConverter.ToUInt32(ntpData, serverReplyTime);
- //获取秒的部分
- ulong fractPart = BitConverter.ToUInt32(ntpData, serverReplyTime + 4);
- //由big-endian 到 little-endian的转换
- intPart = swapEndian(intPart);
- fractPart = swapEndian(fractPart);
- ulong milliseconds = (intPart * 1000) + ((fractPart * 1000) / 0x100000000UL);
- // UTC时间
- DateTime webTime = (new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc)).AddMilliseconds(milliseconds);
- //本地时间
- DateTime dt = webTime.ToLocalTime();
3. 获取当前是否是管理员
- public static bool IsAdministrator()
- {
- WindowsIdentity identity = WindowsIdentity.GetCurrent();
- WindowsPrincipal principal = new WindowsPrincipal(identity);
- return principal.IsInRole(WindowsBuiltInRole.Administrator);
- }
4. 引入dll
- [DllImport("kernel32.dll")]
- private static extern bool SetLocalTime(ref Systemtime time);
-
- //转化后的时间进行本地设置,并返回成功与否
- bool isSuccess = SetLocalDateTime(dt);
5. 提升权限
如果程序不是管理员身份运行则不可以设置时间
引入引用程序清单文件(app.manifest),步骤:添加新建项->选择‘应用程序清单文件(仅限windows)'
引入后再文件中出现app.manifest文件
Value |
Description |
Comment |
asInvoker |
The application runs with the same access token as the parent process. |
Recommended for standard user applications. Do refractoring with internal elevation points, as per the guidance provided earlier in this document. |
highestAvailable |
The application runs with the highest privileges the current user can obtain. |
Recommended for mixed-mode applications. Plan to refractor the application in a future release. |
requireAdministrator |
The application runs only for administrators and requires that the application be launched with the full access token of an administrator. |
Recommended for administrator only applications. Internal elevation points |
默认权限:
- <requestedExecutionLevel level="asInvoker " uiAccess="false" />
asInvoker 表示当前用户本应该具有的权限
highestAvailable 表示提升当前用户最高权限
requireAdministrator 表示提升为管理员权限
修改权限:
- <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
6. 重新生成程序
源码
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Net;
- using System.Net.Sockets;
- using System.Runtime.InteropServices;
- using System.Text;
- using System.Threading.Tasks;
-
- namespace WindowsFormsApp1
- {
-
- public class DateTimeSynchronization
- {
- [StructLayout(LayoutKind.Sequential)]
- private struct Systemtime
- {
- public short year;
- public short month;
- public short dayOfWeek;
- public short day;
- public short hour;
- public short minute;
- public short second;
- public short milliseconds;
- }
-
- [DllImport("kernel32.dll")]
- private static extern bool SetLocalTime(ref Systemtime time);
-
- private static uint swapEndian(ulong x)
- {
- return (uint)(((x & 0x000000ff) << 24) +
- ((x & 0x0000ff00) << 8) +
- ((x & 0x00ff0000) >> 8) +
- ((x & 0xff000000) >> 24));
- }
-
- /// <summary>
- /// 设置系统时间
- /// </summary>
- /// <param name="dt">需要设置的时间</param>
- /// <returns>返回系统时间设置状态,true为成功,false为失败</returns>
- private static bool SetLocalDateTime(DateTime dt)
- {
- Systemtime st;
- st.year = (short)dt.Year;
- st.month = (short)dt.Month;
- st.dayOfWeek = (short)dt.DayOfWeek;
- st.day = (short)dt.Day;
- st.hour = (short)dt.Hour;
- st.minute = (short)dt.Minute;
- st.second = (short)dt.Second;
- st.milliseconds = (short)dt.Millisecond;
- bool rt = SetLocalTime(ref st);
- return rt;
- }
- private static IPAddress iPAddress = null;
- public static bool Synchronization(string host, out DateTime syncDateTime, out string message)
- {
- syncDateTime = DateTime.Now;
- try
- {
- message = "";
- if (iPAddress == null)
- {
- var iphostinfo = Dns.GetHostEntry(host);
- var ntpServer = iphostinfo.AddressList[0];
- iPAddress = ntpServer;
- }
- DateTime dtStart = DateTime.Now;
- //NTP消息大小摘要是16字节 (RFC 2030)
- byte[] ntpData = new byte[48];
- //设置跳跃指示器、版本号和模式值
- // LI = 0 (no warning), VN = 3 (IPv4 only), Mode = 3 (Client Mode)
- ntpData[0] = 0x1B;
- IPAddress ip = iPAddress;
- // NTP服务给UDP分配的端口号是123
- IPEndPoint ipEndPoint = new IPEndPoint(ip, 123);
- // 使用UTP进行通讯
- Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
- socket.Connect(ipEndPoint);
- socket.ReceiveTimeout = 3000;
- socket.Send(ntpData);
- socket.Receive(ntpData);
- socket?.Close();
- socket?.Dispose();
- DateTime dtEnd = DateTime.Now;
- //传输时间戳字段偏移量,以64位时间戳格式,应答离开客户端服务器的时间
- const byte serverReplyTime = 40;
- // 获得秒的部分
- ulong intPart = BitConverter.ToUInt32(ntpData, serverReplyTime);
- //获取秒的部分
- ulong fractPart = BitConverter.ToUInt32(ntpData, serverReplyTime + 4);
- //由big-endian 到 little-endian的转换
- intPart = swapEndian(intPart);
- fractPart = swapEndian(fractPart);
- ulong milliseconds = (intPart * 1000) + ((fractPart * 1000) / 0x100000000UL);
- // UTC时间
- DateTime webTime = (new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc)).AddMilliseconds(milliseconds);
- //本地时间
- DateTime dt = webTime.ToLocalTime();
- bool isSuccess = SetLocalDateTime(dt);
- syncDateTime = dt;
-
- }
- catch (Exception ex)
- {
- message = ex.Message;
- return false;
- }
- return true;
-
- }
- }
- }
以上就是如何使用C#修改本地Windows系统时间的详细内容,更多关于c#修改系统时间的资料请关注w3xue其它相关文章!