c#獲取指定時間並修改本機時間


  由於項目的的需要,系統中的各終端機時間必須與服務器保持一致,卻由於是內部服務器,不連接外網,所以沒辦法使用百度的地址作為時間地址標准,購買一個時間服務器又會增加成本,所以想着自己做一個簡易的程序來同步服務器上面的時間。

  在最初的操作時確實很順利,百度了一下出來很多修改時間的辦法。在自己的本地環境中測試沒任何問題,在其他PC機上同步我的時間也正常,於是很高興的拿來用了,然而,實際生產環境中卻無法使用,提示“無法連接到遠程服務器”,在網上找了很多方法,包括開啟80端口服務;在調用.net的API修改時間方法SetLocalTime(&time)之前,先設置SYSTEMTIME time = systemtime;等多種辦法,還是沒能解決問題。最后終於在微軟社區中找到了一篇,在VS中設置程序自動以管理員權限運行的博客,配合之前的獲取數據庫的時間,然后進行本機時間修改的方法,解決了問題。

  解決方法的連接:https://social.msdn.microsoft.com/Forums/zh-CN/fd806d68-a895-4df6-b7f2-3c158357952e/-win10-datetimenowtostring-0318-224209-?forum=2212

下面是代碼:

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Data.SqlClient;
using static 自動同步時間.Form1;

namespace 自動同步時間
{
    public partial class Form1 : Form
    {
        SqlConnect con = new SqlConnect();
        SqlDataReader dr;
        public Form1()
        {
            InitializeComponent();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            UpdateTime();
        }
        /**
     * 系統時間的設置
     * */
        [StructLayout(LayoutKind.Sequential)]
        public struct SystemTime
        {
            public ushort wYear;
            public ushort wMonth;
            public ushort wDayOfWeek;
            public ushort wDay;
            public ushort wHour;
            public ushort wMinute;
            public ushort wSecond;
            public ushort wMiliseconds;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.Width = 0;
            this.Height = 0;

            UpdateTime();

            timer1.Interval = 604800000;
            if (!CheckExistRegisterApp()) {
                SetRegistryApp();
            }
        }
        private bool UpdateTime() {
            string dtSql = "select  getdate()";//獲取數據庫時間,同步本機時間
            string whStr = "Server=192.168.1.62;initial Catalog=WKDB;user id=sa;password=admin12345678;Connect Timeout=5;Max Pool Size=100;Min Pool Size=5";//數據庫連接字符串
            SqlConnection whCon = new SqlConnection(whStr);
            whCon.Open();
            try
            {

                SqlCommand cmd1 = new SqlCommand(dtSql, whCon);
                dr = cmd1.ExecuteReader();
                DateTime da;
                dr = con.select(dtSql);
                if (dr.Read())
                {
                    da = dr.GetDateTime(0);

                    string dt = da.ToString();
                    SystemTime sysTime = new SystemTime();
                    DateTime datetime = (Convert.ToDateTime(dt));
                    sysTime.wYear = (ushort)datetime.Year;
                    sysTime.wMonth = (ushort)datetime.Month;
                    sysTime.wDay = (ushort)datetime.Day;
                    sysTime.wDayOfWeek = (ushort)datetime.DayOfWeek;
                    sysTime.wHour = (ushort)datetime.Hour;
                    sysTime.wMinute = (ushort)datetime.Minute;
                    sysTime.wSecond = (ushort)datetime.Second;
                    sysTime.wMiliseconds = (ushort)datetime.Millisecond;
                    //SystemTime time = sysTime;//這里是解決問題過程中百度的方法,但是不起作用
                    return SetSystemDateTime.SetLocalTime(ref sysTime);

                }
            }
            catch (Exception ex)
            {
                Util.outlogtext("更新時間失敗");//簡單的日志輸出
                Util.outlogtext(ex.ToString());
            }
            finally
            {
                con.close();
            }
            return false;
        }
        /// <summary>
        ///     檢查當前程序是否在啟動項中
        /// </summary>
        /// <returns></returns>
        public static bool CheckExistRegisterApp()
        {
            string ShortFileName = Application.ProductName;           //獲得應用程序名
            bool bResult = false;

            try
            {
                Microsoft.Win32.RegistryKey Reg;
                Reg = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Run", true);
                if (Reg == null)
                {
                    Reg = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Run");
                }


                foreach (string s in Reg.GetValueNames())
                {
                    if (s.Equals(ShortFileName))
                    {
                        bResult = true;
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                return false;
            }
            return bResult;
        }
        /// <summary>
        /// 注冊表操作,將程序添加到啟動項
        /// </summary>
        public static void SetRegistryApp()
        {
            try
            {
                Microsoft.Win32.RegistryKey Reg;
                string ShortFileName = Application.ProductName;
                Reg = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Run", true);
                if (Reg == null)
                {
                    Reg = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Run");
                }
                Reg.SetValue(ShortFileName, Application.ExecutablePath);
            }
            catch (Exception ex)
            {
            }
        }
    }
    public class SetSystemDateTime
    {
        [DllImport("Kernel32.dll")]
        public static extern bool SetLocalTime(ref SystemTime sysTime);

        public static bool SetLocalTimeByStr(string timestr)
        {
            bool flag = false;
            SystemTime sysTime = new SystemTime();
            DateTime dt = Convert.ToDateTime(timestr);
            sysTime.wYear = Convert.ToUInt16(dt.Year);
            sysTime.wMonth = Convert.ToUInt16(dt.Month);
            sysTime.wDay = Convert.ToUInt16(dt.Day);
            sysTime.wHour = Convert.ToUInt16(dt.Hour);
            sysTime.wMinute = Convert.ToUInt16(dt.Minute);
            sysTime.wSecond = Convert.ToUInt16(dt.Second);
            try
            {
                flag = SetSystemDateTime.SetLocalTime(ref sysTime);
            }
            catch (Exception e)
            {
                Console.WriteLine("SetSystemDateTime函數執行異常" + e.Message);
            }
            return flag;
        }
    }
}

下面才是最關鍵的設置方法,接下來就是改權限的時候了 

一: 在Visual Studio 中--解決方案資源管理器--右鍵項目名稱--屬性,找到“安全性”選項,

二:勾選“啟用ClickOnce安全設置”,

三:這時,在項目下面會多出一個“app.manifest”的文件,選中它,並找到代碼段<requestedExecutionLevel level="asInvoker" uiAccess="false" />,將其改為:<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />,

打開:

將上圖部分修改為:

四:改正后,不要急於重新編譯生成,再次打開“屬性--安全性”界面,

將“啟用ClickOnce安全設置”前面的勾去掉后再編譯運行。 不然程序會報錯無法運行。

 

五:最后,保存修改,重新編譯運行程序。

打開程序時,會提示“用戶賬戶控制”來獲取管理員權限運行,點擊“是”則獲取了管理員權限。

 

到此,整個操作工作完成,運行程序后,下次開機會自動啟動進行時間的更新。應該還有其他方法進行時間的獲取和更新,找到后我會持續更新。☺


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM