Program.cs 11.5 KB
using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
using Hh.Mes.Common;
using Hh.Mes.Common.config;
using Hh.Mes.Common.log;
using Hh.Mes.Common.Redis;
using Hh.Mes.Pojo.System;
using log4net;
using log4net.Config;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using WebMvc.Common;

namespace WebMvc
{
    /// <summary>
    /// 启动类 没有特殊情况请不要随便修改 lsw
    /// 路径 https://www.cnblogs.com/cang12138/p/5845122.html
    /// </summary>
    public class Program
    {
        #region 全局变量

        public static int httpsPort { get; set; }
        public static int httpPort { get; set; }
        public static int reportPort { get; set; }

        public static string cerPath { get; set; }

        public static string cerPwd { get; set; }

        public static readonly string service = "Hh.Mes.Service";
        public static readonly string serviceSuffix = "Service";

        private static string cmdPath { get; set; }

        /// <summary>
        /// 定时器job 定时器命名空间【Quartz.Job】保持一致,不然反射失败
        /// </summary>
        public static readonly string quartzJobNameSpaceTypeName = "Quartz.Job";

        private static IConfiguration config { get; set; }
        public static X509Certificate2 certificate { get; set; }

        #endregion


        /// <summary>
        /// 运用程序key
        /// </summary>
        public static string AppKey { get; set; }
        public static string AppSecret { get; set; }
        public static int PingTimeout { get; set; }
        public static void Main(string[] args)
        {
            ExceptionsHelp.Instance.ExecuteVoidFunc(() =>
            {
                InitLog4Net();

                InitSysValue();

                #region 端口是否占用

                var isHttpPort = ComputerHelp.PortInUse(httpPort);
                if (isHttpPort)
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("httpPort端口已被占用:" + httpPort);
                    Console.ReadLine();
                    return;
                }

                var isHttpsPort = ComputerHelp.PortInUse(httpsPort);
                if (isHttpsPort)
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("httpsPort端口已被占用:" + httpsPort);
                    Console.ReadLine();
                    return;
                }

                #endregion

                #region redis 服务是否开启

                var isRedisServerOk = new RedisBase().IsStartRedisServer();
                if (!isRedisServerOk)
                {
                    Thread.Sleep(2000);
                    Console.ReadLine();
                    return;
                }

                #endregion

                InitIConfiguration();

                #region 本地封装日接口日志

                Logging.GetInstance.InitWriteInterLog();

                #endregion

                //证书 根据实际情况开启
                //if (httpsPort != 0) InitCer();

                //启动java积木报表服务 根据实际情况开启
                //Task.Factory.StartNew(InitJavaJiMuReport);

                CreateWebHostBuilder(args).Build().Run();
            });
        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args)
        {
            Console.ResetColor();
            InitIConfiguration();

            return WebHost.CreateDefaultBuilder(args).UseKestrel(options =>
                {
                    options.AddServerHeader = false;

                    //https://www.cnblogs.com/lxhbky/p/11969478.html
                    //https://www.cnblogs.com/wucy/p/14824585.html
                    //设置Body大小限制256MB
                    options.Limits.MaxRequestBodySize = 268435456;


                    if (certificate != null)
                    {
                        options.Listen(IPAddress.Any, httpsPort,
                            listenOptions => { listenOptions.UseHttps(certificate); });
                    }

                    //http  根据实际情况开启
                    options.Listen(IPAddress.Any, httpPort);

                    Console.WriteLine();
                    Console.WriteLine("WebHostBuilder Init  Started successfully!");
                    Console.WriteLine();
                })
                .UseConfiguration(config)
                .UseContentRoot(Directory.GetCurrentDirectory())
                .UseStartup<Startup>();
        }

        private static void InitIConfiguration()
        {
            config = new ConfigurationBuilder()
                .SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
                .AddEnvironmentVariables()
                .AddJsonFile("certificate.json", optional: true, reloadOnChange: true)
                .AddJsonFile($"certificate.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json",
                    optional: true, reloadOnChange: true)
                .Build();
        }

        #region 证书

        public static void InitCer()
        {
            ConfigRead.GetInstance.GetAppsetConnection().HttpOrHttps = "https";
            var certificateSettings = config.GetSection("certificateSettings");
            var certificateFileName = certificateSettings.GetValue<string>("filename");
            var certificatePassword = certificateSettings.GetValue<string>("password");
            var filePath = Path.Combine(AppContext.BaseDirectory, certificateFileName);
            if (!File.Exists(filePath))
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("证书文件路径不存在,请确认发布属性是【始终复制】:" + filePath);
                Log4NetHelper.Instance.Info("Certificate path:" + filePath);
                Console.ReadLine();
            }

            certificate = new X509Certificate2(certificateFileName, certificatePassword);
            cerPwd = certificatePassword;

            //内存缓存设置 路径和密码 定时器启动使用
            ConfigRead.GetInstance.GetAppsetConnection().CerPwd = cerPwd;
            ConfigRead.GetInstance.GetAppsetConnection().CerPath = cerPath;
            Console.WriteLine("InitCer Init  Started successfully!");
        }

        #endregion

        #region Log4Net
        private static void InitLog4Net()
        {
            Log4NetHelper.Instance.Repository = LogManager.CreateRepository("NETCoreRepository");
            var log4Config = Path.Combine(Path.GetDirectoryName(typeof(Program).Assembly.Location), "Config",
                "log4net.config");
            if (!File.Exists(log4Config))
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("log4net.config文件路径不存在,请确认发布属性是【始终复制】:" + log4Config);
                Log4NetHelper.Instance.Info("Certificate path:" + log4Config);
                Console.ReadLine();
            }
            XmlConfigurator.Configure(Log4NetHelper.Instance.Repository, new FileInfo(log4Config));
            Console.WriteLine("InitLog4Net Init  Started successfully!");
        }
        #endregion

        #region 获取配置信息
        private static void InitSysValue()
        {
            Console.Title = "海能发WebServer 网关服务"; 
            httpPort = ConfigRead.GetInstance.GetAppsetConnection().HttpPort;
            httpsPort = ConfigRead.GetInstance.GetAppsetConnection().HttpsPort;
            reportPort = ConfigRead.GetInstance.GetAppsetConnection().ReportPort;
            cmdPath = @"C:\Windows\System32\cmd.exe";
            cerPath = Path.Combine(Path.GetDirectoryName(typeof(Program).Assembly.Location), "huaheng.pfx");
            if (!File.Exists(cerPath))
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("cerPath文件路径不存在,请确认发布属性是【始终复制】:" + cerPath);
                Log4NetHelper.Instance.Info("Certificate path:" + cerPath);
                Console.ReadLine();
            }
            SystemVariable.StartTime = DateTime.Now;
            ConfigRead.GetInstance.GetAppsetConnection().HttpOrHttps = "http";
            Console.WriteLine("InitSysValue Init  Started successfully!");
        }
        #endregion

        #region InitJavaJiMuReport
        private static void InitJavaJiMuReport()
        {
            Console.WriteLine();
            var isReportPort = ComputerHelp.PortInUse(reportPort);
            if (isReportPort)
            {
                Console.WriteLine($"ReportPort端口{reportPort}已占用,或者服务报表已经启动成功!Url【http://localhost:{reportPort}/jmreport/list】");
                Console.WriteLine();
                Console.ReadLine();
                return;
            }
            var reportPath = Path.Combine(Path.GetDirectoryName(typeof(Program).Assembly.Location), "report");
            if (Directory.Exists(reportPath))
            {
                Console.WriteLine($"Init JavaJiMuReport Initing......Url【http://localhost:{reportPort}/jmreport/list】No exception is success!");
                var cmd = $"cd {reportPath}&javaServiceStart.bat";
                var output = "";
                RunCmd(cmd, out output);
                Console.WriteLine(output);
            }
            else
            {
                Console.WriteLine("javaServiceStart.bat path is not existence!");
                Console.ReadLine();
            }
        }

        /// <summary>
        /// 执行cmd命令 https://www.cnblogs.com/njl041x/p/3881550.html
        /// 多命令请使用批处理命令连接符:
        /// <![CDATA[
        /// &:同时执行两个命令
        /// |:将上一个命令的输出,作为下一个命令的输入
        /// &&:当&&前的命令成功时,才执行&&后的命令
        /// ||:当||前的命令失败时,才执行||后的命令]]>
        /// 其他请百度
        /// </summary>
        /// <param name="cmd"></param>
        /// <param name="output"></param>
        private static void RunCmd(string cmd, out string output)
        {
            cmd = cmd.Trim().TrimEnd('&') + "&exit";//说明:不管命令是否成功均执行exit命令,否则当调用ReadToEnd()方法时,会处于假死状态
            using (var p = new Process())
            {
                p.StartInfo.FileName = cmdPath;
                p.StartInfo.UseShellExecute = false;        //是否使用操作系统shell启动
                p.StartInfo.RedirectStandardInput = true;   //接受来自调用程序的输入信息
                p.StartInfo.RedirectStandardOutput = true;  //由调用程序获取输出信息
                p.StartInfo.RedirectStandardError = true;   //重定向标准错误输出
                p.StartInfo.CreateNoWindow = true;          //不显示程序窗口
                p.Start();//启动程序

                //向cmd窗口写入命令
                p.StandardInput.WriteLine(cmd);
                p.StandardInput.AutoFlush = true;
                //获取cmd窗口的输出信息
                output = p.StandardOutput.ReadToEnd();
                p.WaitForExit();//等待程序执行完退出进程
                p.Close();
            }
        }
        #endregion

     
    }
}