116 lines
4.8 KiB
C#
116 lines
4.8 KiB
C#
using System;
|
|
using System.Diagnostics;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
using System.Net.WebSockets;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Builder;
|
|
using Microsoft.AspNetCore.Hosting;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Hosting;
|
|
|
|
namespace WebDesktopUpdater {
|
|
public class Startup {
|
|
public Startup(IConfiguration configuration) {
|
|
Configuration = configuration;
|
|
}
|
|
|
|
public IConfiguration Configuration { get; }
|
|
|
|
// This method gets called by the runtime. Use this method to add services to the container.
|
|
public void ConfigureServices(IServiceCollection services) {
|
|
services.AddSingleton(Configuration);
|
|
|
|
services.AddControllers();
|
|
}
|
|
|
|
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
|
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {
|
|
if (env.IsDevelopment()) {
|
|
app.UseDeveloperExceptionPage();
|
|
}
|
|
|
|
//app.UseHttpsRedirection();
|
|
|
|
app.UseRouting();
|
|
|
|
app.UseAuthorization();
|
|
|
|
app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
|
|
|
|
app.UseWebSockets(new WebSocketOptions { KeepAliveInterval = TimeSpan.FromSeconds(10) });
|
|
app.Use(async (context, next) => {
|
|
if (context.Request.Path == "/") {
|
|
if (context.WebSockets.IsWebSocketRequest) {
|
|
WebSocket socket = await context.WebSockets.AcceptWebSocketAsync();
|
|
|
|
byte[] buffer = new byte[1024 * 4];
|
|
WebSocketReceiveResult result = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
|
|
while (!result.CloseStatus.HasValue) {
|
|
string msg = Read(buffer, result);
|
|
|
|
if (msg.Equals("Ping")) {
|
|
await Write(DateTime.UtcNow.ToString(CultureInfo.InvariantCulture), socket, result);
|
|
}
|
|
|
|
if (msg.Equals("Start")) {
|
|
Process updater = Update();
|
|
|
|
var handler = new DataReceivedEventHandler(async (sender, e) => {
|
|
await Write(e.Data, socket, result);
|
|
});
|
|
|
|
updater.OutputDataReceived += handler;
|
|
updater.ErrorDataReceived += handler;
|
|
|
|
updater.Start();
|
|
updater.BeginOutputReadLine();
|
|
updater.BeginErrorReadLine();
|
|
}
|
|
|
|
result = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
|
|
}
|
|
|
|
await socket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
|
|
}
|
|
else {
|
|
byte[] html = Encoding.UTF8.GetBytes(await File.ReadAllTextAsync(Environment.CurrentDirectory + "/updater.html"));
|
|
await context.Response.Body.WriteAsync(html, 0, html.Length);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
private Process Update() {
|
|
FileInfo file = new FileInfo(Configuration.GetValue<string>("UpdaterScript"));
|
|
if (file.DirectoryName == null) throw new FileNotFoundException(file.FullName);
|
|
|
|
Process process = new Process();
|
|
ProcessStartInfo startInfo = new ProcessStartInfo();
|
|
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
|
|
startInfo.FileName = "/bin/bash";
|
|
startInfo.WorkingDirectory = file.DirectoryName;
|
|
startInfo.Arguments = "./" + file.Name;
|
|
startInfo.RedirectStandardError = true;
|
|
startInfo.RedirectStandardOutput = true;
|
|
startInfo.UseShellExecute = false;
|
|
|
|
process.StartInfo = startInfo;
|
|
|
|
return process;
|
|
}
|
|
|
|
private string Read(in byte[] buffer, in WebSocketReceiveResult result) {
|
|
return Encoding.UTF8.GetString(new ArraySegment<byte>(buffer, 0, result.Count));
|
|
}
|
|
|
|
private async Task Write(string message, WebSocket socket, WebSocketReceiveResult result) {
|
|
try {
|
|
await socket.SendAsync(new ArraySegment<byte>(Encoding.UTF8.GetBytes(message)), result.MessageType, result.EndOfMessage, CancellationToken.None);
|
|
} catch (Exception) {}
|
|
}
|
|
}
|
|
} |