Eden 2 月之前
父节点
当前提交
b84784c9dc

+ 6 - 62
TEAMModelOS.Extension/IES.Exam/IES.ExamServer/Controllers/IndexController.cs

@@ -380,66 +380,8 @@ namespace IES.ExamServer.Controllers
         {
         {
             try
             try
             {
             {
-               
-                string pathCerNew = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "certificate.cer");
-                string pathBatNew = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "install_certificate.bat");
-                if (!System.IO.File.Exists(pathCerNew)|| !System.IO.File.Exists(pathBatNew))
-                {
-                    string pathCer = Path.Combine(Directory.GetCurrentDirectory(), "Configs", "cer", "certificate.cer");
-                    System.IO.File.Copy(pathCer, pathCerNew);
-                    string pathBat = Path.Combine(Directory.GetCurrentDirectory(), "Configs", "cer", "install_certificate.bat");
-                    System.IO.File.Copy(pathBat, pathBatNew);
-                    var res = ProcessHelper.ExecuteProcess(pathBatNew);
-                }
-
-                ServerDevice serverDevice = _memoryCache.Get<ServerDevice>(Constant._KeyServerDevice);
-                if (serverDevice != null && serverDevice.networks.IsNotEmpty())
-                {
-                    Network? network = serverDevice.networks.FirstOrDefault();
-                    if (!string.IsNullOrWhiteSpace(ip))
-                    {
-                        network = serverDevice.networks.FindAll(x => ip.Equals(x.ip))?.FirstOrDefault(); 
-                    }
-                   
-                    if (network != null && !string.IsNullOrWhiteSpace(network.ip))
-                    {
-                        network.primary = 1;
-                        _memoryCache.Set<ServerDevice>(Constant._KeyServerDevice,serverDevice);
-                        string pathBatHosts = Path.Combine(Directory.GetCurrentDirectory(), "Configs", "cer", "modify_hosts.bat");
-                        string text = await System.IO.File.ReadAllTextAsync(pathBatHosts);
-                        // 使用正则表达式替换 IP 地址
-                        string pattern = @"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b";
-                        string result = Regex.Replace(text, pattern, network.ip);
-                        string pathBatHostsNew = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot",  "modify_hosts.bat");
-                        await System.IO.File.WriteAllTextAsync(pathBatHostsNew, result);
-                        string pathBatStudent = Path.Combine(Directory.GetCurrentDirectory(), "Configs", "cer", "student_manual.bat");
-                        string textStudent = await System.IO.File.ReadAllTextAsync(pathBatStudent);
-                        // 使用正则表达式替换 IP 地址
-                        string resultStudent = Regex.Replace(textStudent, pattern, network.ip);
-                        string pathBatStudentNew = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "student_manual.bat");
-                        await System.IO.File.WriteAllTextAsync(pathBatStudentNew, resultStudent);
-                        var resHosts = ProcessHelper.ExecuteProcess(pathBatHostsNew);
-                        return Ok(new {
-                            code = 200,
-                            msg = "成功",
-                            serverDevice,
-                            cer = "certificate.cer",
-                            install_certificate = "install_certificate.bat",
-                            modify_hosts= "modify_hosts.bat",
-                            student_manual= "student_manual.bat"
-                        });
-                    }
-                    else
-                    {
-                        code = 400;
-                        msg = "未找到匹配的IP。";
-                    }
-                }
-                else
-                {
-                    code = 400;
-                    msg = "服务端设备未找到,或网卡设备不存在。";
-                }
+                var data = await IndexService. ModifyHosts(ip,_memoryCache,_liteDBFactory,_connectionService);
+                return Ok(new { data.code,data.code_zip,data.code_cer,data.code_hosts,data.msg});
             }
             }
             catch (Exception ex)
             catch (Exception ex)
             {
             {
@@ -449,7 +391,10 @@ namespace IES.ExamServer.Controllers
             }
             }
             return Ok(new { code = 400, msg = msg });
             return Ok(new { code = 400, msg = msg });
         }
         }
-
+        /// <summary>
+        /// 强制重新安装证书
+        /// </summary>
+        /// <returns></returns>
         [HttpGet("install-certificate")]
         [HttpGet("install-certificate")]
         public IActionResult InstallCertificate()
         public IActionResult InstallCertificate()
         {
         {
@@ -462,7 +407,6 @@ namespace IES.ExamServer.Controllers
                 string pathBat = Path.Combine(Directory.GetCurrentDirectory(), "Configs", "cer", "install_certificate.bat");
                 string pathBat = Path.Combine(Directory.GetCurrentDirectory(), "Configs", "cer", "install_certificate.bat");
                 System.IO.File.Copy(pathBat, pathBatNew);
                 System.IO.File.Copy(pathBat, pathBatNew);
                 var res = ProcessHelper.ExecuteProcess(pathBatNew);
                 var res = ProcessHelper.ExecuteProcess(pathBatNew);
-
                 return Ok(new {code= res.code, msg= res.msg });
                 return Ok(new {code= res.code, msg= res.msg });
             }
             }
             catch (Exception ex)
             catch (Exception ex)

+ 1 - 0
TEAMModelOS.Extension/IES.Exam/IES.ExamServer/DI/ServiceInitializer.cs

@@ -131,6 +131,7 @@ namespace IES.ExamServer.DI
             _cache.Set(Constant._KeyServerDevice, serverDevice);
             _cache.Set(Constant._KeyServerDevice, serverDevice);
             _liteDBFactory.GetLiteDatabase().GetCollection<ServerDevice>().Upsert(serverDevice);
             _liteDBFactory.GetLiteDatabase().GetCollection<ServerDevice>().Upsert(serverDevice);
             _connectionService.serverDevice = serverDevice;
             _connectionService.serverDevice = serverDevice;
+            await  IndexService.ModifyHosts(null, _cache, _liteDBFactory, _connectionService);
             _lifetime.ApplicationStarted.Register(() =>
             _lifetime.ApplicationStarted.Register(() =>
             {
             {
                var serverDevice=  _cache.Get<ServerDevice>(Constant._KeyServerDevice);
                var serverDevice=  _cache.Get<ServerDevice>(Constant._KeyServerDevice);

+ 152 - 0
TEAMModelOS.Extension/IES.Exam/IES.ExamServer/Helpers/SystemScriptHelper.cs

@@ -0,0 +1,152 @@
+using System.Runtime.InteropServices;
+using System.Security.Cryptography.X509Certificates;
+using System.Security.Principal;
+
+namespace IES.ExamServer.Helpers
+{
+    public static class SystemScriptHelper
+    {
+        /// <summary>
+        /// 检查是否管理员身份运行
+        /// </summary>
+        /// <returns></returns>
+        public static bool IsAdministrator()
+        {
+            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+            {
+                // 获取当前用户的 Windows 身份
+                WindowsIdentity identity = WindowsIdentity.GetCurrent();
+                // 创建一个 WindowsPrincipal 对象,用于表示当前用户的主体
+                WindowsPrincipal principal = new WindowsPrincipal(identity);
+                // 检查当前用户是否属于管理员组
+                return principal.IsInRole(WindowsBuiltInRole.Administrator);
+            }
+            return false;
+        }
+        /// <summary>
+        /// 根据域名在hosts文件中找到对于的ip地址。
+        /// </summary>
+        /// <param name="domain"></param>
+        /// <returns></returns>
+        public static (string? ip, string msg) FindIpAddressForDomain(string domain)
+        {
+            string? lastMatchingIp = null;
+            try
+            {
+                string filePath = @"C:\Windows\System32\drivers\etc\hosts";
+                string[] lines = File.ReadAllLines(filePath);
+                foreach (string line in lines)
+                {
+                    string trimmedLine = line.Trim();
+                    if (string.IsNullOrEmpty(trimmedLine) || trimmedLine.StartsWith("#"))
+                    {
+                        continue;
+                    }
+                    string[] parts = trimmedLine.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
+                    if (parts.Length >= 2)
+                    {
+                        string ip = parts[0];
+                        for (int i = 1; i < parts.Length; i++)
+                        {
+                            if (parts[i].Equals(domain, StringComparison.OrdinalIgnoreCase))
+                            {
+                                lastMatchingIp = ip;
+                            }
+                        }
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+                return (null, $"读取文件时出错: {ex.Message}");
+            }
+            return (lastMatchingIp, "匹配结果");
+        }
+        /// <summary>
+        /// 检查证书是否安装,切是否过期,true 已经安装,false 未安装,用于检查证书是否需要重新安装,最终返回 true不用安装。
+        /// 代码中使用的是 CurrentUser 存储位置,如果你需要检查计算机级别的证书存储区,可以将 StoreLocation.CurrentUser 替换为 StoreLocation.LocalMachine,但这可能需要管理员权限。
+        /// </summary>
+        /// <param name="certificate"></param>
+        /// <returns></returns>
+        public static bool CheckCertificate(string certificatePath)
+        {
+            bool installed = false, expired=false;
+            X509Certificate2 certificate = new X509Certificate2(certificatePath);
+            // 定义要检查的证书存储区
+            StoreName[] storeNames = { StoreName.Root, StoreName.CertificateAuthority, StoreName.My };
+            foreach (StoreName storeName in storeNames)
+            {
+                if (IsAdministrator())
+                {
+                    using (X509Store store = new X509Store(storeName, StoreLocation.LocalMachine))
+                    {
+                        try
+                        {
+                            // 打开存储区
+                            store.Open(OpenFlags.ReadOnly);
+                            // 查找匹配的证书
+                            X509Certificate2Collection collection = store.Certificates.Find(X509FindType.FindByThumbprint, certificate.Thumbprint, false);
+                            if (collection.Count > 0)
+                            {
+                                installed = true;
+                                var  certificateInstalled = collection.First();
+                                expired  = CheckCertificateExpired(certificateInstalled);
+                                break;
+                            }
+                        }
+                        catch (Exception ex)
+                        {
+                            Console.WriteLine($"访问 {storeName} 存储区时出错: {ex.Message}");
+                        }
+                        finally
+                        {
+                            // 关闭存储区
+                            store.Close();
+                        }
+                    }
+                }
+                else {
+                    using (X509Store store = new X509Store(storeName, StoreLocation.CurrentUser))
+                    {
+                        try
+                        {
+                            // 打开存储区
+                            store.Open(OpenFlags.ReadOnly);
+                            // 查找匹配的证书
+                            X509Certificate2Collection collection = store.Certificates.Find(X509FindType.FindByThumbprint, certificate.Thumbprint, false);
+                            if (collection.Count > 0)
+                            {
+                                installed = true;
+                                var certificateInstalled = collection.First();
+                                expired = CheckCertificateExpired(certificateInstalled);
+                                break;
+                            }
+                        }
+                        catch (Exception ex)
+                        {
+                            Console.WriteLine($"访问 {storeName} 存储区时出错: {ex.Message}");
+                        }
+                        finally
+                        {
+                            // 关闭存储区
+                            store.Close();
+                        }
+                    }
+                }
+               
+            }
+            return installed && !expired;
+        }
+
+        /// <summary>
+        /// 检查证书是否过期,true  过期,false 未过期
+        /// </summary>
+        /// <param name="certificate"></param>
+        /// <returns></returns>
+        public static bool CheckCertificateExpired(X509Certificate2 certificate)
+        {
+            DateTime now = DateTime.Now;
+            return now < certificate.NotBefore || now > certificate.NotAfter;
+        }
+    }
+}

+ 4 - 1
TEAMModelOS.Extension/IES.Exam/IES.ExamServer/Models/ServerDevice.cs

@@ -91,12 +91,15 @@ namespace IES.ExamServer.Models
         /// <summary>
         /// <summary>
         /// 绑定域名
         /// 绑定域名
         /// </summary>
         /// </summary>
-        public string? domain { get; set; }
+        //public string? domain { get; set; }
         public int physical {  get; set; }
         public int physical {  get; set; }
         /// <summary>
         /// <summary>
         /// 当前主站域名
         /// 当前主站域名
         /// </summary>
         /// </summary>
         public int primary { get; set; }
         public int primary { get; set; }
+        /// <summary>
+        /// 脚本压缩文件
+        /// </summary>
         public string? batscriptZip { get; set; }
         public string? batscriptZip { get; set; }
     }
     }
 }
 }

+ 102 - 75
TEAMModelOS.Extension/IES.Exam/IES.ExamServer/Services/IndexService.cs

@@ -11,19 +11,30 @@ using System.Text;
 using IES.ExamServer.DI;
 using IES.ExamServer.DI;
 using IES.ExamServer.Helper;
 using IES.ExamServer.Helper;
 using System;
 using System;
+using System.Security.Principal;
 
 
 namespace IES.ExamServer.Services
 namespace IES.ExamServer.Services
 {
 {
     public static class IndexService
     public static class IndexService
     {
     {
-        public static async Task<(int code, string msg)> ModifyHosts(string ip,IMemoryCache _memoryCache,LiteDBFactory _liteDBFactory)
+
+        /// <summary>
+        /// 修改IP域名映射,以及处理证书是否安装的问题。
+        /// </summary>
+        /// <param name="ip"></param>
+        /// <param name="_memoryCache"></param>
+        /// <param name="_liteDBFactory"></param>
+        /// <param name="connectionService"></param>
+        /// <returns></returns>
+        public static async Task<(int code, int code_cer ,int code_hosts,int code_zip, string msg)> ModifyHosts(string? ip,IMemoryCache _memoryCache,LiteDBFactory _liteDBFactory,CenterServiceConnectionService connectionService)
         {
         {
-            int code = 0;
-            string msg = string.Empty;
+           (string? hostsIp,string hostsMsg) = SystemScriptHelper.FindIpAddressForDomain("exam.habook.local");
+            int code = 0, code_cer = 0,code_hosts=0,code_zip=0 ;
+            StringBuilder sb = new StringBuilder();
             try
             try
             {
             {
                 string batscriptPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "batscript");
                 string batscriptPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "batscript");
-                if (!Directory.Exists(batscriptPath)) 
+                if (!Directory.Exists(batscriptPath))
                 {
                 {
                     Directory.CreateDirectory(batscriptPath);
                     Directory.CreateDirectory(batscriptPath);
                 }
                 }
@@ -35,18 +46,36 @@ namespace IES.ExamServer.Services
                     System.IO.File.Copy(pathCer, pathCerNew);
                     System.IO.File.Copy(pathCer, pathCerNew);
                     string pathBat = Path.Combine(Directory.GetCurrentDirectory(), "Configs", "cer", "install_certificate.bat");
                     string pathBat = Path.Combine(Directory.GetCurrentDirectory(), "Configs", "cer", "install_certificate.bat");
                     System.IO.File.Copy(pathBat, pathBatNew);
                     System.IO.File.Copy(pathBat, pathBatNew);
-                    var res = ProcessHelper.ExecuteProcess(pathBatNew);
+                }
+                var needInstall = SystemScriptHelper.CheckCertificate(pathCerNew);
+                if (!needInstall)
+                {
+                    if (SystemScriptHelper.IsAdministrator())
+                    {
+                        var res = ProcessHelper.ExecuteProcess(pathBatNew);
+                        sb.Append(res.msg);
+                        code_cer = res.code;
+                    }
+                    else
+                    {
+                        code_cer = 401;
+                        sb.Append("请使用管理员身份运行本程序,如果已经安装过脚本请忽略!");
+                    }
+                }
+                else
+                {
+                    code_cer = 200;
                 }
                 }
                 //获取主站配置信息。
                 //获取主站配置信息。
                 ServerDevice serverDevice = _memoryCache.Get<ServerDevice>(Constant._KeyServerDevice);
                 ServerDevice serverDevice = _memoryCache.Get<ServerDevice>(Constant._KeyServerDevice);
                 var primaryNetworks=   _liteDBFactory.GetLiteDatabase().GetCollection<Network>().FindAll().ToList();
                 var primaryNetworks=   _liteDBFactory.GetLiteDatabase().GetCollection<Network>().FindAll().ToList();
                 Network? primaryNetwork = null;
                 Network? primaryNetwork = null;
-                //传入的ip为不为空
+                //传入的ip为不为空,切换
                 if (!string.IsNullOrWhiteSpace(ip) )
                 if (!string.IsNullOrWhiteSpace(ip) )
                 {
                 {
                     if (serverDevice != null && serverDevice.networks.IsNotEmpty()) 
                     if (serverDevice != null && serverDevice.networks.IsNotEmpty()) 
                     {
                     {
-                    
+                        primaryNetwork = serverDevice.networks.FindAll(x => ip.Equals(x.ip))?.FirstOrDefault();
                     }
                     }
                 }
                 }
                 else 
                 else 
@@ -65,14 +94,6 @@ namespace IES.ExamServer.Services
                                     {
                                     {
                                         primaryNetwork = network;
                                         primaryNetwork = network;
                                     }
                                     }
-                                    else
-                                    {
-                                        _liteDBFactory.GetLiteDatabase().GetCollection<Network>().Delete(network.id);
-                                    }
-                                }
-                                else
-                                {
-                                    _liteDBFactory.GetLiteDatabase().GetCollection<Network>().Delete(network.id);
                                 }
                                 }
                             }
                             }
                         }
                         }
@@ -82,79 +103,85 @@ namespace IES.ExamServer.Services
                             primaryNetwork = serverDevice.networks.FirstOrDefault();//第一个是物理网卡
                             primaryNetwork = serverDevice.networks.FirstOrDefault();//第一个是物理网卡
                         }
                         }
                     }
                     }
-                   
                 }
                 }
-
-
-                if (serverDevice != null && serverDevice.networks.IsNotEmpty())
+                if (primaryNetwork != null)
                 {
                 {
-                    Network? network = serverDevice.networks.FirstOrDefault();
-                    if (!string.IsNullOrWhiteSpace(ip))
+                    string pathBatHosts = Path.Combine(Directory.GetCurrentDirectory(), "Configs", "cer", "modify_hosts.bat");
+                    string text = await System.IO.File.ReadAllTextAsync(pathBatHosts);
+                    // 使用正则表达式替换 IP 地址
+                    string pattern = @"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b";
+                    string result = Regex.Replace(text, pattern, primaryNetwork.ip!);
+                    string pathBatHostsNew = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "batscript", "modify_hosts.bat");
+                    await System.IO.File.WriteAllTextAsync(pathBatHostsNew, result);
+                    string pathBatStudent = Path.Combine(Directory.GetCurrentDirectory(), "Configs", "cer", "student_manual.bat");
+                    string textStudent = await System.IO.File.ReadAllTextAsync(pathBatStudent);
+                    // 使用正则表达式替换 IP 地址
+                    string resultStudent = Regex.Replace(textStudent, pattern, primaryNetwork.ip!);
+                    string pathBatStudentNew = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "batscript", "student_manual.bat");
+                    await System.IO.File.WriteAllTextAsync(pathBatStudentNew, resultStudent);
+                    if (string.IsNullOrWhiteSpace(hostsIp) || !hostsIp.Equals(primaryNetwork.ip))
                     {
                     {
-                        network = serverDevice.networks.FindAll(x => ip.Equals(x.ip))?.FirstOrDefault();
+                        if (SystemScriptHelper.IsAdministrator())
+                        {
+                            var resHosts = ProcessHelper.ExecuteProcess(pathBatHostsNew);
+                            sb.Append(resHosts.msg);
+                            code_hosts = resHosts.code;
+                        }
+                        else
+                        {
+                            code_hosts = 401;
+                            sb.Append("请使用管理员身份执行本程序!");
+                        }
+                    }
+                    else
+                    {
+                        code_hosts = 200;
+                        sb.Append("IP域名映射已存在,无需再次映射!");
                     }
                     }
 
 
-                    if (network != null && !string.IsNullOrWhiteSpace(network.ip))
+                    string batscriptZipPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot","student_script.zip");
+
+                    var res = ZipHelper.CreateZip(batscriptPath, batscriptZipPath);
+                    if (res.res)
                     {
                     {
-                       
-                        string pathBatHosts = Path.Combine(Directory.GetCurrentDirectory(), "Configs", "cer", "modify_hosts.bat");
-                        string text = await System.IO.File.ReadAllTextAsync(pathBatHosts);
-                        // 使用正则表达式替换 IP 地址
-                        string pattern = @"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b";
-                        string result = Regex.Replace(text, pattern, network.ip);
-                        string pathBatHostsNew = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "batscript", "modify_hosts.bat");
-                        await System.IO.File.WriteAllTextAsync(pathBatHostsNew, result);
-                        string pathBatStudent = Path.Combine(Directory.GetCurrentDirectory(), "Configs", "cer", "student_manual.bat");
-                        string textStudent = await System.IO.File.ReadAllTextAsync(pathBatStudent);
-                        // 使用正则表达式替换 IP 地址
-                        string resultStudent = Regex.Replace(textStudent, pattern, network.ip);
-                        string pathBatStudentNew = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "batscript", "student_manual.bat");
-                        await System.IO.File.WriteAllTextAsync(pathBatStudentNew, resultStudent);
-                        var resHosts = ProcessHelper.ExecuteProcess(pathBatHostsNew);
-                        string batscriptZipPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "student_script.zip");
-                       
-                        var  res=    ZipHelper.CreateZip(batscriptPath, batscriptZipPath);
-                        if (res.res) 
-                        {
-                            serverDevice.networks.ForEach(x => {
-                                x.primary = 0;
-                                x.batscriptZip = null;
-                            });
-                            network.primary = 1;
-                            network.batscriptZip = batscriptZipPath;
-                            _memoryCache.Set<ServerDevice>(Constant._KeyServerDevice, serverDevice);
-                           // _liteDBFactory.GetLiteDatabase().GetCollection<ServerDevice>().Upsert(serverDevice);
-                        }
-                        //return Ok(new
-                        //{
-                        //    code = 200,
-                        //    msg = "成功",
-                        //    serverDevice,
-                        //    cer = "certificate.cer",
-                        //    install_certificate = "install_certificate.bat",
-                        //    modify_hosts = "modify_hosts.bat",
-                        //    student_manual = "student_manual.bat"
-                        //});
+                        code_zip = 200;
+                        sb.Append(res.msg);
+                        
                     }
                     }
                     else
                     else
                     {
                     {
-                        code = 400;
-                        msg = "未找到匹配的IP。";
+                        code_zip = 400;
+                        sb.Append("脚本文件创建异常!");
                     }
                     }
-                }
-                else
-                {
-                    code = 400;
-                    msg = "服务端设备未找到,或网卡设备不存在。";
+                    serverDevice!.networks.ForEach(x =>
+                    {
+                        x.primary = 0;
+                        x.batscriptZip = null;
+                        if (x.id!.Equals(primaryNetwork.id))
+                        {
+                            x.primary = code_hosts ==200? 1:0;
+                            x.batscriptZip = res.res? "student_script.zip":null;
+                        }
+                    });
+                    //更新设备的主站设备信息
+                    connectionService.serverDevice = serverDevice;
+                    _memoryCache.Set<ServerDevice>(Constant._KeyServerDevice, serverDevice);
+                    _liteDBFactory.GetLiteDatabase().GetCollection<ServerDevice>().Upsert(serverDevice);
+                    //清理后再保存,保证只有一条主站数据。
+                    _liteDBFactory.GetLiteDatabase().GetCollection<Network>().DeleteAll();
+                    _liteDBFactory.GetLiteDatabase().GetCollection<Network>().Upsert(primaryNetwork);
+                    //所有执行成功
+                    code = 200;
+                    sb.Append("证书安装成功,域名IP绑定成功,脚本文件创建成功!");
                 }
                 }
             }
             }
             catch (Exception ex)
             catch (Exception ex)
             {
             {
                 code = 500;
                 code = 500;
                 //_logger.LogError($"域名IP绑定错误。{ex.Message},{ex.StackTrace}");
                 //_logger.LogError($"域名IP绑定错误。{ex.Message},{ex.StackTrace}");
-                msg = $"域名IP绑定错误,{ex.Message}";
+                return (500,code_cer,code_hosts,code_zip, $"域名IP绑定错误,{ex.Message},{ex.StackTrace}");
             }
             }
-            return (code, msg);
+            return (code, code_cer, code_hosts, code_zip, sb.ToString());
         }
         }
 
 
 
 
@@ -460,10 +487,10 @@ namespace IES.ExamServer.Services
             if (device.networks.IsNotEmpty()) 
             if (device.networks.IsNotEmpty()) 
             {
             {
                 var order=  device.networks.OrderByDescending(x => x.physical).ToList();
                 var order=  device.networks.OrderByDescending(x => x.physical).ToList();
-                for (int i=0; i<order.Count();i++) 
-                {
-                    order[i].domain="exam.habook.local";
-                }
+                //for (int i=0; i<order.Count();i++) 
+                //{
+                //    order[i].domain="exam.habook.local";
+                //}
                 device.networks=order;
                 device.networks=order;
                 //优先以物理网卡来生成hash,如果没有则以所有网卡生成hash
                 //优先以物理网卡来生成hash,如果没有则以所有网卡生成hash
                 var physical = order.FindAll(x => x.physical==1);
                 var physical = order.FindAll(x => x.physical==1);

+ 113 - 0
TEAMModelOS/Properties/ServiceDependencies/teammodelos-rc - Web Deploy/profile.arm.json

@@ -0,0 +1,113 @@
+{
+  "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
+  "contentVersion": "1.0.0.0",
+  "metadata": {
+    "_dependencyType": "compute.appService.windows"
+  },
+  "parameters": {
+    "resourceGroupName": {
+      "type": "string",
+      "defaultValue": "TEAMModelChengdu",
+      "metadata": {
+        "description": "Name of the resource group for the resource. It is recommended to put resources under same resource group for better tracking."
+      }
+    },
+    "resourceGroupLocation": {
+      "type": "string",
+      "defaultValue": "",
+      "metadata": {
+        "description": "Location of the resource group. Resource groups could have different location than resources, however by default we use API versions from latest hybrid profile which support all locations for resource types we support."
+      }
+    },
+    "resourceName": {
+      "type": "string",
+      "defaultValue": "rc",
+      "metadata": {
+        "description": "Name of the main resource to be created by this template."
+      }
+    },
+    "resourceLocation": {
+      "type": "string",
+      "defaultValue": "[parameters('resourceGroupLocation')]",
+      "metadata": {
+        "description": "Location of the resource. By default use resource group's location, unless the resource provider is not supported there."
+      }
+    }
+  },
+  "variables": {
+    "appServicePlan_name": "[concat('Plan', uniqueString(concat(parameters('resourceName'), subscription().subscriptionId)))]",
+    "appServicePlan_ResourceId": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', parameters('resourceGroupName'), '/providers/Microsoft.Web/serverFarms/', variables('appServicePlan_name'))]"
+  },
+  "resources": [
+    {
+      "type": "Microsoft.Resources/resourceGroups",
+      "name": "[parameters('resourceGroupName')]",
+      "location": "[parameters('resourceGroupLocation')]",
+      "apiVersion": "2019-10-01"
+    },
+    {
+      "type": "Microsoft.Resources/deployments",
+      "name": "[concat(parameters('resourceGroupName'), 'Deployment', uniqueString(concat(parameters('resourceName'), subscription().subscriptionId)))]",
+      "resourceGroup": "[parameters('resourceGroupName')]",
+      "apiVersion": "2019-10-01",
+      "dependsOn": [
+        "[parameters('resourceGroupName')]"
+      ],
+      "properties": {
+        "mode": "Incremental",
+        "template": {
+          "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
+          "contentVersion": "1.0.0.0",
+          "resources": [
+            {
+              "location": "[parameters('resourceLocation')]",
+              "name": "[parameters('resourceName')]",
+              "type": "Microsoft.Web/sites",
+              "apiVersion": "2015-08-01",
+              "tags": {
+                "[concat('hidden-related:', variables('appServicePlan_ResourceId'))]": "empty"
+              },
+              "dependsOn": [
+                "[variables('appServicePlan_ResourceId')]"
+              ],
+              "kind": "app",
+              "properties": {
+                "name": "[parameters('resourceName')]",
+                "kind": "app",
+                "httpsOnly": true,
+                "reserved": false,
+                "serverFarmId": "[variables('appServicePlan_ResourceId')]",
+                "siteConfig": {
+                  "metadata": [
+                    {
+                      "name": "CURRENT_STACK",
+                      "value": "dotnetcore"
+                    }
+                  ]
+                }
+              },
+              "identity": {
+                "type": "SystemAssigned"
+              }
+            },
+            {
+              "location": "[parameters('resourceLocation')]",
+              "name": "[variables('appServicePlan_name')]",
+              "type": "Microsoft.Web/serverFarms",
+              "apiVersion": "2015-08-01",
+              "sku": {
+                "name": "S1",
+                "tier": "Standard",
+                "family": "S",
+                "size": "S1"
+              },
+              "properties": {
+                "name": "[variables('appServicePlan_name')]"
+              }
+            }
+          ]
+        }
+      }
+    }
+  ]
+}

+ 1 - 2
TEAMModelOS/TEAMModelOS.csproj

@@ -111,11 +111,10 @@
 			<Output TaskParameter="ExitCode" PropertyName="ErrorCode" />
 			<Output TaskParameter="ExitCode" PropertyName="ErrorCode" />
 		</Exec>
 		</Exec>
 	</Target>
 	</Target>
-
+	<!-- 不用每次都安装。-->
 	<Target Name="EnsureNodeModulesInstalled" BeforeTargets="Build" Inputs="package.json" Outputs="packages-lock.json">
 	<Target Name="EnsureNodeModulesInstalled" BeforeTargets="Build" Inputs="package.json" Outputs="packages-lock.json">
 		<!-- Build Target: Restore NPM packages using npm -->
 		<!-- Build Target: Restore NPM packages using npm -->
 		<Message Importance="high" Text="Restoring dependencies using 'npm'. This may take several minutes..." />
 		<Message Importance="high" Text="Restoring dependencies using 'npm'. This may take several minutes..." />
-
 		<Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
 		<Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
 	</Target>
 	</Target>