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安全设置”前面的勾去掉后再编译运行。 不然程序会报错无法运行。

 

五:最后,保存修改,重新编译运行程序。

打开程序时,会提示“用户账户控制”来获取管理员权限运行,点击“是”则获取了管理员权限。

 

到此,整个操作工作完成,运行程序后,下次开机会自动启动进行时间的更新。应该还有其他方法进行时间的获取和更新,找到后我会持续更新。☺

posted @   桃子宝宝  阅读(1249)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示