EI-Image-Viewer-Api/PublishSite/PublishForm.cs

929 lines
30 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Security;
using System.Diagnostics;
using System.Net;
using Renci.SshNet;
using Serilog;
using Newtonsoft.Json.Linq;
using System.ServiceProcess;
using Renci.SshNet.Messages;
using System.Management;
using System.IO;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.Window;
using System.Management.Automation.Host;
using SharpCompress.Common;
using System.IO.Compression;
namespace PublishSite
{
public partial class PublishForm : Form
{
public PublishForm()
{
InitializeComponent();
Serilog.Log.Logger = new LoggerConfiguration()
.WriteTo.File("logs\\log.txt", rollingInterval: RollingInterval.Day)
.CreateLogger();
}
public string EnvName = "";
public JObject jObjectCofig;
public string Host = "";
public string UserName = "";
public string Password = "";
private void WinformLog(string message, Color? color = null)
{
if (InvokeRequired)
{
Invoke(new Action(() => WinformLog(message, color)));
return;
}
logTBox.SelectionColor = color == null ? Color.Green : (Color)color;
logTBox.AppendText($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}: {message}" + Environment.NewLine);
Serilog.Log.Information(message);
}
#region 切换环境 配置回写
private void rb_Env_CheckedChanged(object sender, EventArgs e)
{
//本地
if (rb_local.Checked)
{
EnvName = "本地";
WinformLog($"当前操作环境切换为: 本地", Color.DarkRed);
var configJson = File.ReadAllText("appsettings.local.json");
jObjectCofig = JObject.Parse(configJson);
}
//测试
if (rb_test.Checked)
{
EnvName = "测试";
WinformLog($"当前操作环境切换为: 测试", Color.DarkRed);
var configJson = File.ReadAllText("appsettings.Development.json");
jObjectCofig = JObject.Parse(configJson);
}
//验证
if (rb_Verify.Checked)
{
EnvName = "验证";
WinformLog($"当前操作环境切换为: 验证", Color.DarkRed);
var configJson = File.ReadAllText("appsettings.Verify.json");
jObjectCofig = JObject.Parse(configJson);
}
//生产
if (rb_production.Checked)
{
EnvName = "生产";
WinformLog($"当前操作环境切换为: 生产", Color.DarkRed);
var configJson = File.ReadAllText("appsettings.Production.json");
jObjectCofig = JObject.Parse(configJson);
}
#region 界面控件赋值
Host = rb_local.Checked ? "" : jObjectCofig["Credential"]["Host"].ToString();
UserName = rb_local.Checked ? "" : jObjectCofig["Credential"]["UserName"].ToString();
Password = rb_local.Checked ? "" : jObjectCofig["Credential"]["Password"].ToString();
serviceNameTBox.Text = jObjectCofig["DefaultService"]["ServiceName"].ToString();
serviceDisplayNameTBox.Text = jObjectCofig["DefaultService"]["ServiceDisplayName"].ToString();
servicePortTBox.Text = jObjectCofig["DefaultService"]["ServicePort"].ToString();
exePathTbox.Text = jObjectCofig["DefaultService"]["BinPath"].ToString();
en_TBox.Text = jObjectCofig["DefaultService"]["Env"].ToString();
startOrStopServiceTbox.Text = jObjectCofig["DefaultService"]["ServiceName"].ToString();
bakDbName.Text = jObjectCofig["BackUp"]["DataBaseName"].ToString();
backPathTBox.Text = jObjectCofig["BackUp"]["BackPath"].ToString();
backExePath.Text = jObjectCofig["DefaultService"]["BinPath"].ToString();
var credentialNode = jObjectCofig["Credential"];
var defaultServiceNode = jObjectCofig["DefaultService"];
var BackUpNode = jObjectCofig["BackUp"];
#endregion
}
private void serviceConfigSaveBtn_Click(object sender, EventArgs e)
{
serviceConfigSaveBtn.Enabled = false;
var serviceName = serviceNameTBox.Text;
DialogResult dr = MessageBox.Show($"{EnvName}环境服务配置回写 ", "保存提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
if (dr == DialogResult.OK)
{
var path = string.Empty;
if (rb_local.Checked)
{
path = "appsettings.local.json";
}
if (rb_test.Checked)
{
path = "appsettings.Development.json";
}
if (rb_Verify.Checked)
{
path = "appsettings.Verify.json";
}
if (rb_production.Checked)
{
path = "appsettings.Production.json";
}
var configJson = File.ReadAllText(path);
jObjectCofig = JObject.Parse(configJson);
jObjectCofig["DefaultService"]["ServiceName"] = serviceNameTBox.Text.Trim();
jObjectCofig["DefaultService"]["ServiceDisplayName"] = serviceDisplayNameTBox.Text.Trim();
jObjectCofig["DefaultService"]["ServicePort"] = servicePortTBox.Text.Trim();
jObjectCofig["DefaultService"]["BinPath"] = exePathTbox.Text.Trim();
jObjectCofig["DefaultService"]["Env"] = en_TBox.Text.Trim();
File.WriteAllText(path, jObjectCofig.ToString());
WinformLog("服务配置回写成功!");
}
serviceConfigSaveBtn.Enabled = true;
}
private void bakConfigSaveBtn_Click(object sender, EventArgs e)
{
bakConfigSaveBtn.Enabled = false;
var serviceName = serviceNameTBox.Text;
DialogResult dr = MessageBox.Show($"{EnvName}环境备份配置回写 ", "保存提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
if (dr == DialogResult.OK)
{
var path = string.Empty;
if (rb_local.Checked)
{
path = "appsettings.local.json";
}
if (rb_test.Checked)
{
path = "appsettings.Development.json";
}
if (rb_Verify.Checked)
{
path = "appsettings.Verify.json";
}
if (rb_production.Checked)
{
path = "appsettings.Production.json";
}
var configJson = File.ReadAllText(path);
jObjectCofig = JObject.Parse(configJson);
jObjectCofig["BackUp"]["DataBaseName"] = bakDbName.Text.Trim();
jObjectCofig["BackUp"]["BackPath"] = backPathTBox.Text.Trim();
File.WriteAllText(path, jObjectCofig.ToString());
WinformLog("备份配置回写成功!");
bakConfigSaveBtn.Enabled = true;
}
}
#endregion
#region 备份
private async void startBakBtn_Click(object sender, EventArgs e)
{
await Task.Run(() =>
{
if (rb_local.Checked)
{
WinformLog("本地环境不支持备份操作,懒得开发");
return;
}
else
{
using (var client = new SshClient(Host, UserName, Password))
{
// 连接到远程服务器
client.Connect();
try
{
var dbName = bakDbName.Text.Trim();
var backRootPath = backPathTBox.Text.Trim();
var serviceName = jObjectCofig["DefaultService"]["ServiceName"].ToString().Trim();
var programPath = backExePath.Text.Trim();
var programFolder = Path.GetDirectoryName(programPath);
var dbUser = jObjectCofig["BackUp"]["DBUser"].ToString().Trim();
var dbPwd = jObjectCofig["BackUp"]["DBPwd"].ToString().Trim();
var backupFolderPath = Path.Combine(backRootPath, DateTime.Now.ToString("yyyyMMdd"));
//创建文件夹
WinformLog("准备当日备份文件夹...");
var command = client.CreateCommand($"if not exist \"{backupFolderPath}\" mkdir \"{backupFolderPath}\"");
command.Execute();
if (command.ExitStatus != 0)
{
throw new Exception($"Failed to create {backupFolderPath}.");
}
//停止服务
WinformLog($"停止后台服务{serviceName}...");
var stopServiceCommand = client.CreateCommand($"sc stop \"{serviceName}\"");
stopServiceCommand.Execute();
if (stopServiceCommand.ExitStatus != 0)
{
throw new Exception($"Failed to stop {serviceName}.");
}
Task.Delay(1000);
//备份后端文件
WinformLog($"备份后端文件...");
string archivePath = $"{backupFolderPath}\\NetCore.zip";
var compressCommand = client.CreateCommand($"powershell.exe Compress-Archive -Path \"{programFolder}\\*.*\" -DestinationPath \"{archivePath}\" -Force");
compressCommand.Execute();
if (compressCommand.ExitStatus != 0)
{
throw new Exception("Failed to compress and move folder contents.");
}
//启动服务
WinformLog($"启动后台服务{serviceName}...");
var startServiceCommand = client.CreateCommand($"sc start \"{serviceName}\"");
startServiceCommand.Execute();
if (startServiceCommand.ExitStatus != 0)
{
throw new Exception($"Failed to start {serviceName}.");
}
//备份数据库
WinformLog($"开始备份数据库{dbName}...");
string databaseBackupPath = $"{backupFolderPath}\\db.bak";
var sqlcommand = client.CreateCommand($"sqlcmd -S . -U \"{dbUser}\" -P \"{dbPwd}\" -Q \"BACKUP DATABASE [{dbName}] TO DISK='{databaseBackupPath}' WITH INIT\"");
sqlcommand.Execute();
if (sqlcommand.ExitStatus != 0)
{
throw new Exception("Failed to backup database.");
}
WinformLog($"备份操作执行结束...");
}
catch (Exception ex)
{
WinformLog($"{ex.Message}", Color.Red);
}
}
}
});
}
#endregion
#region 服务的创建与删除
private void createService_Btn_Click(object sender, EventArgs e)
{
}
private async void deleteService_Btn_Click(object sender, EventArgs e)
{
var serviceName = serviceNameTBox.Text;
DialogResult dr = MessageBox.Show($"{EnvName}环境删除服务:{serviceName}", "删除提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
if (dr == DialogResult.OK)
{
await Task.Run(() =>
{
if (rb_local.Checked)
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = "cmd.exe";
startInfo.Arguments = $"/c sc query {serviceName} | find \"STATE\" | find /i \"RUNNING\" && net stop {serviceName} & sc delete {serviceName}";
// 在后台运行命令行窗口
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.CreateNoWindow = true;
using (Process process = new Process())
{
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
if (process.ExitCode == 0)
{
WinformLog($"{serviceName} 服务已经成功删除!");
}
else
{
WinformLog($"尝试停止并删除 {serviceName} 服务失败,请检查是否拥有管理员权限或服务是否存在。", Color.Red);
}
}
}
else
{
using (var client = new SshClient(Host, UserName, Password))
{
// 连接到远程服务器
client.Connect();
// 停止服务
string stopCommand = $"sc stop {serviceName}";
using (var stopCmd = client.CreateCommand(stopCommand))
{
WinformLog(stopCommand);
var stopOutput = stopCmd.Execute();
WinformLog(stopOutput);
}
// 删除服务
string deleteCommand = $"sc delete {serviceName}";
using (var deleteCmd = client.CreateCommand(deleteCommand))
{
WinformLog(deleteCommand);
var deleteOutput = deleteCmd.Execute();
WinformLog(deleteOutput);
}
// 断开SSH连接
client.Disconnect();
}
}
});
}
}
private void selectPathBtn_Click(object sender, EventArgs e)
{
if (rb_local.Checked)
{
OpenFileDialog dialog = new OpenFileDialog();
if (dialog.ShowDialog() == DialogResult.OK)
{
exePathTbox.Text = dialog.FileName;
WinformLog($"部署启动文件选择成功", Color.Green);
}
}
else
{
WinformLog("远程环境不支持直接选择目录", Color.Red);
}
}
#endregion
#region 测试环境发布
private async void vuePublishBtn_Click(object sender, EventArgs e)
{
vuePublishBtn.Enabled = false;
await Task.Run(() =>
{
using (var client = new SshClient("123.56.94.154", "Administrator", "WHxckj2019"))
{
// 连接到远程服务器
client.Connect();
//&& ./IRaCIS_Vue_Web.bat
string command = $@"cd C:\Users\Administrator\VueSourceCode && npm i && npm run build";
using (var cmd = client.CreateCommand(command))
{
WinformLog("测试环境:开始执行前端发布");
WinformLog(command);
var output = cmd.Execute();
WinformLog(output);
var output3 = cmd.Execute($@"xcopy /Y /Q ""C:\Users\Administrator\VueSourceCode\dist\index.html"" ""D:\Develop\PublishSite\IRaCIS.Vue.Web\dist\""");
WinformLog(output);
WinformLog("测试环境:前端发布成功");
}
// 断开SSH连接
client.Disconnect();
}
});
vuePublishBtn.Enabled = true;
}
private async void netCorePublishBtn_Click(object sender, EventArgs e)
{
netCorePublishBtn.Enabled = false;
await Task.Run(() =>
{
using (var client = new SshClient("123.56.94.154", "Administrator", "WHxckj2019"))
{
// 连接到远程服务器
client.Connect();
string command = $@"C:\Users\Administrator\bat\IRaCIS_Core_API.bat";
using (var cmd = client.CreateCommand(command))
{
WinformLog("测试环境:开始执行后端发布");
WinformLog(command);
var output = cmd.Execute();
WinformLog(output);
WinformLog("测试环境:后端发布成功");
}
// 断开SSH连接
client.Disconnect();
}
});
netCorePublishBtn.Enabled = true;
}
#endregion
#region 服务的启动与停止
private async void startServiceBtn_Click(object sender, EventArgs e)
{
startServiceBtn.Enabled = false;
await Task.Run(() =>
{
if (rb_local.Checked)
{
ServiceController controller = new ServiceController($"{startOrStopServiceTbox.Text}");
if (controller?.Status == ServiceControllerStatus.Running)
{
controller.Stop();
controller.WaitForStatus(ServiceControllerStatus.Stopped);
}
else
{
WinformLog("服务不是停止状态", Color.Red);
}
return;
}
using (var client = new SshClient(Host, UserName, Password))
{
// 连接到远程服务器
client.Connect();
string command = $@"sc start {startOrStopServiceTbox.Text}";
using (var cmd = client.CreateCommand(command))
{
WinformLog(command);
var output = cmd.Execute();
WinformLog(output);
}
// 断开SSH连接
client.Disconnect();
}
});
startServiceBtn.Enabled = true;
}
private async void stopServiceBtn_Click(object sender, EventArgs e)
{
startServiceBtn.Enabled = false;
await Task.Run(() =>
{
if (rb_local.Checked)
{
ServiceController controller = new ServiceController($"{startOrStopServiceTbox.Text}");
if (controller?.Status == ServiceControllerStatus.Running)
{
controller.Stop();
controller.WaitForStatus(ServiceControllerStatus.Stopped);
}
else
{
WinformLog("服务不是启动状态", Color.Red);
}
return;
}
using (var client = new SshClient(Host, UserName, Password))
{
// 连接到远程服务器
client.Connect();
string command = $@"sc stop {startOrStopServiceTbox.Text}";
using (var cmd = client.CreateCommand(command))
{
WinformLog(command);
var output = cmd.Execute();
WinformLog(output);
}
// 断开SSH连接
client.Disconnect();
}
});
startServiceBtn.Enabled = true;
}
#endregion
#region 上传文件到远程服务器发布
private void selectPublishFilePathBtn_Click(object sender, EventArgs e)
{
OpenFileDialog dialog = new OpenFileDialog();
if (dialog.ShowDialog() == DialogResult.OK)
{
publishFileTBox.Text = dialog.FileName;
WinformLog($"远程部署文件选择成功", Color.Green);
}
}
private void selectPublishFolderPathBtn_Click(object sender, EventArgs e)
{
FolderBrowserDialog dialog = new FolderBrowserDialog();
dialog.Description = "选择目录";
if (dialog.ShowDialog() == DialogResult.OK)
{
publishFolderTBox.Text = dialog.SelectedPath;
WinformLog($"远程部署后端发布文件夹选择成功", Color.Green);
}
}
private async void sshVuePublishBtn_Click(object sender, EventArgs e)
{
var desTinationFoder = jObjectCofig["BackUp"]["VuePublishFolder"].ToString();
sshVuePublishBtn.Enabled = false;
var filePath = publishFileTBox.Text;
var realName = Path.GetFileName(filePath);
var storeTempName = $"{Guid.NewGuid()}_{realName}";
if (string.IsNullOrEmpty(filePath) || !File.Exists(filePath))
{
WinformLog($"请选择存在的文件才能开始发布", Color.Red);
return;
}
WinformLog($"开始上传前端部署文件{Path.GetFileName(filePath)}...");
await Task.Run(() =>
{
using (var client = new SshClient(Host, UserName, Password))
{
client.ConnectionInfo.Encoding = System.Text.Encoding.UTF8;
// 连接到远程服务器
client.Connect();
using (var scpClient = new ScpClient(Host, UserName, Password))
{
scpClient.Connect();
using (var fileStream = new FileStream(filePath, FileMode.Open))
{
scpClient.Upload(fileStream, @$"/{storeTempName}");
}
scpClient.Disconnect();
WinformLog($"上传{realName}结束");
}
string command = $@"xcopy /Y /Q ""C:\{storeTempName}"" ""{desTinationFoder}""";
//拷贝文件到发布文件夹
using (var cmd = client.CreateCommand(command))
{
WinformLog(command);
var output = cmd.Execute();
WinformLog(output);
}
//删除临时文件
var delCommand = $"move /Y \"{Path.Combine(desTinationFoder, storeTempName)}\" \"{Path.Combine(desTinationFoder, realName)}\" && del C:\\{storeTempName}";
using (var cmd = client.CreateCommand(delCommand))
{
WinformLog(delCommand);
var output = cmd.Execute();
WinformLog(output);
}
WinformLog($"清除零时文件{storeTempName}完成");
// 断开SSH连接
client.Disconnect();
WinformLog($"前端发布成功");
}
});
WinformLog($"前端你发布结束");
sshVuePublishBtn.Enabled = true;
}
private async void sshNetCorePublishBtn_Click(object sender, EventArgs e)
{
var binPath = jObjectCofig["DefaultService"]["BinPath"].ToString();
var desTinationFoder = Path.GetDirectoryName(binPath);
sshNetCorePublishBtn.Enabled = false;
var filePath = publishFileTBox.Text;
var realName = Path.GetFileName(filePath);
var storeTempName = $"{Guid.NewGuid()}_{realName}";
if (string.IsNullOrEmpty(filePath) || !File.Exists(filePath))
{
WinformLog($"请选择存在的文件才能开始发布", Color.Red);
return;
}
if (!string.Equals(Path.GetExtension(realName), ".zip", StringComparison.OrdinalIgnoreCase))
{
WinformLog($"后端远程发布的压缩包必须是zip格式,并且不带目录", Color.Red);
return;
}
WinformLog($"开始上传后端部署文件{realName}...");
await NetCoreZipPublishAsync(filePath, desTinationFoder);
WinformLog($"后端发布结束");
sshNetCorePublishBtn.Enabled = true;
}
private async Task NetCoreZipPublishAsync(string filePath, string desTinationFoder)
{
var realName = Path.GetFileName(filePath);
var storeTempName = $"{Guid.NewGuid()}_{realName}";
await Task.Run(async () =>
{
using (var client = new SshClient(Host, UserName, Password))
{
client.ConnectionInfo.Encoding = System.Text.Encoding.UTF8;
// 连接到远程服务器
client.Connect();
using (var scpClient = new ScpClient(Host, UserName, Password))
{
scpClient.Connect();
using (var fileStream = new FileStream(filePath, FileMode.Open))
{
scpClient.Upload(fileStream, @$"/{storeTempName}");
}
scpClient.Disconnect();
WinformLog($"上传{realName}结束");
}
//后端发布,处理压缩包流程
//停止服务
stopServiceBtn_Click(null, null);
await Task.Delay(2000);
//解压到发布的目录
string expandCommand = $"Expand-Archive -Path '{filePath}' -DestinationPath '{desTinationFoder}' -Force";
using (var cmd = client.CreateCommand($"powershell.exe {expandCommand}"))
{
WinformLog(expandCommand);
var output = cmd.Execute();
WinformLog(output);
}
//启动服务
startServiceBtn_Click(null, null);
//删除临时文件
var delCommand = $" del C:\\{storeTempName}";
using (var cmd = client.CreateCommand(delCommand))
{
WinformLog(delCommand);
var output = cmd.Execute();
WinformLog(output);
}
WinformLog($"清除零时文件{storeTempName}完成");
// 断开SSH连接
client.Disconnect();
}
});
}
private async void sshNetCorePublishBtn2_Click(object sender, EventArgs e)
{
var binPath = jObjectCofig["DefaultService"]["BinPath"].ToString();
var localSourceFolder = publishFolderTBox.Text;
var desTinationFoder = Path.GetDirectoryName(binPath);
sshNetCorePublishBtn2.Enabled = false;
WinformLog($"开始打包该文件夹下的内容...");
var filePath = Path.Combine(localSourceFolder, "NetCorePublish.zip");
if (File.Exists(filePath))
{
File.Delete(filePath);
}
try
{
//将文件夹里的内容打包成压缩包
ZipFile.CreateFromDirectory(localSourceFolder, filePath);
}
catch (Exception ex)
{
WinformLog("错误:" + ex.Message, Color.Red);
}
await NetCoreZipPublishAsync(filePath, desTinationFoder);
WinformLog($"后端发布结束");
sshNetCorePublishBtn2.Enabled = true;
}
#endregion
}
}