如何使用C#修改本地Windows系統(tǒng)時(shí)間
C#提升管理員權(quán)限修改本地Windows系統(tǒng)時(shí)間
在桌面應(yīng)用程序開發(fā)過程中,需要對(duì)C盤下進(jìn)行文件操作或者系統(tǒng)參數(shù)進(jìn)行設(shè)置,例如在沒有外網(wǎng)的情況下局域網(wǎng)內(nèi)部自己的機(jī)制進(jìn)行時(shí)間同步校準(zhǔn),這是沒有管理員權(quán)限便無法進(jìn)行設(shè)置。

1. 首先需要獲得校準(zhǔn)時(shí)間,兩種方式:
通過可上網(wǎng)的電腦進(jìn)行外部獲取當(dāng)前時(shí)間。
通過NTP實(shí)現(xiàn)
//NTP消息大小摘要是16字節(jié) (RFC 2030) byte[] ntpData = new byte[48]; //設(shè)置跳躍指示器、版本號(hào)和模式值 // LI = 0 (no warning), VN = 3 (IPv4 only), Mode = 3 (Client Mode) ntpData[0] = 0x1B; IPAddress ip = iPAddress; // NTP服務(wù)給UDP分配的端口號(hào)是123 IPEndPoint ipEndPoint = new IPEndPoint(ip, 123); // 使用UTP進(jìn)行通訊 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();
程序手動(dòng)輸入。
2. 轉(zhuǎn)換為本地時(shí)間
//傳輸時(shí)間戳字段偏移量,以64位時(shí)間戳格式,應(yīng)答離開客戶端服務(wù)器的時(shí)間 const byte serverReplyTime = 40; // 獲得秒的部分 ulong intPart = BitConverter.ToUInt32(ntpData, serverReplyTime); //獲取秒的部分 ulong fractPart = BitConverter.ToUInt32(ntpData, serverReplyTime + 4); //由big-endian 到 little-endian的轉(zhuǎn)換 intPart = swapEndian(intPart); fractPart = swapEndian(fractPart); ulong milliseconds = (intPart * 1000) + ((fractPart * 1000) / 0x100000000UL); // UTC時(shí)間 DateTime webTime = (new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc)).AddMilliseconds(milliseconds); //本地時(shí)間 DateTime dt = webTime.ToLocalTime();
3. 獲取當(dāng)前是否是管理員
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);
//轉(zhuǎn)化后的時(shí)間進(jìn)行本地設(shè)置,并返回成功與否
bool isSuccess = SetLocalDateTime(dt);
5. 提升權(quán)限
如果程序不是管理員身份運(yùn)行則不可以設(shè)置時(shí)間
引入引用程序清單文件(app.manifest),步驟:添加新建項(xiàng)->選擇‘應(yīng)用程序清單文件(僅限windows)'
引入后再文件中出現(xiàn)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 |
默認(rèn)權(quán)限:
<requestedExecutionLevel level="asInvoker " uiAccess="false" />
asInvoker 表示當(dāng)前用戶本應(yīng)該具有的權(quán)限
highestAvailable 表示提升當(dāng)前用戶最高權(quán)限
requireAdministrator 表示提升為管理員權(quán)限
修改權(quán)限:
<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>
/// 設(shè)置系統(tǒng)時(shí)間
/// </summary>
/// <param name="dt">需要設(shè)置的時(shí)間</param>
/// <returns>返回系統(tǒng)時(shí)間設(shè)置狀態(tài),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字節(jié) (RFC 2030)
byte[] ntpData = new byte[48];
//設(shè)置跳躍指示器、版本號(hào)和模式值
// LI = 0 (no warning), VN = 3 (IPv4 only), Mode = 3 (Client Mode)
ntpData[0] = 0x1B;
IPAddress ip = iPAddress;
// NTP服務(wù)給UDP分配的端口號(hào)是123
IPEndPoint ipEndPoint = new IPEndPoint(ip, 123);
// 使用UTP進(jìn)行通訊
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;
//傳輸時(shí)間戳字段偏移量,以64位時(shí)間戳格式,應(yīng)答離開客戶端服務(wù)器的時(shí)間
const byte serverReplyTime = 40;
// 獲得秒的部分
ulong intPart = BitConverter.ToUInt32(ntpData, serverReplyTime);
//獲取秒的部分
ulong fractPart = BitConverter.ToUInt32(ntpData, serverReplyTime + 4);
//由big-endian 到 little-endian的轉(zhuǎn)換
intPart = swapEndian(intPart);
fractPart = swapEndian(fractPart);
ulong milliseconds = (intPart * 1000) + ((fractPart * 1000) / 0x100000000UL);
// UTC時(shí)間
DateTime webTime = (new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc)).AddMilliseconds(milliseconds);
//本地時(shí)間
DateTime dt = webTime.ToLocalTime();
bool isSuccess = SetLocalDateTime(dt);
syncDateTime = dt;
}
catch (Exception ex)
{
message = ex.Message;
return false;
}
return true;
}
}
}
以上就是如何使用C#修改本地Windows系統(tǒng)時(shí)間的詳細(xì)內(nèi)容,更多關(guān)于c#修改系統(tǒng)時(shí)間的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
WPF中的ValidationRule實(shí)現(xiàn)參數(shù)綁定解決方案
在WPF中,默認(rèn)情況下,DataContext是通過可視化樹來傳遞的,父元素的DataContext會(huì)自動(dòng)傳遞給其子元素,以便子元素可以訪問父元素的數(shù)據(jù)對(duì)象,這篇文章主要介紹了WPF中的ValidationRule實(shí)現(xiàn)參數(shù)綁定解決方案,需要的朋友可以參考下2023-08-08
C#、ASP.NET通用擴(kuò)展工具類之TypeParse
這篇文章主要介紹了C#、ASP.NET通用擴(kuò)展工具類之TypeParse,使用了此類,類型轉(zhuǎn)換方便多了,本文直接給出實(shí)現(xiàn)代碼和使用方法,需要的朋友可以參考下2015-06-06
C#判斷當(dāng)前程序是否通過管理員運(yùn)行的方法
這篇文章主要介紹了C#判斷當(dāng)前程序是否通過管理員運(yùn)行的方法,可通過非常簡單的系統(tǒng)函數(shù)調(diào)用實(shí)現(xiàn)對(duì)當(dāng)前程序是否通過管理員運(yùn)行進(jìn)行判定,是非常實(shí)用的技巧,需要的朋友可以參考下2014-11-11
C#在DataTable中根據(jù)條件刪除某一行的實(shí)現(xiàn)方法
我們通常的方法是把數(shù)據(jù)源放在DataTable里面,但是偶爾也會(huì)需要把不要的行移除,怎么實(shí)現(xiàn)呢,下面通過代碼給大家介紹c# atatable 刪除行的方法,需要的朋友一起看下吧2016-05-05
C#實(shí)現(xiàn)拷貝文件的9種方法小結(jié)
最近遇一個(gè)問題,一個(gè)程序調(diào)用另一個(gè)程序的文件,結(jié)果另一個(gè)程序的文件被占用,使用不了文件,這時(shí)候的解決方案就是把另一個(gè)程序的文件拷貝到當(dāng)前程序就可以了,本文介紹用C#拷貝文件的多種方式,需要的朋友可以參考下2024-04-04

