2024-10-29 04:46:13 +00:00
|
|
|
|
using System.Diagnostics;
|
|
|
|
|
using System.IO.Pipelines;
|
2024-09-27 07:02:55 +00:00
|
|
|
|
using System.Xml.Linq;
|
2024-07-31 09:14:07 +00:00
|
|
|
|
using Common;
|
2024-07-30 07:36:42 +00:00
|
|
|
|
|
|
|
|
|
namespace LocalServer;
|
|
|
|
|
|
|
|
|
|
public class LocalSyncServer
|
|
|
|
|
{
|
2024-09-05 01:59:57 +00:00
|
|
|
|
#pragma warning disable CA2211 // Non-constant fields should not be visible
|
|
|
|
|
public static string TempRootFile = "C:/TempPack";
|
2024-09-27 07:02:55 +00:00
|
|
|
|
public static string SqlPackageAbPath = "sqlpackage";
|
2024-10-29 04:46:13 +00:00
|
|
|
|
|
2024-10-12 06:30:56 +00:00
|
|
|
|
// 使用msdeploy 将会打包当前可运行的内容,它很有可能不包含最新的构建
|
2024-09-27 10:41:12 +00:00
|
|
|
|
//public static string MsdeployAbPath = "msdeploy";
|
2024-09-27 07:02:55 +00:00
|
|
|
|
|
|
|
|
|
//与visual studio 匹配的Msbuild 路径。在vs 中打开power shell 命令行,使用 `(get-Command -Name msbuild).Source `
|
2024-10-12 06:30:56 +00:00
|
|
|
|
//使用msbuild 会缺少.net frame的运行环境 bin\roslyn 里面的内容,第一次需要人为复制一下,后面就就好了。
|
2024-09-27 07:02:55 +00:00
|
|
|
|
public static string MSBuildAbPath = "MSBuild";
|
2024-09-05 01:59:57 +00:00
|
|
|
|
#pragma warning restore CA2211 // Non-constant fields should not be visible
|
2024-10-29 04:46:13 +00:00
|
|
|
|
|
2024-10-12 06:30:56 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 连接状态,流程管理,LocalPipe 和 remotePipe 也在此处交换信息
|
|
|
|
|
/// </summary>
|
2024-09-26 09:49:40 +00:00
|
|
|
|
private StateHelpBase StateHelper;
|
|
|
|
|
|
|
|
|
|
public void SetStateHelper(StateHelpBase helper)
|
|
|
|
|
{
|
2024-10-29 04:46:13 +00:00
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
StateHelper = helper;
|
|
|
|
|
if (SyncConfig != null)
|
|
|
|
|
{
|
|
|
|
|
var LastExec = NotNullSyncConfig.ExecProcesses.Find(x =>
|
|
|
|
|
{
|
|
|
|
|
return x.StepBeforeOrAfter == "A"
|
|
|
|
|
&& x.Step == (helper.Step - 1)
|
|
|
|
|
&& x.ExecInLocalOrServer == "L";
|
|
|
|
|
});
|
|
|
|
|
ExecProcess(LastExec);
|
|
|
|
|
var CurrentExec = NotNullSyncConfig.ExecProcesses.Find(x =>
|
|
|
|
|
{
|
|
|
|
|
return x.StepBeforeOrAfter == "B"
|
|
|
|
|
&& x.Step == helper.Step
|
|
|
|
|
&& x.ExecInLocalOrServer == "L";
|
|
|
|
|
});
|
|
|
|
|
ExecProcess(CurrentExec);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Close(ex.Message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void ExecProcess(ExecProcess? ep)
|
|
|
|
|
{
|
|
|
|
|
if (ep != null)
|
|
|
|
|
{
|
|
|
|
|
ProcessStartInfo startInfo =
|
|
|
|
|
new()
|
|
|
|
|
{
|
|
|
|
|
StandardOutputEncoding = System.Text.Encoding.UTF8,
|
|
|
|
|
Arguments = ep.Argumnets,
|
|
|
|
|
FileName = ep.FileName, // The command to execute (can be any command line tool)
|
|
|
|
|
// The arguments to pass to the command (e.g., list directory contents)
|
|
|
|
|
RedirectStandardOutput = true, // Redirect the standard output to a string
|
|
|
|
|
UseShellExecute = false, // Do not use the shell to execute the command
|
|
|
|
|
CreateNoWindow = true // Do not create a new window for the command
|
|
|
|
|
};
|
|
|
|
|
using Process process = new() { StartInfo = startInfo };
|
|
|
|
|
// Start the process
|
|
|
|
|
process.Start();
|
|
|
|
|
|
|
|
|
|
// Read the output from the process
|
|
|
|
|
string output = process.StandardOutput.ReadToEnd();
|
|
|
|
|
|
|
|
|
|
// Wait for the process to exit
|
|
|
|
|
process.WaitForExit();
|
|
|
|
|
|
|
|
|
|
if (process.ExitCode == 0)
|
|
|
|
|
{
|
|
|
|
|
LocalPipe
|
|
|
|
|
.SendMsg(
|
|
|
|
|
StateHelper.CreateMsg(
|
|
|
|
|
$"{ep.Step}-{ep.StepBeforeOrAfter}-{ep.ExecInLocalOrServer}-{ep.FileName} {ep.Argumnets} 执行成功!"
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
.Wait();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
LocalPipe
|
|
|
|
|
.SendMsg(
|
|
|
|
|
StateHelper.CreateMsg(
|
|
|
|
|
$"{ep.Step}-{ep.StepBeforeOrAfter}-{ep.ExecInLocalOrServer}-{ep.FileName} {ep.Argumnets} 失败 {output}!"
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
.Wait();
|
|
|
|
|
throw new Exception("错误,信息参考上一条消息!");
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-09-26 09:49:40 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-10-12 06:30:56 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 查找构建xml文件,获取构建信息,那这个不用了
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
// public static string GetProjectOutPath(string project)
|
|
|
|
|
// {
|
|
|
|
|
// try
|
|
|
|
|
// {
|
|
|
|
|
// XDocument xdoc = XDocument.Load(project);
|
|
|
|
|
// // 获取根元素
|
|
|
|
|
// XElement rootElement = xdoc.Root ?? throw new NullReferenceException("Root");
|
|
|
|
|
// Console.WriteLine("根元素: " + rootElement.Name);
|
|
|
|
|
|
|
|
|
|
// // 遍历子节点
|
|
|
|
|
// foreach (XElement element in rootElement.Elements())
|
|
|
|
|
// {
|
|
|
|
|
// if (element.Name.LocalName.Contains("PropertyGroup"))
|
|
|
|
|
// {
|
|
|
|
|
// var Conditon = element.Attribute("Condition");
|
|
|
|
|
|
|
|
|
|
// if (Conditon != null)
|
|
|
|
|
// {
|
|
|
|
|
// if (Conditon.Value.Contains("Release"))
|
|
|
|
|
// {
|
|
|
|
|
// foreach (XElement element2 in element.Elements())
|
|
|
|
|
// {
|
|
|
|
|
// if (element2.Name.LocalName == "OutputPath")
|
|
|
|
|
// {
|
|
|
|
|
// return element2.Value;
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// return "bin/";
|
|
|
|
|
// }
|
|
|
|
|
// catch (Exception)
|
|
|
|
|
// {
|
|
|
|
|
// return "bin/";
|
|
|
|
|
// }
|
|
|
|
|
// }
|
2024-09-27 07:02:55 +00:00
|
|
|
|
|
2024-09-26 09:49:40 +00:00
|
|
|
|
public StateHelpBase GetStateHelper()
|
|
|
|
|
{
|
|
|
|
|
return StateHelper;
|
|
|
|
|
}
|
2024-07-31 09:14:07 +00:00
|
|
|
|
|
2024-10-12 06:30:56 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 此次发布的配置
|
|
|
|
|
/// </summary>
|
2024-07-31 09:14:07 +00:00
|
|
|
|
public Config? SyncConfig;
|
|
|
|
|
|
2024-09-05 09:48:08 +00:00
|
|
|
|
public Config NotNullSyncConfig
|
|
|
|
|
{
|
|
|
|
|
get
|
2024-09-05 01:59:57 +00:00
|
|
|
|
{
|
2024-09-05 09:48:08 +00:00
|
|
|
|
if (SyncConfig == null)
|
|
|
|
|
{
|
|
|
|
|
throw new ArgumentNullException("SyncConfig");
|
|
|
|
|
}
|
|
|
|
|
return SyncConfig;
|
2024-09-05 01:59:57 +00:00
|
|
|
|
}
|
2024-09-05 09:48:08 +00:00
|
|
|
|
}
|
2024-09-05 01:59:57 +00:00
|
|
|
|
|
2024-10-12 06:30:56 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 发布的名称
|
|
|
|
|
/// </summary>
|
2024-09-07 06:46:08 +00:00
|
|
|
|
public string Name;
|
|
|
|
|
|
2024-07-31 09:14:07 +00:00
|
|
|
|
/// <summary>
|
2024-10-12 06:30:56 +00:00
|
|
|
|
/// jswebsocket 和 local server 的连接,它没有加密
|
2024-07-31 09:14:07 +00:00
|
|
|
|
/// </summary>
|
2024-09-05 09:48:08 +00:00
|
|
|
|
public readonly AbsPipeLine LocalPipe;
|
2024-07-31 09:14:07 +00:00
|
|
|
|
|
2024-10-12 06:30:56 +00:00
|
|
|
|
/// <summary>
|
2024-10-29 04:46:13 +00:00
|
|
|
|
/// local server 和 remote server 的连接,它有加密
|
2024-10-12 06:30:56 +00:00
|
|
|
|
/// </summary>
|
2024-09-23 05:55:17 +00:00
|
|
|
|
public readonly AbsPipeLine RemotePipe;
|
2024-09-23 09:46:46 +00:00
|
|
|
|
|
2024-07-31 09:14:07 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 父工程,用于释放资源
|
|
|
|
|
/// </summary>
|
2024-07-30 07:36:42 +00:00
|
|
|
|
public readonly LocalSyncServerFactory Factory;
|
|
|
|
|
|
2024-09-23 09:46:46 +00:00
|
|
|
|
public LocalSyncServer(
|
|
|
|
|
AbsPipeLine pipe,
|
|
|
|
|
LocalSyncServerFactory factory,
|
|
|
|
|
string name,
|
|
|
|
|
AbsPipeLine remotePipe
|
|
|
|
|
)
|
2024-07-30 07:36:42 +00:00
|
|
|
|
{
|
2024-09-05 09:48:08 +00:00
|
|
|
|
LocalPipe = pipe;
|
2024-07-30 07:36:42 +00:00
|
|
|
|
Factory = factory;
|
2024-09-05 01:59:57 +00:00
|
|
|
|
StateHelper = new ConnectAuthorityHelper(this);
|
2024-09-07 06:46:08 +00:00
|
|
|
|
Name = name;
|
2024-09-23 05:55:17 +00:00
|
|
|
|
RemotePipe = remotePipe;
|
2024-10-10 05:15:14 +00:00
|
|
|
|
}
|
2024-07-31 09:14:07 +00:00
|
|
|
|
|
2024-10-12 06:30:56 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 这个阻塞在,接口中有http上下文处
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
2024-10-10 05:15:14 +00:00
|
|
|
|
public async Task Connect()
|
|
|
|
|
{
|
|
|
|
|
try
|
2024-09-05 01:59:57 +00:00
|
|
|
|
{
|
2024-10-10 05:15:14 +00:00
|
|
|
|
var rs = LocalPipe.Work(
|
|
|
|
|
(byte[] b) =>
|
|
|
|
|
{
|
|
|
|
|
return StateHelper.ReceiveLocalMsg(b);
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
await foreach (var r in rs) { }
|
|
|
|
|
}
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
{
|
|
|
|
|
Close(e.Message);
|
|
|
|
|
}
|
2024-07-30 07:36:42 +00:00
|
|
|
|
}
|
2024-07-31 09:14:07 +00:00
|
|
|
|
|
2024-10-12 06:30:56 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 关闭连接
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="CloseReason"></param>
|
2024-09-05 01:59:57 +00:00
|
|
|
|
public void Close(string? CloseReason)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2024-09-05 09:48:08 +00:00
|
|
|
|
LocalPipe.Close(CloseReason);
|
|
|
|
|
RemotePipe.Close(CloseReason);
|
2024-09-05 01:59:57 +00:00
|
|
|
|
}
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
{
|
|
|
|
|
//TODO 日志
|
|
|
|
|
Console.WriteLine(e.Message);
|
|
|
|
|
}
|
|
|
|
|
finally
|
|
|
|
|
{
|
|
|
|
|
Factory.RemoveLocalSyncServer(this);
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-07-30 07:36:42 +00:00
|
|
|
|
}
|