master
wanggang 4 years ago
parent c2517d6bd8
commit 6a84fa65de

@ -0,0 +1,48 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System.IO;
namespace SiteLibrary.Controllers
{
public class AdminController : Controller
{
private readonly IWebHostEnvironment _env;
private readonly ILogger<AdminController> _logger;
private readonly IHostApplicationLifetime _appLifetime;
public AdminController(IWebHostEnvironment env, ILogger<AdminController> logger, IHostApplicationLifetime appLifetime)
{
this._env = env;
this._logger = logger;
this._appLifetime = appLifetime;
}
public IActionResult Index()
{
return View();
}
public IActionResult UpdateDB()
{
using var db = new MyDbContext(new DbContextOptionsBuilder<MyDbContext>().UseSqlite($"Data Source={Path.Combine(this._env.WebRootPath, "data.db")}").Options);
db.Seed(this._env.WebRootPath, false, o => this._logger.LogInformation(o), o => this._logger.LogError(o));
this._env.WebRootPath.UpdateList(o => this._logger.LogInformation(o));
return RedirectToAction("Index");
}
public IActionResult UpdateList()
{
this._env.WebRootPath.UpdateList(o => this._logger.LogInformation(o));
return RedirectToAction("Index");
}
public IActionResult Restart()
{
this._appLifetime.StopApplication();
return RedirectToAction("Index");
}
}
}

@ -35,6 +35,7 @@ namespace SiteLibrary
stream.Dispose();
return BitConverter.ToString(hash).Replace("-", "").ToLower();
}
public static string ExtToLower(this string file)
{
if (!string.IsNullOrEmpty(file))

@ -0,0 +1,30 @@
@{
Layout = null;
}
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Home</title>
<style>
a {
display: block;
background: #eee;
padding: 2vh;
text-decoration: none;
color: #000;
font-size: 2vh;
}
</style>
</head>
<body>
<div id="app">
<a href="gxytj/index.html">高校轮播一体机</a>
<a href="syytj/index.html">生涯体验一体机</a>
<a href="@Url.Action("UpdateDB")">更新数据库</a>
<a href="@Url.Action("UpdateList")">更新清单</a>
<a href="@Url.Action("Restart")">重启</a>
</div>
</body>
</html>

@ -1,61 +1,13 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System;
using System.IO;
using System.Reflection;
using Microsoft.AspNetCore.Mvc;
namespace TestServer.Controllers
{
public class HomeController : Controller
{
private readonly IWebHostEnvironment _env;
private readonly ILogger<HomeController> _logger;
private readonly DbContext _dbContext;
public HomeController(IWebHostEnvironment env, ILogger<HomeController> logger,DbContext dbContext)
{
this._env = env;
this._logger = logger;
this._dbContext = dbContext;
}
public IActionResult Index()
{
return View();
}
public IActionResult UpdateDB()
{
var builder = new DbContextOptionsBuilder();
builder.UseSqlite($"Data Source={Path.Combine(this._env.WebRootPath, "data.db")}");
this._dbContext.GetType().InvokeMember("Seed",
BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod,
null,
null,
new object[]{
this._dbContext, this._env.WebRootPath, false, (Action<string>)(o => this._logger.LogInformation(o)), (Action<string>)(o => this._logger.LogError(o))
});
//context.Seed(this._env.WebRootPath, false, o => this._logger.LogInformation(o), o => this._logger.LogError(o));
this._env.WebRootPath.GetType().InvokeMember("UpdateList",
BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod,
null,
null,
new object[] { (Action<string>)(o => this._logger.LogInformation(o))});
return RedirectToAction("Index");
}
public IActionResult UpdateList()
{
//this._env.WebRootPath.UpdateList(o => this._logger.LogInformation(o));
this._env.WebRootPath.GetType().InvokeMember("UpdateList",
BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod,
null,
null,
new object[] { (Action<string>)(o => this._logger.LogInformation(o)) });
return RedirectToAction("Index");
}
}
}

@ -0,0 +1,18 @@
using System;
using System.IO;
using System.Security.Cryptography;
namespace TestServer
{
public static class ObjectExtensions
{
public static string Md5(this string file)
{
using var md5 = MD5.Create();
using var stream = File.OpenRead(file);
var hash = md5.ComputeHash(stream);
stream.Dispose();
return BitConverter.ToString(hash).Replace("-", "").ToLower();
}
}
}

@ -6,35 +6,45 @@ using Serilog.Core;
using Serilog.Events;
using System;
using System.IO;
using System.Threading;
namespace TestServer
{
public class Program
{
private static CancellationTokenSource cts = new CancellationTokenSource();
public static void Main(string[] args)
{
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
.MinimumLevel.Debug()
.WriteTo.File(Path.Combine(AppContext.BaseDirectory, "logs", "app.log.txt"), shared: true, rollOnFileSizeLimit: true, fileSizeLimitBytes: 1024 * 1024 * 1024, rollingInterval: RollingInterval.Day, retainedFileCountLimit: 7, levelSwitch: new LoggingLevelSwitch(LogEventLevel.Information))
.WriteTo.File(Path.Combine(AppContext.BaseDirectory, "logs", "app.err.txt"), shared: true, rollOnFileSizeLimit: true, fileSizeLimitBytes: 1024 * 1024 * 1024, rollingInterval: RollingInterval.Day, retainedFileCountLimit: 7, levelSwitch: new LoggingLevelSwitch(LogEventLevel.Error))
.WriteTo.File(Path.Combine(Directory.GetCurrentDirectory(), "logs", "app.log.txt"), shared: true, rollOnFileSizeLimit: true, fileSizeLimitBytes: 1024 * 1024 * 1024, rollingInterval: RollingInterval.Day, retainedFileCountLimit: 7, levelSwitch: new LoggingLevelSwitch(LogEventLevel.Information))
.WriteTo.File(Path.Combine(Directory.GetCurrentDirectory(), "logs", "app.err.txt"), shared: true, rollOnFileSizeLimit: true, fileSizeLimitBytes: 1024 * 1024 * 1024, rollingInterval: RollingInterval.Day, retainedFileCountLimit: 7, levelSwitch: new LoggingLevelSwitch(LogEventLevel.Error))
.CreateLogger();
try
{
Log.Information("server start");
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false)
.Build();
webBuilder.UseUrls(config.GetValue("server.urls", "http://*:9505"));
webBuilder.UseStartup<Startup>();
})
.Build()
.Run();
Log.Information("server exit");
while(!cts.IsCancellationRequested)
{
Log.Information("server start");
Host.CreateDefaultBuilder(args)
.UseSerilog()
.ConfigureWebHostDefaults(webBuilder =>
{
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false)
.Build();
webBuilder.UseUrls(config.GetValue("server.urls", "http://*:9505"));
webBuilder.CaptureStartupErrors(true);
webBuilder.UseSetting(WebHostDefaults.DetailedErrorsKey, "true");
webBuilder.UseStartup<Startup>();
})
.Build()
.Run();
Log.Information("server exit");
}
}
catch (Exception ex)
{

@ -13,6 +13,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Loader;
using System.Text.Encodings.Web;
using System.Text.Unicode;
@ -25,14 +26,39 @@ namespace TestServer
public IWebHostEnvironment Env { get; }
public IConfiguration Configuration { get; }
private readonly string _origins = "AllowAllHeaders";
private List<Type> _myMiddlewares = new List<Type>();
private List<Type> _startups = new List<Type>();
private string _url;
private Dictionary<string, Assembly> assemblyList = new Dictionary<string, Assembly>();
public Startup(IWebHostEnvironment env, IConfiguration configuration)
{
this.Env = env;
this.Configuration = configuration;
this.Init();
}
private void Init()
{
var pluginsPath = Path.Combine(this.Env.WebRootPath, "plugin");
var pluginsPathCopy = Path.Combine(this.Env.WebRootPath, "plugin", "copy");
Directory.CreateDirectory(pluginsPath);
Directory.CreateDirectory(pluginsPathCopy);
var files = Directory.GetFiles(pluginsPath);
foreach (var file in files)
{
var fileName = Path.GetFileName(file);
var copyFile = Path.Combine(pluginsPathCopy, fileName);
if (!File.Exists(copyFile) || file.Md5() != copyFile.Md5())
{
File.Copy(file, copyFile, true);
}
}
var assemblyFiles = Directory.GetFiles(pluginsPathCopy, "*.dll", SearchOption.AllDirectories);
foreach (var file in assemblyFiles)
{
using var fs = new FileStream(file, FileMode.Open);
var assembly = new AssemblyLoadContext(file, true).LoadFromStream(fs);
this.assemblyList.Add(file,assembly);
}
}
public void ConfigureServices(IServiceCollection services)
@ -50,16 +76,25 @@ namespace TestServer
services.AddSingleton(MyActionDescriptorChangeProvider.Instance);
services.AddSingleton<IActionDescriptorChangeProvider>(MyActionDescriptorChangeProvider.Instance);
services.AddHttpClient();
services.AddSignalR(o => o.EnableDetailedErrors = true).AddJsonProtocol();
services.AddControllersWithViews()
.AddNewtonsoftJson(o =>
{
o.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
})
.ConfigureApplicationPartManager(ConfigureApplicationParts);
foreach (var item in _startups)
foreach (var assembly in this.assemblyList)
{
(item.Assembly.CreateInstance(item.FullName) as IStartup).ConfigureServices(services);
try
{
assembly.Value.GetTypes()
.Where(o => typeof(IStartup).IsAssignableFrom(o))
.ToList()
.ForEach(o => (assembly.Value.CreateInstance(o.FullName) as IStartup).ConfigureServices(services));
}
catch (Exception ex)
{
Log.Error(ex.ToString());
}
}
}
@ -85,13 +120,23 @@ namespace TestServer
app.UseDeveloperExceptionPage();
app.UseCors(_origins);
foreach (var item in _startups)
{
(item.Assembly.CreateInstance(item.FullName) as IStartup).Configure(app);
}
foreach (var item in this._myMiddlewares)
foreach (var assembly in this.assemblyList)
{
app.UseMiddleware(item);
try
{
assembly.Value.GetTypes()
.Where(o => typeof(IStartup).IsAssignableFrom(o))
.ToList()
.ForEach(o => (assembly.Value.CreateInstance(o.FullName) as IStartup).Configure(app));
assembly.Value.GetTypes()
.Where(o => o.Name.EndsWith("Middleware"))
.ToList()
.ForEach(o => app.UseMiddleware(o));
}
catch (Exception ex)
{
Log.Error(ex.ToString());
}
}
app.UseStaticFiles(new StaticFileOptions
{
@ -105,12 +150,6 @@ namespace TestServer
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
//endpoints.MapHub<PageHub>("/hub", o =>
//{
// o.ApplicationMaxBufferSize = long.MaxValue;
// o.TransportMaxBufferSize = long.MaxValue;
//});
endpoints.MapControllerRoute(
name: "areas",
pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
@ -124,27 +163,17 @@ namespace TestServer
private void ConfigureApplicationParts(ApplicationPartManager apm)
{
Log.Logger.Information("Startup>ConfigureApplicationParts");
var pluginsPath = Path.Combine(this.Env.WebRootPath, "plugin", "copy");
if (!Directory.Exists(pluginsPath))
{
Directory.CreateDirectory(pluginsPath);
}
var assemblyFiles = Directory.GetFiles(pluginsPath, "*.dll", SearchOption.AllDirectories);
foreach (var assemblyFile in assemblyFiles)
foreach (var assembly in assemblyList)
{
try
{
using var fs = new FileStream(assemblyFile, FileMode.Open);
var assembly = new AssemblyLoadContext(assemblyFile, true).LoadFromStream(fs);
if (assemblyFile.EndsWith(".Views.dll"))
if (assembly.Key.EndsWith(".Views.dll"))
{
apm.ApplicationParts.Add(new MyCompiledRazorAssemblyPart(assembly));
apm.ApplicationParts.Add(new MyCompiledRazorAssemblyPart(assembly.Value));
}
else
{
apm.ApplicationParts.Add(new MyAssemblyPart(assembly));
this._myMiddlewares.AddRange(assembly.GetTypes().Where(o => o.Name.EndsWith("Middleware")));
this._startups.AddRange(assembly.GetTypes().Where(o => typeof(IStartup).IsAssignableFrom(o)));
apm.ApplicationParts.Add(new MyAssemblyPart(assembly.Value));
}
}
catch (Exception ex)

@ -22,8 +22,6 @@
<div id="app">
<a href="gxytj/index.html">高校轮播一体机</a>
<a href="syytj/index.html">生涯体验一体机</a>
<a href="@Url.Action("UpdateDB")">更新数据库</a>
<a href="@Url.Action("UpdateList")">更新清单</a>
</div>
</body>
</html>
Loading…
Cancel
Save