using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace ChuPiao.Common.Utils
{
    public class ComputerExe
    {
        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        internal struct TokPriv1Luid
        {
            public int Count;
            public long Luid;
            public int Attr;
        }

        [DllImport("kernel32.dll", ExactSpelling = true)]
        internal static extern IntPtr GetCurrentProcess();

        [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
        internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok);

        [DllImport("advapi32.dll", SetLastError = true)]
        internal static extern bool LookupPrivilegeValue(string host, string name, ref long pluid);

        [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
        internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall,
        ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen);

        [DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
        internal static extern bool ExitWindowsEx(int flg, int rea);

        // 以下定义了在调用WinAPI时需要的常数。这些常数通常可以从Platform SDK的包含文件（头文件）中找到
        //http://msdn.microsoft.com/en-us/library/aa392758%28VS.85%29.aspx
        internal const int SE_PRIVILEGE_ENABLED = 0x00000002;
        internal const int TOKEN_QUERY = 0x00000008;
        internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
        internal const string SE_SHUTDOWN_NAME = "SeShutdownPrivilege";
        internal const int EWX_LOGOFF = 0x00000000;
        internal const int EWX_SHUTDOWN = 0x00000001;
        internal const int EWX_REBOOT = 0x00000002;
        internal const int EWX_FORCE = 0x00000004;
        internal const int EWX_POWEROFF = 0x00000008;
        internal const int EWX_FORCEIFHUNG = 0x00000010;
        internal const int ERROR_SUCCESS = 0x00000000;
        internal const string SE_SYSTEMTIME_NAME = "SeSystemtimePrivilege";

        // 通过调用WinAPI实现关机，主要代码再最后一行ExitWindowsEx，这调用了同名的WinAPI，正好是关机用的。

        private static void DoExitWin(int flg)
        {
            bool ok;
            TokPriv1Luid tp;
            IntPtr hproc = GetCurrentProcess();
            IntPtr htok = IntPtr.Zero;
            ok = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok);
            tp.Count = 1;
            tp.Luid = 0;
            tp.Attr = SE_PRIVILEGE_ENABLED;
            ok = LookupPrivilegeValue(null, SE_SHUTDOWN_NAME, ref tp.Luid);
            ok = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
            ok = ExitWindowsEx(flg, 0);
        }

        /// <summary>
        /// 强制关闭电脑
        /// </summary>
        public static void ShutDown()
        {
            DoExitWin(EWX_FORCE | EWX_SHUTDOWN);
        }

        /// <summary>
        /// 重启电脑
        /// </summary>
        public static void ReBoot()
        {
            DoExitWin(EWX_REBOOT);
        }


        #region SetLocalTime
        [DllImport("Kernel32.dll")]
        private static extern bool SetLocalTime(ref SystemTime lpSystemTime);

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern long GetLastError();

        [StructLayout(LayoutKind.Sequential)]
        public struct SystemTime
        {
            public short wYear;
            public short wMonth;
            public short wDayOfWeek;
            public short wDay;
            public short wHour;
            public short wMinute;
            public short wSecond;
            public short wMilliseconds;
        }

       
        public static string SetSystemTime(DateTime date)
        {
            //TokPriv1Luid tp;
            //IntPtr hproc = GetCurrentProcess();
            //IntPtr htok = IntPtr.Zero;
            //OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok);
            //tp.Count = 1;
            //tp.Luid = 0;
            //tp.Attr = SE_PRIVILEGE_ENABLED;
            //LookupPrivilegeValue(null, SE_SYSTEMTIME_NAME, ref tp.Luid);
            //AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
            
            //if (GetLastError() != ERROR_SUCCESS)
            //{
            //   return "更新本地时间失败：提升权限失败！";
            //}

            SystemTime st = new SystemTime();
            st.wYear = (short)date.Year;
            st.wMonth = (short)date.Month;
            st.wDayOfWeek = (short)date.DayOfWeek;
            st.wDay = (short)date.Day;
            st.wHour = (short)date.Hour;
            st.wMinute = (short)date.Minute;
            st.wSecond = (short)date.Second;
            st.wMilliseconds = (short)date.Millisecond;
            bool isok=SetLocalTime(ref st);
            if (isok)
            {
                return "更新本地时间成功：" + date.ToString("yyyy-MM-dd HH:mm:ss.fff");
            }
            else if (GetLastError().Equals(1314))
            {
                return "更新本地时间失败：当前用户没有更新时间的权限。";
            }
            else
            {
                return "更新本地时间失败：" + GetLastError().ToString();
            }
        }
        #endregion


        //调用可执行文件的方法
        public static void Run(string filepath,string domain,string username,string password)
        {
            string strCmd = "";

            //注意：需要引入System.Diagnostics;
            Process prc = new Process();

            try
            {
                //指定调用的可执行文件
                strCmd += filepath;

                //如果可执行文件需要接收参数就加下下面这句，不同参数之间用空格隔开
                //strCmd += 参数1 + " " + 参数2 + " " + 参数n;

                //调用cmd.exe在命令提示符下执行可执行文件
                prc.StartInfo.FileName = "cmd.exe";
                prc.StartInfo.Arguments = " /c " + strCmd;
                prc.StartInfo.UseShellExecute = false;
                //prc.StartInfo.Domain = domain;
                //prc.StartInfo.UserName = username;

                //System.Security.SecureString ss = new System.Security.SecureString();
                //foreach(char cc in password.ToCharArray())
                //{
                //    ss.AppendChar(cc);
                //}
                //prc.StartInfo.Password = ss;

                prc.StartInfo.RedirectStandardError = true;
                prc.StartInfo.RedirectStandardOutput = true;
                prc.StartInfo.RedirectStandardInput = true;
                prc.StartInfo.CreateNoWindow = false;

                bool temp = prc.Start();
                Logger.Log.Debug(temp.ToString());

                //1.
                //ProcessStartInfo processinfo = new ProcessStartInfo();
                //processinfo.FileName = @"F:\Soft\出票点新系统\管理Office\ChuPiao.Office.Desktop.exe";
                ////processinfo.Domain = "";
                ////processinfo.UserName = "administrator";
                ////string password = "gtdmanager123";

                ////System.Security.SecureString ss = new System.Security.SecureString();
                ////foreach (char cc in password.ToCharArray())
                ////{
                ////    ss.AppendChar(cc);
                ////}
                ////processinfo.Password = ss;

                //processinfo.UseShellExecute = false;
                //processinfo.RedirectStandardInput = true;
                //processinfo.RedirectStandardOutput = true;
                //processinfo.RedirectStandardError = true;
                //processinfo.CreateNoWindow = true;
                //processinfo.WindowStyle = ProcessWindowStyle.Normal;
                //processinfo.Arguments = "";

                //Process.Start(processinfo);

                //2.
                //Process pro = new Process();
                //pro.StartInfo.FileName = @"F:\Soft\出票点新系统\管理Office\ChuPiao.Office.Desktop.exe";
                //pro.StartInfo.UseShellExecute = false;
                //pro.StartInfo.RedirectStandardInput = true;
                //pro.StartInfo.RedirectStandardOutput = true;
                //pro.StartInfo.RedirectStandardError = true;
                //pro.StartInfo.CreateNoWindow = true;
                //pro.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
                //pro.StartInfo.Arguments = "";

                //pro.StartInfo.Domain = "";
                //pro.StartInfo.UserName = "Administrator";
                //string password = "gtdmanager123";

                //System.Security.SecureString ss = new System.Security.SecureString();
                //foreach (char cc in password.ToCharArray())
                //{
                //    ss.AppendChar(cc);
                //}
                //pro.StartInfo.Password = ss;
                //pro.StartInfo.Verb = "runas";
                //pro.Start();

            }
            catch (Exception exU)
            {
                if (!prc.HasExited)
                {
                    prc.Close();
                }
                Logger.Log.Debug(exU.Message.ToString());
                throw new Exception(exU.Message.ToString());
            }
        }


    }
}
