style: 修改了代码格式,删掉了一些无用的代码,添加了一些注释
This commit is contained in:
parent
1e033e2ca3
commit
ca6795d31f
14 changed files with 815 additions and 1206 deletions
|
@ -3,7 +3,7 @@ namespace Common;
|
|||
public class DirFileConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 相对路径
|
||||
/// 相对路径,与根路径拼成一个完整的路径,注意 "/" 不要缺少
|
||||
/// </summary>
|
||||
public required string DirPath { get; set; }
|
||||
|
||||
|
@ -17,9 +17,17 @@ public class DirFileConfig
|
|||
/// </summary>
|
||||
public List<string>? CherryPicks { get; set; }
|
||||
|
||||
///
|
||||
/// <summary>
|
||||
/// 本地文件信息,也是即将发布的文件信息,通常是最新的版本
|
||||
/// </summary>
|
||||
public Dir? LocalDirInfo { get; set; }
|
||||
/// <summary>
|
||||
/// 差异文件信息
|
||||
/// </summary>
|
||||
public Dir? DiffDirInfo { get; set; }
|
||||
/// <summary>
|
||||
/// 远程文件信息,通常是较旧的版本
|
||||
/// </summary>
|
||||
public Dir? RemoteDirInfo { get; set; }
|
||||
}
|
||||
|
||||
|
@ -63,6 +71,9 @@ public class Config
|
|||
/// </summary>
|
||||
public required string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 本次发布的唯一id
|
||||
/// </summary>
|
||||
public Guid Id { get; set; } = Guid.NewGuid();
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -6,28 +6,52 @@ namespace Common;
|
|||
|
||||
public abstract class AbsPipeLine(bool isAES)
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// pipeLine工作函数,生效期间永久阻塞
|
||||
/// </summary>
|
||||
/// <param name="receiveCb">回调函数,从pipeline接收到的消息</param>
|
||||
/// <param name="addr">连接的远程地址</param>
|
||||
/// <returns>第一次返回连接信息,第二次当pipeline 被断开时返回,此时可能是正常完成断开,或异常发生断开</returns>
|
||||
public abstract IAsyncEnumerable<int> Work(Func<byte[], bool> receiveCb, string addr = "");
|
||||
protected Func<byte[], bool> ReceiveMsg = (byte[] a) =>
|
||||
{
|
||||
return true;
|
||||
};
|
||||
/// <summary>
|
||||
/// 监听pipeline 消息,由Work 函数调用
|
||||
/// </summary>
|
||||
/// <param name="receiveCb">消息回调</param>
|
||||
/// <returns></returns>
|
||||
protected abstract Task Listen(Func<byte[], bool> receiveCb);
|
||||
|
||||
/// <summary>
|
||||
/// 关闭连接
|
||||
/// </summary>
|
||||
/// <param name="CloseReason"></param>
|
||||
/// <param name="CloseReason">关闭原因</param>
|
||||
/// <returns></returns>
|
||||
public abstract Task Close(string? CloseReason);
|
||||
|
||||
/// <summary>
|
||||
/// 发送消息
|
||||
/// 向管道中发送消息
|
||||
/// </summary>
|
||||
/// <param name="msg"></param>
|
||||
/// <returns></returns>
|
||||
public abstract Task SendMsg(SyncMsg msg);
|
||||
|
||||
/// <summary>
|
||||
/// 打包文件上传
|
||||
/// </summary>
|
||||
/// <param name="url">上传地址</param>
|
||||
/// <param name="filePath">上传的文件路径</param>
|
||||
/// <param name="progressCb">上传进度回调(现在没有回调)</param>
|
||||
/// <returns>上传完成时返回</returns>/
|
||||
public abstract Task UploadFile(string url, string filePath, Func<double, bool> progressCb);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 管道消息是否使用AES加密
|
||||
/// </summary>
|
||||
protected readonly bool IsAES = isAES;
|
||||
}
|
||||
|
||||
|
@ -42,16 +66,16 @@ public class WebSocPipeLine<TSocket>(TSocket socket, bool isAES) : AbsPipeLine(i
|
|||
Func<double, bool> progressCb
|
||||
)
|
||||
{
|
||||
//throw new Exception("sdfsdf");
|
||||
using var client = new HttpClient();
|
||||
using var content = new MultipartFormDataContent();
|
||||
using var fileStream = new FileStream(filePath, FileMode.Open);
|
||||
var progress = new Progress<double>(
|
||||
(current) =>
|
||||
{
|
||||
progressCb(current);
|
||||
}
|
||||
);
|
||||
// TODO 上传进度回调
|
||||
// var progress = new Progress<double>(
|
||||
// (current) =>
|
||||
// {
|
||||
// progressCb(current);
|
||||
// }
|
||||
// );
|
||||
//var fileContent = new ProgressStreamContent(fileStream, progress);
|
||||
content.Add(new StreamContent(fileStream), "file", Path.GetFileName(filePath));
|
||||
var it = await client.PostAsync("http://" + url + "/UploadFile", content);
|
||||
|
@ -80,7 +104,7 @@ public class WebSocPipeLine<TSocket>(TSocket socket, bool isAES) : AbsPipeLine(i
|
|||
|
||||
protected override async Task Listen(Func<byte[], bool> receiveCb)
|
||||
{
|
||||
//最大1MB!=
|
||||
//warning 最大支持1MB,这由需要同步的文件数量大小决定 UTF-8 每个字符,汉字视为4个字节,数字1个 ,英文字母2个。1MB=256KB*4,25万个字符能描述就行
|
||||
var buffer = new byte[1024 * 1024];
|
||||
|
||||
while (Socket.State == WebSocketState.Open)
|
||||
|
@ -100,8 +124,6 @@ public class WebSocPipeLine<TSocket>(TSocket socket, bool isAES) : AbsPipeLine(i
|
|||
System.Buffer.BlockCopy(buffer, 0, nbuffer, 0, receiveResult.Count);
|
||||
if (IsAES)
|
||||
{
|
||||
//var msg1 = Encoding.UTF8.GetString(nbuffer);
|
||||
//var n1Buffler = Encoding.UTF8.GetBytes(msg1);
|
||||
var nnbuffer = AESHelper.DecryptStringFromBytes_Aes(nbuffer);
|
||||
receiveCb(Encoding.UTF8.GetBytes(nnbuffer));
|
||||
}
|
||||
|
@ -117,14 +139,8 @@ public class WebSocPipeLine<TSocket>(TSocket socket, bool isAES) : AbsPipeLine(i
|
|||
{
|
||||
if (Socket.State == WebSocketState.Open)
|
||||
{
|
||||
//await SendMsg(
|
||||
// new SyncMsg
|
||||
// {
|
||||
// Type = SyncMsgType.Error,
|
||||
// Step = SyncProcessStep.Finally,
|
||||
// Body = CloseReason ?? ""
|
||||
// }
|
||||
//);
|
||||
//CloseReason 最大不能超过123bytes.https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/close
|
||||
//若传递超过这个限制,此处表现WebSocket将会卡住,无法关闭。
|
||||
if (Encoding.UTF8.GetBytes(CloseReason ?? "").Length > 120)
|
||||
{
|
||||
await SendMsg(
|
||||
|
@ -156,9 +172,9 @@ public class WebSocPipeLine<TSocket>(TSocket socket, bool isAES) : AbsPipeLine(i
|
|||
{
|
||||
string msgStr = JsonSerializer.Serialize(msg);
|
||||
var it = AESHelper.EncryptStringToBytes_Aes(msgStr);
|
||||
//var xx = new ArraySegment<byte>(it);
|
||||
if (IsAES)
|
||||
{
|
||||
// 加密后的字符,使用Binary 发送,加密通常不会发送到最前端,通常是 js 写的websocket
|
||||
await Socket.SendAsync(
|
||||
new ArraySegment<byte>(it),
|
||||
WebSocketMessageType.Binary,
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
namespace Common;
|
||||
|
||||
/// <summary>
|
||||
/// Dir比较方法
|
||||
/// </summary>
|
||||
public static class DirExtension
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -248,6 +251,13 @@ public static class DirExtension
|
|||
return cDir;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 根据Dirobject记录的信息,写入磁盘
|
||||
/// </summary>
|
||||
/// <param name="thisDir"></param>
|
||||
/// <param name="fileDirOp"> 文件操作类,它是如何写入文件的方法</param>
|
||||
/// <exception cref="ArgumentException"></exception>
|
||||
public static void WriteByThisInfo(this Dir thisDir, FileDirOpStra fileDirOp)
|
||||
{
|
||||
static void f(Dir dir, FileDirOpStra fileDirOp)
|
||||
|
@ -285,6 +295,13 @@ public static class DirExtension
|
|||
f(thisDir, fileDirOp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从文件夹中提取文件信息
|
||||
/// </summary>
|
||||
/// <param name="thisDir"></param>
|
||||
/// <param name="cherryPicks">只提取这些信息,最高级别</param>
|
||||
/// <param name="exculdes">忽略这些文件信息</param>
|
||||
/// <exception cref="NotSupportedException"></exception>
|
||||
public static void ExtractInfo(
|
||||
this Dir thisDir,
|
||||
List<string>? cherryPicks = null,
|
||||
|
@ -334,7 +351,12 @@ public static class DirExtension
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加一个子对象,这个不包含文件或文件夹的创建
|
||||
/// </summary>
|
||||
/// <param name="thisDir"></param>
|
||||
/// <param name="child"></param>
|
||||
/// <exception cref="ArgumentException"></exception>
|
||||
public static void AddChild(this Dir thisDir, AFileOrDir child)
|
||||
{
|
||||
if (child.FormatedPath[..thisDir.FormatedPath.Length] != thisDir.FormatedPath)
|
||||
|
@ -371,6 +393,16 @@ public static class DirExtension
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 合并diffdir中的内容
|
||||
/// </summary>
|
||||
/// <param name="thisDir"></param>
|
||||
/// <param name="diffdir"></param>
|
||||
/// <param name="IsUpdateObject">是否更新对象</param>
|
||||
/// <param name="IsUpdateDirFile">是否更新文件夹和文件</param>
|
||||
/// <exception cref="ArgumentException"></exception>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public static void Combine(
|
||||
this Dir thisDir,
|
||||
FileDirOpStra? fileDirOp,
|
||||
|
@ -495,6 +527,14 @@ public static class DirExtension
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// clone一个新的对象
|
||||
/// </summary>
|
||||
/// <param name="thisDir"></param>
|
||||
/// <param name="optype">重设的操作类型</param>
|
||||
/// <param name="IsResetNextOpType">是否重设操作类型</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="Exception"></exception>
|
||||
public static Dir Clone(
|
||||
this Dir thisDir,
|
||||
NextOpType? optype = null,
|
||||
|
@ -536,6 +576,13 @@ public static class DirExtension
|
|||
return ndir;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 改变根路径位置
|
||||
/// </summary>
|
||||
/// <param name="thisDir"></param>
|
||||
/// <param name="oldPath"></param>
|
||||
/// <param name="newPath"></param>
|
||||
/// <returns></returns>
|
||||
public static Dir ResetRootPath(this Dir thisDir, string oldPath, string newPath)
|
||||
{
|
||||
thisDir.FormatedPath = thisDir.FormatedPath.Replace(oldPath, newPath);
|
||||
|
@ -553,6 +600,10 @@ public static class DirExtension
|
|||
return thisDir;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 文件操作权限检查(废弃)
|
||||
/// </summary>
|
||||
/// <param name="thisDir"></param>
|
||||
public static void AccessCheck(this Dir thisDir)
|
||||
{
|
||||
//不是核心关注点,下面实现有bug。不校验所有文件夹权限,创建时会抛出错误,此时手动处理吧。
|
||||
|
@ -639,247 +690,3 @@ public static class DirExtension
|
|||
//});
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 文件夹结构,它包含文件和文件夹
|
||||
/// </summary>
|
||||
/// <param name="path">绝对路径</param>
|
||||
/// <param name="children">子文件或文件夹</param>
|
||||
// public class Dirxx(string path, List<AFileOrDir>? children = null, NextOpType? nextOp = null)
|
||||
// : AFileOrDir(path, DirOrFile.Dir, nextOp)
|
||||
// {
|
||||
// public List<AFileOrDir> Children { get; set; } = children ?? [];
|
||||
|
||||
/* public override bool IsEqual(AFileOrDir other)
|
||||
{
|
||||
if (other is not Dir otherDir)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this.FormatedPath != otherDir.FormatedPath || this.NextOp != otherDir.NextOp)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (this.Children.Count != otherDir.Children.Count)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
this.Children.Sort(AFileOrDir.Compare);
|
||||
otherDir.Children.Sort(AFileOrDir.Compare);
|
||||
for (int i = 0; i < this.Children.Count; i++)
|
||||
{
|
||||
if (!this.Children[i].IsEqual(otherDir.Children[i]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} */
|
||||
|
||||
/// <summary>
|
||||
/// clone, 但是更改根目录
|
||||
/// </summary>
|
||||
/// <param name="optype">操作步骤</param>
|
||||
/// <param name="oldRootPath">旧根路径</param>
|
||||
/// <param name="newRootPath">新根路径</param>
|
||||
/// <param name="IsResetNextOpType">是否重置下步操作</param>
|
||||
/// <returns></returns>
|
||||
// public Dir Clone(
|
||||
// NextOpType? optype,
|
||||
// string oldRootPath,
|
||||
// string newRootPath,
|
||||
// bool IsResetNextOpType = false
|
||||
// )
|
||||
// {
|
||||
// var ndir = this.Clone(optype, IsResetNextOpType);
|
||||
// ndir.ResetRootPath(oldRootPath, newRootPath);
|
||||
// return ndir;
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// clone,不克隆文件
|
||||
/// </summary>
|
||||
/// <param name="optype"></param>
|
||||
/// <param name="IsResetNextOpType"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="Exception"></exception>
|
||||
// public Dir Clone(NextOpType? optype = null, bool IsResetNextOpType = false) { }
|
||||
|
||||
/// <summary>
|
||||
/// 重设置根目录
|
||||
/// </summary>
|
||||
/// <param name="oldPath"></param>
|
||||
/// <param name="newPath"></param>
|
||||
// public void ResetRootPath(string oldPath, string newPath)
|
||||
// {
|
||||
// this.FormatedPath = this.FormatedPath.Replace(oldPath, newPath);
|
||||
// this.Children.ForEach(e =>
|
||||
// {
|
||||
// if (e is File file)
|
||||
// {
|
||||
// file.FormatedPath = file.FormatedPath.Replace(oldPath, newPath);
|
||||
// }
|
||||
// else if (e is Dir dir)
|
||||
// {
|
||||
// dir.ResetRootPath(oldPath, newPath);
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// 文件夹合并
|
||||
/// </summary>
|
||||
/// <param name="fileDirOp">具体操作步骤</param>
|
||||
/// <param name="diffdir">将要更新的内容</param>
|
||||
/// <param name="IsUpdateObject"> 是否更新Object对象</param>
|
||||
/// <param name="IsUpdateDirFile">是否更新文件目录树</param>
|
||||
/// <returns></returns>
|
||||
// public void Combine(
|
||||
// FileDirOpStra? fileDirOp,
|
||||
// Dir diffdir,
|
||||
// bool IsUpdateObject = true,
|
||||
// bool IsUpdateDirFile = false
|
||||
// ) { }
|
||||
|
||||
// /// <summary>
|
||||
// /// 合并两个文件夹,other不会发生改变,this将合并一个副本,这不会改变文件结构
|
||||
// /// </summary>
|
||||
// /// <param name="other">它的一个clone将被合并的dir,它的NextOp 不应该是空,否则什么都不会发生</param>
|
||||
// /// <returns></returns>
|
||||
// public void CombineJustObject(Dir other)
|
||||
// {
|
||||
// Combine(null, other, true, false);
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// 合并两个文件夹,other不会发生改变,this将不会改变,而文件结构会改变
|
||||
// /// </summary>
|
||||
// /// <param name="other">它的一个clone将被合并的dir,它的NextOp 不应该是空,否则什么都不会发生</param>
|
||||
// /// <returns></returns>
|
||||
// public void CombineJustDirFile(FileDirOpStra fileDirOp, Dir diffDir)
|
||||
// {
|
||||
// Combine(fileDirOp, diffDir, false, true);
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// 添加子节点,根目录相同,才会被添加进去
|
||||
// /// </summary>
|
||||
// /// <param name="child"></param>
|
||||
// /// <returns></returns>/
|
||||
// protected void AddChild(AFileOrDir child) { }
|
||||
|
||||
// /// <summary>
|
||||
// /// 从文件夹中提取信息
|
||||
// /// </summary>
|
||||
// /// <param name="cherryPicks">绝对路径,只包含的文件或者目录</param>
|
||||
// /// <param name="exculdes">绝对路径,排除的文件或目录</param>
|
||||
// /// <exception cref="NotSupportedException"></exception>
|
||||
|
||||
|
||||
// /// <summary>
|
||||
// /// 写入目录文件树,首先必须定义写入文件的策略,此目录结构不包含文件内容,但有一个
|
||||
// /// 文件的修改时间,是否修改文件的修改时间,需要定义文件的写入策略 WriteFileStrageFunc
|
||||
// /// </summary>
|
||||
// /// <returns></returns>
|
||||
|
||||
|
||||
// /// <summary>
|
||||
// /// 校验文件夹和文件权限
|
||||
// /// </summary>
|
||||
// // private void AccessCheck()j
|
||||
// // {
|
||||
// //不是核心关注点,下面实现有bug。不校验所有文件夹权限,创建时会抛出错误,此时手动处理吧。
|
||||
// // return;
|
||||
// //this.Children.ForEach(e =>
|
||||
// //{
|
||||
// // if (e is File file)
|
||||
// // {
|
||||
// // if (file.NextOp == null) { }
|
||||
// // else if (file.NextOp == NextOpType.Add)
|
||||
// // {
|
||||
// // if (
|
||||
// // !AccessWrapper.CheckDirAccess(
|
||||
// // Path.GetDirectoryName(file.FormatedPath)
|
||||
// // ?? throw new DirectoryNotFoundException(
|
||||
// // $"{file.FormatedPath} 此父路径不存在"
|
||||
// // ),
|
||||
// // [DirAcess.CreateFiles]
|
||||
// // )
|
||||
// // )
|
||||
// // {
|
||||
// // throw new UnauthorizedAccessException($"{file.FormatedPath} 无权限创建文件");
|
||||
// // }
|
||||
// // }
|
||||
// // else if (file.NextOp == NextOpType.Modify)
|
||||
// // {
|
||||
// // if (
|
||||
// // !(
|
||||
// // AccessWrapper.CheckFileAccess(file.FormatedPath, [FileAccess.Delete])
|
||||
// // && AccessWrapper.CheckDirAccess(
|
||||
// // Path.GetDirectoryName(file.FormatedPath)
|
||||
// // ?? throw new DirectoryNotFoundException(
|
||||
// // $"{file.FormatedPath} 此父路径不存在"
|
||||
// // ),
|
||||
// // [DirAcess.CreateFiles]
|
||||
// // )
|
||||
// // )
|
||||
// // )
|
||||
// // {
|
||||
// // throw new UnauthorizedAccessException(
|
||||
// // $"{file.FormatedPath} 无权限删除源文件或者创建新文件"
|
||||
// // );
|
||||
// // }
|
||||
// // }
|
||||
// // else if (file.NextOp == NextOpType.Del)
|
||||
// // {
|
||||
// // if (!AccessWrapper.CheckFileAccess(file.FormatedPath, [FileAccess.Delete]))
|
||||
// // {
|
||||
// // throw new UnauthorizedAccessException($"{file.FormatedPath} 无权限删除源文件");
|
||||
// // }
|
||||
// // }
|
||||
// // }
|
||||
// // else if (e is Dir dir)
|
||||
// // {
|
||||
// // if (dir.NextOp == null) { }
|
||||
// // else if (dir.NextOp == NextOpType.Add)
|
||||
// // {
|
||||
// // if (
|
||||
// // !AccessWrapper.CheckDirAccess(
|
||||
// // Path.GetDirectoryName(dir.FormatedPath)
|
||||
// // ?? throw new DirectoryNotFoundException(
|
||||
// // $"{dir.FormatedPath} 此父路径不存在"
|
||||
// // ),
|
||||
// // [DirAcess.CreateDirectories, DirAcess.CreateFiles]
|
||||
// // )
|
||||
// // )
|
||||
// // {
|
||||
// // throw new UnauthorizedAccessException($"{dir.FormatedPath} 无权限创建文件夹或者文件");
|
||||
// // }
|
||||
// // }
|
||||
// // else if (dir.NextOp == NextOpType.Del)
|
||||
// // {
|
||||
// // if (!AccessWrapper.CheckDirAccess(dir.FormatedPath, [DirAcess.Delete]))
|
||||
// // {
|
||||
// // throw new UnauthorizedAccessException($"{dir.FormatedPath} 无权限删除文件夹");
|
||||
// // }
|
||||
// // else
|
||||
// // {
|
||||
// // //校验是否拥有子文件或者文件夹的删除权限,
|
||||
// // dir.AccessCheck();
|
||||
// // }
|
||||
// // }
|
||||
// // }
|
||||
// //});
|
||||
// // }
|
||||
|
||||
// /// <summary>
|
||||
// /// 比较两个目录文件树是否相同,不相同返回差异部分,左侧是右侧的下一个版本,任何一个节点的nextop != null,即所有
|
||||
// /// 节点都会打上标记
|
||||
// /// 文件夹的 NextOp 只有新增和删除
|
||||
// /// </summary>
|
||||
// /// <param name="otherRootDir"></param>
|
||||
// /// <returns></returns>
|
||||
// }
|
||||
|
|
|
@ -39,10 +39,10 @@ public class AFileOrDir
|
|||
set { Path = value; }
|
||||
}
|
||||
|
||||
public bool IsEqual(AFileOrDir other)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// public bool IsEqual(AFileOrDir other)
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
public static int Compare(AFileOrDir l, AFileOrDir r)
|
||||
{
|
||||
|
@ -69,7 +69,7 @@ public class File : AFileOrDir
|
|||
|
||||
public required DateTime MTime { get; set; }
|
||||
|
||||
public new bool IsEqual(AFileOrDir other)
|
||||
public bool IsEqual(AFileOrDir other)
|
||||
{
|
||||
if (other is not File otherFile)
|
||||
{
|
||||
|
@ -96,7 +96,7 @@ public class Dir : AFileOrDir
|
|||
|
||||
public required List<AFileOrDir> Children { get; set; }
|
||||
|
||||
public new bool IsEqual(AFileOrDir other)
|
||||
public bool IsEqual(AFileOrDir other)
|
||||
{
|
||||
if (other is not Dir otherDir)
|
||||
{
|
||||
|
@ -116,7 +116,23 @@ public class Dir : AFileOrDir
|
|||
otherDir.Children.Sort(AFileOrDir.Compare);
|
||||
for (int i = 0; i < this.Children.Count; i++)
|
||||
{
|
||||
if (!this.Children[i].IsEqual(otherDir.Children[i]))
|
||||
var l = this.Children[i];
|
||||
var r = otherDir.Children[i];
|
||||
if (l is Dir ld && r is Dir rd)
|
||||
{
|
||||
if (!ld.IsEqual(rd))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (l is File lf && r is File rf)
|
||||
{
|
||||
if (!lf.IsEqual(rf))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -321,391 +321,391 @@ public class FileDirOpForUnpack(string srcRootPath, string dstRootPath) : FileDi
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 文件目录权限校验
|
||||
/// </summary>
|
||||
public class FileDirOpForAccessCheck : FileDirOpStra
|
||||
{
|
||||
public override void FileCreate(string absolutePath, DateTime mtime)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
// /// <summary>
|
||||
// /// 文件目录权限校验
|
||||
// /// </summary>
|
||||
// public class FileDirOpForAccessCheck : FileDirOpStra
|
||||
// {
|
||||
// public override void FileCreate(string absolutePath, DateTime mtime)
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
|
||||
public override void DirCreate(Dir dir, bool IsRecursion = true)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
// public override void DirCreate(Dir dir, bool IsRecursion = true)
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
|
||||
public override void FileModify(string absolutePath, DateTime mtime)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
// public override void FileModify(string absolutePath, DateTime mtime)
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
|
||||
public override void FileDel(string absolutePath)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
// public override void FileDel(string absolutePath)
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
|
||||
public override void DirDel(Dir dir, bool IsRecursion = true)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
// public override void DirDel(Dir dir, bool IsRecursion = true)
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
// }
|
||||
|
||||
public enum FileAccess
|
||||
{
|
||||
Read,
|
||||
Write,
|
||||
Delete,
|
||||
Execute
|
||||
}
|
||||
// public enum FileAccess
|
||||
// {
|
||||
// Read,
|
||||
// Write,
|
||||
// Delete,
|
||||
// Execute
|
||||
// }
|
||||
|
||||
public enum DirAcess
|
||||
{
|
||||
/// <summary>
|
||||
/// 读取权限
|
||||
/// </summary>
|
||||
Read,
|
||||
// public enum DirAcess
|
||||
// {
|
||||
// /// <summary>
|
||||
// /// 读取权限
|
||||
// /// </summary>
|
||||
// Read,
|
||||
|
||||
/// <summary>
|
||||
/// 写入权限
|
||||
/// </summary>
|
||||
Write,
|
||||
// /// <summary>
|
||||
// /// 写入权限
|
||||
// /// </summary>
|
||||
// Write,
|
||||
|
||||
/// <summary>
|
||||
/// 列出文件夹权限
|
||||
/// </summary>
|
||||
ListDirectory,
|
||||
// /// <summary>
|
||||
// /// 列出文件夹权限
|
||||
// /// </summary>
|
||||
// ListDirectory,
|
||||
|
||||
/// <summary>
|
||||
/// 创建文件权限
|
||||
/// </summary>
|
||||
CreateFiles,
|
||||
// /// <summary>
|
||||
// /// 创建文件权限
|
||||
// /// </summary>
|
||||
// CreateFiles,
|
||||
|
||||
/// <summary>
|
||||
/// 创建文件夹权限
|
||||
/// </summary>
|
||||
CreateDirectories,
|
||||
// /// <summary>
|
||||
// /// 创建文件夹权限
|
||||
// /// </summary>
|
||||
// CreateDirectories,
|
||||
|
||||
/// <summary>
|
||||
/// 删除文件权限
|
||||
/// </summary>
|
||||
Delete,
|
||||
// /// <summary>
|
||||
// /// 删除文件权限
|
||||
// /// </summary>
|
||||
// Delete,
|
||||
|
||||
/// <summary>
|
||||
/// 删除文件夹及其子文件
|
||||
/// </summary>
|
||||
DeleteSubdirectoriesAndFiles,
|
||||
}
|
||||
// /// <summary>
|
||||
// /// 删除文件夹及其子文件
|
||||
// /// </summary>
|
||||
// DeleteSubdirectoriesAndFiles,
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// 运行此软件的用户与目标软件的用户最好是 一个用户,一个用户组,或者运行此软件的用户具备最高权限。
|
||||
/// </summary>
|
||||
public class AccessWrapper
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="absolutePath"></param>
|
||||
public static void FreeThisDirAccess(string absolutePath)
|
||||
{
|
||||
if (
|
||||
CheckDirAccess(
|
||||
absolutePath,
|
||||
[
|
||||
DirAcess.Read,
|
||||
DirAcess.Write,
|
||||
DirAcess.Delete,
|
||||
DirAcess.ListDirectory,
|
||||
DirAcess.CreateFiles,
|
||||
DirAcess.CreateDirectories,
|
||||
DirAcess.DeleteSubdirectoriesAndFiles
|
||||
]
|
||||
)
|
||||
) { }
|
||||
else
|
||||
{
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
DirectoryInfo dirInfo = new(absolutePath);
|
||||
//获得该文件的访问权限
|
||||
var dirSecurity = dirInfo.GetAccessControl();
|
||||
//设定文件ACL继承
|
||||
InheritanceFlags inherits =
|
||||
InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit;
|
||||
// /// <summary>
|
||||
// /// 运行此软件的用户与目标软件的用户最好是 一个用户,一个用户组,或者运行此软件的用户具备最高权限。
|
||||
// /// </summary>
|
||||
// public class AccessWrapper
|
||||
// {
|
||||
// /// <summary>
|
||||
// ///
|
||||
// /// </summary>
|
||||
// /// <param name="absolutePath"></param>
|
||||
// public static void FreeThisDirAccess(string absolutePath)
|
||||
// {
|
||||
// if (
|
||||
// CheckDirAccess(
|
||||
// absolutePath,
|
||||
// [
|
||||
// DirAcess.Read,
|
||||
// DirAcess.Write,
|
||||
// DirAcess.Delete,
|
||||
// DirAcess.ListDirectory,
|
||||
// DirAcess.CreateFiles,
|
||||
// DirAcess.CreateDirectories,
|
||||
// DirAcess.DeleteSubdirectoriesAndFiles
|
||||
// ]
|
||||
// )
|
||||
// ) { }
|
||||
// else
|
||||
// {
|
||||
// if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
// {
|
||||
// DirectoryInfo dirInfo = new(absolutePath);
|
||||
// //获得该文件的访问权限
|
||||
// var dirSecurity = dirInfo.GetAccessControl();
|
||||
// //设定文件ACL继承
|
||||
// InheritanceFlags inherits =
|
||||
// InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit;
|
||||
|
||||
var cUser =
|
||||
(
|
||||
WindowsIdentity.GetCurrent().Groups
|
||||
?? throw new Exception("GetWindowsIdentity failed. 你需要手动处理发布内容!--检查权限!")
|
||||
).FirstOrDefault() ?? throw new NullReferenceException("can't be null");
|
||||
FileSystemAccessRule MdfRule =
|
||||
new(
|
||||
cUser,
|
||||
FileSystemRights.Modify,
|
||||
inherits,
|
||||
PropagationFlags.InheritOnly,
|
||||
AccessControlType.Allow
|
||||
);
|
||||
if (dirSecurity.ModifyAccessRule(AccessControlModification.Set, MdfRule, out _)) { }
|
||||
else
|
||||
{
|
||||
throw new Exception("AddAccessRule failed. 你需要手动处理发布内容!--检查权限!");
|
||||
}
|
||||
//设置访问权限
|
||||
dirInfo.SetAccessControl(dirSecurity);
|
||||
}
|
||||
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||
{
|
||||
//TODO Linux文件权限
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotSupportedException(
|
||||
$"{RuntimeInformation.OSDescription} is not supported."
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
// var cUser =
|
||||
// (
|
||||
// WindowsIdentity.GetCurrent().Groups
|
||||
// ?? throw new Exception("GetWindowsIdentity failed. 你需要手动处理发布内容!--检查权限!")
|
||||
// ).FirstOrDefault() ?? throw new NullReferenceException("can't be null");
|
||||
// FileSystemAccessRule MdfRule =
|
||||
// new(
|
||||
// cUser,
|
||||
// FileSystemRights.Modify,
|
||||
// inherits,
|
||||
// PropagationFlags.InheritOnly,
|
||||
// AccessControlType.Allow
|
||||
// );
|
||||
// if (dirSecurity.ModifyAccessRule(AccessControlModification.Set, MdfRule, out _)) { }
|
||||
// else
|
||||
// {
|
||||
// throw new Exception("AddAccessRule failed. 你需要手动处理发布内容!--检查权限!");
|
||||
// }
|
||||
// //设置访问权限
|
||||
// dirInfo.SetAccessControl(dirSecurity);
|
||||
// }
|
||||
// else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||
// {
|
||||
// //TODO Linux文件权限
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// throw new NotSupportedException(
|
||||
// $"{RuntimeInformation.OSDescription} is not supported."
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
public static void FreeThisFileAccess(string absolutePath)
|
||||
{
|
||||
if (
|
||||
CheckFileAccess(
|
||||
absolutePath,
|
||||
[FileAccess.Read, FileAccess.Write, FileAccess.Delete, FileAccess.Execute]
|
||||
)
|
||||
) { }
|
||||
else
|
||||
{
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
FileInfo fileInfo = new(absolutePath);
|
||||
//获得该文件的访问权限
|
||||
FileSecurity fileSecurity = fileInfo.GetAccessControl();
|
||||
// public static void FreeThisFileAccess(string absolutePath)
|
||||
// {
|
||||
// if (
|
||||
// CheckFileAccess(
|
||||
// absolutePath,
|
||||
// [FileAccess.Read, FileAccess.Write, FileAccess.Delete, FileAccess.Execute]
|
||||
// )
|
||||
// ) { }
|
||||
// else
|
||||
// {
|
||||
// if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
// {
|
||||
// FileInfo fileInfo = new(absolutePath);
|
||||
// //获得该文件的访问权限
|
||||
// FileSecurity fileSecurity = fileInfo.GetAccessControl();
|
||||
|
||||
var cUser =
|
||||
(
|
||||
WindowsIdentity.GetCurrent().Groups
|
||||
?? throw new NullReferenceException(
|
||||
"GetWindowsIdentity failed. 你需要手动处理发布内容!-- 检查权限"
|
||||
)
|
||||
).FirstOrDefault() ?? throw new NullReferenceException("can't be null");
|
||||
FileSystemAccessRule MdfRule =
|
||||
new(cUser, FileSystemRights.Modify, AccessControlType.Allow);
|
||||
if (fileSecurity.ModifyAccessRule(AccessControlModification.Set, MdfRule, out _))
|
||||
{ }
|
||||
else
|
||||
{
|
||||
throw new Exception("AddAccessRule failed. 你需要手动处理发布内容!--检查权限");
|
||||
}
|
||||
}
|
||||
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||
{
|
||||
//TODO Linux文件权限
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotSupportedException(
|
||||
$"{RuntimeInformation.OSDescription} is not supported."
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
// var cUser =
|
||||
// (
|
||||
// WindowsIdentity.GetCurrent().Groups
|
||||
// ?? throw new NullReferenceException(
|
||||
// "GetWindowsIdentity failed. 你需要手动处理发布内容!-- 检查权限"
|
||||
// )
|
||||
// ).FirstOrDefault() ?? throw new NullReferenceException("can't be null");
|
||||
// FileSystemAccessRule MdfRule =
|
||||
// new(cUser, FileSystemRights.Modify, AccessControlType.Allow);
|
||||
// if (fileSecurity.ModifyAccessRule(AccessControlModification.Set, MdfRule, out _))
|
||||
// { }
|
||||
// else
|
||||
// {
|
||||
// throw new Exception("AddAccessRule failed. 你需要手动处理发布内容!--检查权限");
|
||||
// }
|
||||
// }
|
||||
// else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||
// {
|
||||
// //TODO Linux文件权限
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// throw new NotSupportedException(
|
||||
// $"{RuntimeInformation.OSDescription} is not supported."
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
public static bool CheckDirAccess(string absolutePath, DirAcess[] access)
|
||||
{
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
DirectoryInfo dirInfo = new(absolutePath);
|
||||
//获得该文件的访问权限
|
||||
var dirSecurity = dirInfo.GetAccessControl();
|
||||
var ac = dirSecurity
|
||||
.GetAccessRules(true, true, typeof(System.Security.Principal.SecurityIdentifier))
|
||||
.Cast<FileSystemAccessRule>();
|
||||
#pragma warning disable CA1416 // Validate platform compatibility
|
||||
var it =
|
||||
from i in ac
|
||||
where
|
||||
(
|
||||
WindowsIdentity.GetCurrent().Groups
|
||||
?? throw new NullReferenceException("未能获取当前用户组!")
|
||||
).Contains(i.IdentityReference)
|
||||
select i;
|
||||
#pragma warning restore CA1416 // Validate platform compatibility
|
||||
List<DirAcess> caccess = [];
|
||||
foreach (var i in it)
|
||||
{
|
||||
if (i.FileSystemRights.HasFlag(FileSystemRights.FullControl))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (
|
||||
i.FileSystemRights.HasFlag(
|
||||
FileSystemRights.Read
|
||||
| FileSystemRights.Modify
|
||||
| FileSystemRights.ReadAndExecute
|
||||
)
|
||||
)
|
||||
{
|
||||
caccess.Add(DirAcess.Read);
|
||||
}
|
||||
if (i.FileSystemRights.HasFlag(FileSystemRights.Write | FileSystemRights.Modify))
|
||||
{
|
||||
caccess.Add(DirAcess.Write);
|
||||
}
|
||||
if (i.FileSystemRights.HasFlag(FileSystemRights.Modify | FileSystemRights.Delete))
|
||||
{
|
||||
caccess.Add(DirAcess.Delete);
|
||||
}
|
||||
if (
|
||||
i.FileSystemRights.HasFlag(
|
||||
FileSystemRights.ListDirectory | FileSystemRights.Modify
|
||||
)
|
||||
)
|
||||
{
|
||||
caccess.Add(DirAcess.ListDirectory);
|
||||
}
|
||||
if (
|
||||
i.FileSystemRights.HasFlag(
|
||||
FileSystemRights.CreateFiles | FileSystemRights.Modify
|
||||
)
|
||||
)
|
||||
{
|
||||
caccess.Add(DirAcess.CreateFiles);
|
||||
}
|
||||
if (
|
||||
i.FileSystemRights.HasFlag(
|
||||
FileSystemRights.CreateDirectories | FileSystemRights.Modify
|
||||
)
|
||||
)
|
||||
{
|
||||
caccess.Add(DirAcess.CreateDirectories);
|
||||
}
|
||||
if (
|
||||
i.FileSystemRights.HasFlag(
|
||||
FileSystemRights.DeleteSubdirectoriesAndFiles | FileSystemRights.Modify
|
||||
)
|
||||
)
|
||||
{
|
||||
caccess.Add(DirAcess.DeleteSubdirectoriesAndFiles);
|
||||
}
|
||||
}
|
||||
foreach (var i in access)
|
||||
{
|
||||
if (!caccess.Contains(i))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||
{
|
||||
//TODO Linux文件权限
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotSupportedException(
|
||||
$"{RuntimeInformation.OSDescription} is not supported."
|
||||
);
|
||||
}
|
||||
}
|
||||
// public static bool CheckDirAccess(string absolutePath, DirAcess[] access)
|
||||
// {
|
||||
// if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
// {
|
||||
// DirectoryInfo dirInfo = new(absolutePath);
|
||||
// //获得该文件的访问权限
|
||||
// var dirSecurity = dirInfo.GetAccessControl();
|
||||
// var ac = dirSecurity
|
||||
// .GetAccessRules(true, true, typeof(System.Security.Principal.SecurityIdentifier))
|
||||
// .Cast<FileSystemAccessRule>();
|
||||
// #pragma warning disable CA1416 // Validate platform compatibility
|
||||
// var it =
|
||||
// from i in ac
|
||||
// where
|
||||
// (
|
||||
// WindowsIdentity.GetCurrent().Groups
|
||||
// ?? throw new NullReferenceException("未能获取当前用户组!")
|
||||
// ).Contains(i.IdentityReference)
|
||||
// select i;
|
||||
// #pragma warning restore CA1416 // Validate platform compatibility
|
||||
// List<DirAcess> caccess = [];
|
||||
// foreach (var i in it)
|
||||
// {
|
||||
// if (i.FileSystemRights.HasFlag(FileSystemRights.FullControl))
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
// if (
|
||||
// i.FileSystemRights.HasFlag(
|
||||
// FileSystemRights.Read
|
||||
// | FileSystemRights.Modify
|
||||
// | FileSystemRights.ReadAndExecute
|
||||
// )
|
||||
// )
|
||||
// {
|
||||
// caccess.Add(DirAcess.Read);
|
||||
// }
|
||||
// if (i.FileSystemRights.HasFlag(FileSystemRights.Write | FileSystemRights.Modify))
|
||||
// {
|
||||
// caccess.Add(DirAcess.Write);
|
||||
// }
|
||||
// if (i.FileSystemRights.HasFlag(FileSystemRights.Modify | FileSystemRights.Delete))
|
||||
// {
|
||||
// caccess.Add(DirAcess.Delete);
|
||||
// }
|
||||
// if (
|
||||
// i.FileSystemRights.HasFlag(
|
||||
// FileSystemRights.ListDirectory | FileSystemRights.Modify
|
||||
// )
|
||||
// )
|
||||
// {
|
||||
// caccess.Add(DirAcess.ListDirectory);
|
||||
// }
|
||||
// if (
|
||||
// i.FileSystemRights.HasFlag(
|
||||
// FileSystemRights.CreateFiles | FileSystemRights.Modify
|
||||
// )
|
||||
// )
|
||||
// {
|
||||
// caccess.Add(DirAcess.CreateFiles);
|
||||
// }
|
||||
// if (
|
||||
// i.FileSystemRights.HasFlag(
|
||||
// FileSystemRights.CreateDirectories | FileSystemRights.Modify
|
||||
// )
|
||||
// )
|
||||
// {
|
||||
// caccess.Add(DirAcess.CreateDirectories);
|
||||
// }
|
||||
// if (
|
||||
// i.FileSystemRights.HasFlag(
|
||||
// FileSystemRights.DeleteSubdirectoriesAndFiles | FileSystemRights.Modify
|
||||
// )
|
||||
// )
|
||||
// {
|
||||
// caccess.Add(DirAcess.DeleteSubdirectoriesAndFiles);
|
||||
// }
|
||||
// }
|
||||
// foreach (var i in access)
|
||||
// {
|
||||
// if (!caccess.Contains(i))
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
// else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||
// {
|
||||
// //TODO Linux文件权限
|
||||
// return true;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// throw new NotSupportedException(
|
||||
// $"{RuntimeInformation.OSDescription} is not supported."
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
||||
public static bool CheckFileAccess(string absolutePath, FileAccess[] access)
|
||||
{
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
FileInfo fileInfo = new(absolutePath);
|
||||
//获得该文件的访问权限
|
||||
FileSecurity fileSecurity = fileInfo.GetAccessControl();
|
||||
// public static bool CheckFileAccess(string absolutePath, FileAccess[] access)
|
||||
// {
|
||||
// if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
// {
|
||||
// FileInfo fileInfo = new(absolutePath);
|
||||
// //获得该文件的访问权限
|
||||
// FileSecurity fileSecurity = fileInfo.GetAccessControl();
|
||||
|
||||
var ac = fileSecurity
|
||||
.GetAccessRules(true, true, typeof(System.Security.Principal.SecurityIdentifier))
|
||||
.Cast<FileSystemAccessRule>();
|
||||
#pragma warning disable CA1416 // 验证平台兼容性
|
||||
var it =
|
||||
from i in ac
|
||||
where
|
||||
(
|
||||
WindowsIdentity.GetCurrent().Groups
|
||||
?? throw new NullReferenceException("未能获取当前用户组!")
|
||||
).Contains(i.IdentityReference)
|
||||
select i;
|
||||
#pragma warning restore CA1416 // 验证平台兼容性
|
||||
// var ac = fileSecurity
|
||||
// .GetAccessRules(true, true, typeof(System.Security.Principal.SecurityIdentifier))
|
||||
// .Cast<FileSystemAccessRule>();
|
||||
// #pragma warning disable CA1416 // 验证平台兼容性
|
||||
// var it =
|
||||
// from i in ac
|
||||
// where
|
||||
// (
|
||||
// WindowsIdentity.GetCurrent().Groups
|
||||
// ?? throw new NullReferenceException("未能获取当前用户组!")
|
||||
// ).Contains(i.IdentityReference)
|
||||
// select i;
|
||||
// #pragma warning restore CA1416 // 验证平台兼容性
|
||||
|
||||
List<FileAccess> caccess = [];
|
||||
foreach (var i in it)
|
||||
{
|
||||
if (i.FileSystemRights.HasFlag(FileSystemRights.FullControl))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (i.FileSystemRights.HasFlag(FileSystemRights.Read | FileSystemRights.Modify))
|
||||
{
|
||||
caccess.Add(FileAccess.Read);
|
||||
}
|
||||
if (i.FileSystemRights.HasFlag(FileSystemRights.Write | FileSystemRights.Modify))
|
||||
{
|
||||
caccess.Add(FileAccess.Write);
|
||||
}
|
||||
if (i.FileSystemRights.HasFlag(FileSystemRights.Write | FileSystemRights.Modify))
|
||||
{
|
||||
caccess.Add(FileAccess.Delete);
|
||||
}
|
||||
if (
|
||||
i.FileSystemRights.HasFlag(
|
||||
FileSystemRights.ExecuteFile | FileSystemRights.Modify
|
||||
)
|
||||
)
|
||||
{
|
||||
caccess.Add(FileAccess.Execute);
|
||||
}
|
||||
}
|
||||
foreach (var i in access)
|
||||
{
|
||||
if (!caccess.Contains(i))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||
{
|
||||
//TODO Linux文件夹权限
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotSupportedException(
|
||||
$"{RuntimeInformation.OSDescription} is not supported."
|
||||
);
|
||||
}
|
||||
}
|
||||
// List<FileAccess> caccess = [];
|
||||
// foreach (var i in it)
|
||||
// {
|
||||
// if (i.FileSystemRights.HasFlag(FileSystemRights.FullControl))
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
// if (i.FileSystemRights.HasFlag(FileSystemRights.Read | FileSystemRights.Modify))
|
||||
// {
|
||||
// caccess.Add(FileAccess.Read);
|
||||
// }
|
||||
// if (i.FileSystemRights.HasFlag(FileSystemRights.Write | FileSystemRights.Modify))
|
||||
// {
|
||||
// caccess.Add(FileAccess.Write);
|
||||
// }
|
||||
// if (i.FileSystemRights.HasFlag(FileSystemRights.Write | FileSystemRights.Modify))
|
||||
// {
|
||||
// caccess.Add(FileAccess.Delete);
|
||||
// }
|
||||
// if (
|
||||
// i.FileSystemRights.HasFlag(
|
||||
// FileSystemRights.ExecuteFile | FileSystemRights.Modify
|
||||
// )
|
||||
// )
|
||||
// {
|
||||
// caccess.Add(FileAccess.Execute);
|
||||
// }
|
||||
// }
|
||||
// foreach (var i in access)
|
||||
// {
|
||||
// if (!caccess.Contains(i))
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
// else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||
// {
|
||||
// //TODO Linux文件夹权限
|
||||
// return true;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// throw new NotSupportedException(
|
||||
// $"{RuntimeInformation.OSDescription} is not supported."
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前用户
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="NotSupportedException"></exception>
|
||||
// /// <summary>
|
||||
// /// 获取当前用户
|
||||
// /// </summary>
|
||||
// /// <returns></returns>
|
||||
// /// <exception cref="NotSupportedException"></exception>
|
||||
|
||||
public static string GetCurrentUser()
|
||||
{
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
return System.Security.Principal.WindowsIdentity.GetCurrent().Name;
|
||||
}
|
||||
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||
{
|
||||
return Environment.UserName;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotSupportedException(
|
||||
$"{RuntimeInformation.OSDescription} is not supported."
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
// public static string GetCurrentUser()
|
||||
// {
|
||||
// if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
// {
|
||||
// return System.Security.Principal.WindowsIdentity.GetCurrent().Name;
|
||||
// }
|
||||
// else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||
// {
|
||||
// return Environment.UserName;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// throw new NotSupportedException(
|
||||
// $"{RuntimeInformation.OSDescription} is not supported."
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
|
|
@ -10,36 +10,11 @@ namespace LocalServer.Controllers
|
|||
{
|
||||
private readonly LocalSyncServerFactory Factory = factory;
|
||||
|
||||
private static async Task Echo(WebSocket webSocket)
|
||||
{
|
||||
var buffer = new byte[1024 * 4];
|
||||
var receiveResult = await webSocket.ReceiveAsync(
|
||||
new ArraySegment<byte>(buffer),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
while (!receiveResult.CloseStatus.HasValue)
|
||||
{
|
||||
await webSocket.SendAsync(
|
||||
new ArraySegment<byte>(buffer, 0, receiveResult.Count),
|
||||
receiveResult.MessageType,
|
||||
receiveResult.EndOfMessage,
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
receiveResult = await webSocket.ReceiveAsync(
|
||||
new ArraySegment<byte>(buffer),
|
||||
CancellationToken.None
|
||||
);
|
||||
}
|
||||
|
||||
await webSocket.CloseAsync(
|
||||
receiveResult.CloseStatus.Value,
|
||||
receiveResult.CloseStatusDescription,
|
||||
CancellationToken.None
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// websoc 连接入口
|
||||
/// </summary>
|
||||
/// <param name="Name"></param>
|
||||
/// <returns></returns>
|
||||
[Route("/websoc")]
|
||||
public async Task WebsocketConnection(string Name)
|
||||
{
|
||||
|
@ -50,8 +25,8 @@ namespace LocalServer.Controllers
|
|||
if (Factory.GetServerByName(Name) == null)
|
||||
{
|
||||
var webSocket = await HttpContext.WebSockets.AcceptWebSocketAsync();
|
||||
//await Echo(webSocket);
|
||||
var pipeLine = new WebSocPipeLine<WebSocket>(webSocket, false);
|
||||
//必须在此保留连接的上下文,否则 websocket 就直接断了。。。微软 这个设计措不及防
|
||||
await Factory.CreateLocalSyncServer(
|
||||
pipeLine,
|
||||
Name,
|
||||
|
@ -75,18 +50,18 @@ namespace LocalServer.Controllers
|
|||
}
|
||||
}
|
||||
|
||||
[Route("/macaddr")]
|
||||
public string GetMacAddress()
|
||||
{
|
||||
NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
|
||||
string macaddrs = "";
|
||||
foreach (NetworkInterface nic in nics)
|
||||
{
|
||||
PhysicalAddress physicalAddress = nic.GetPhysicalAddress();
|
||||
macaddrs += physicalAddress.ToString() + ";";
|
||||
}
|
||||
return macaddrs;
|
||||
}
|
||||
//TODO 是否在本地记载同步日志?
|
||||
// [Route("/macaddr")]
|
||||
// public string GetMacAddress()
|
||||
// {
|
||||
// NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
|
||||
// string macaddrs = "";
|
||||
// foreach (NetworkInterface nic in nics)
|
||||
// {
|
||||
// PhysicalAddress physicalAddress = nic.GetPhysicalAddress();
|
||||
// macaddrs += physicalAddress.ToString() + ";";
|
||||
// }
|
||||
// return macaddrs;
|
||||
// }
|
||||
// //TODO 是否在本地记载同步日志?
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,63 +8,76 @@ public class LocalSyncServer
|
|||
#pragma warning disable CA2211 // Non-constant fields should not be visible
|
||||
public static string TempRootFile = "C:/TempPack";
|
||||
public static string SqlPackageAbPath = "sqlpackage";
|
||||
|
||||
// 使用msdeploy 将会打包当前可运行的内容,它很有可能不包含最新的构建
|
||||
//public static string MsdeployAbPath = "msdeploy";
|
||||
|
||||
//与visual studio 匹配的Msbuild 路径。在vs 中打开power shell 命令行,使用 `(get-Command -Name msbuild).Source `
|
||||
//使用msbuild 会缺少.net frame的运行环境 bin\roslyn 里面的内容,第一次需要人为复制一下,后面就就好了。
|
||||
public static string MSBuildAbPath = "MSBuild";
|
||||
#pragma warning restore CA2211 // Non-constant fields should not be visible
|
||||
|
||||
/// <summary>
|
||||
/// 连接状态,流程管理,LocalPipe 和 remotePipe 也在此处交换信息
|
||||
/// </summary>
|
||||
private StateHelpBase StateHelper;
|
||||
|
||||
|
||||
public void SetStateHelper(StateHelpBase helper)
|
||||
{
|
||||
StateHelper = helper;
|
||||
}
|
||||
|
||||
public static string GetProjectOutPath(string project)
|
||||
{
|
||||
try
|
||||
{
|
||||
XDocument xdoc = XDocument.Load(project);
|
||||
// 获取根元素
|
||||
XElement rootElement = xdoc.Root ?? throw new NullReferenceException("Root");
|
||||
Console.WriteLine("根元素: " + rootElement.Name);
|
||||
/// <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");
|
||||
// // 遍历子节点
|
||||
// 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/";
|
||||
}
|
||||
}
|
||||
// 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/";
|
||||
// }
|
||||
// }
|
||||
|
||||
public StateHelpBase GetStateHelper()
|
||||
{
|
||||
return StateHelper;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 此次发布的配置
|
||||
/// </summary>
|
||||
public Config? SyncConfig;
|
||||
|
||||
public Config NotNullSyncConfig
|
||||
|
@ -79,13 +92,19 @@ public class LocalSyncServer
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发布的名称
|
||||
/// </summary>
|
||||
public string Name;
|
||||
|
||||
/// <summary>
|
||||
/// 发布源连接
|
||||
/// jswebsocket 和 local server 的连接,它没有加密
|
||||
/// </summary>
|
||||
public readonly AbsPipeLine LocalPipe;
|
||||
|
||||
/// <summary>
|
||||
/// local server 和 remote server 的连接,它有加密
|
||||
/// </summary>
|
||||
public readonly AbsPipeLine RemotePipe;
|
||||
|
||||
/// <summary>
|
||||
|
@ -107,6 +126,10 @@ public class LocalSyncServer
|
|||
RemotePipe = remotePipe;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 这个阻塞在,接口中有http上下文处
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task Connect()
|
||||
{
|
||||
try
|
||||
|
@ -125,6 +148,10 @@ public class LocalSyncServer
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 关闭连接
|
||||
/// </summary>
|
||||
/// <param name="CloseReason"></param>
|
||||
public void Close(string? CloseReason)
|
||||
{
|
||||
try
|
||||
|
|
|
@ -2,19 +2,10 @@ using System.Diagnostics;
|
|||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using Common;
|
||||
|
||||
namespace LocalServer;
|
||||
|
||||
// enum StateWhenMsg
|
||||
// {
|
||||
// Authority = 0,
|
||||
// ConfigInfo = 1,
|
||||
// LocalPackAndUpload = 2,
|
||||
// RemoteUnPackAndRelease = 3,
|
||||
// }
|
||||
|
||||
public abstract class StateHelpBase(
|
||||
LocalSyncServer context,
|
||||
SyncProcessStep step = SyncProcessStep.Connect
|
||||
|
@ -147,18 +138,11 @@ public class DeployHelper(LocalSyncServer context)
|
|||
h.DiffProcess();
|
||||
}
|
||||
else
|
||||
{
|
||||
{ // msbuild 只在windows 才有
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
//构建
|
||||
|
||||
//var OutputPath = LocalSyncServer.GetProjectOutPath(
|
||||
// Context.NotNullSyncConfig.LocalProjectAbsolutePath
|
||||
//);
|
||||
//var AbOutPath = Path.Combine(
|
||||
// Context.NotNullSyncConfig.LocalProjectAbsolutePath,
|
||||
// OutputPath
|
||||
//);
|
||||
ProcessStartInfo startbuildInfo =
|
||||
new()
|
||||
{
|
||||
|
@ -334,59 +318,52 @@ public class DeployMSSqlHelper(LocalSyncServer context)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
var arguments =
|
||||
$" /Action:Extract /TargetFile:{LocalSyncServer.TempRootFile}/{Context.NotNullSyncConfig.Id.ToString()}/{Context.NotNullSyncConfig.Id.ToString()}.dacpac"
|
||||
// 不要log file 了
|
||||
//+ $" /DiagnosticsFile:{LocalSyncServer.TempRootFile}/{Context.NotNullSyncConfig.Id.ToString()}/{Context.NotNullSyncConfig.Id.ToString()}.log"
|
||||
+ $" /p:ExtractAllTableData=false /p:VerifyExtraction=true /SourceServerName:{Context.NotNullSyncConfig.SrcDb.ServerName}"
|
||||
+ $" /SourceDatabaseName:{Context.NotNullSyncConfig.SrcDb.DatebaseName} /SourceUser:{Context.NotNullSyncConfig.SrcDb.User}"
|
||||
+ $" /SourcePassword:{Context.NotNullSyncConfig.SrcDb.Password} /SourceTrustServerCertificate:{Context.NotNullSyncConfig.SrcDb.TrustServerCertificate}"
|
||||
+ $" /p:ExtractReferencedServerScopedElements=False /p:IgnoreUserLoginMappings=True /p:IgnorePermissions=True";
|
||||
if (Context.NotNullSyncConfig.SrcDb.SyncTablesData != null)
|
||||
{
|
||||
var arguments =
|
||||
$" /Action:Extract /TargetFile:{LocalSyncServer.TempRootFile}/{Context.NotNullSyncConfig.Id.ToString()}/{Context.NotNullSyncConfig.Id.ToString()}.dacpac"
|
||||
// 不要log file 了
|
||||
//+ $" /DiagnosticsFile:{LocalSyncServer.TempRootFile}/{Context.NotNullSyncConfig.Id.ToString()}/{Context.NotNullSyncConfig.Id.ToString()}.log"
|
||||
+ $" /p:ExtractAllTableData=false /p:VerifyExtraction=true /SourceServerName:{Context.NotNullSyncConfig.SrcDb.ServerName}"
|
||||
+ $" /SourceDatabaseName:{Context.NotNullSyncConfig.SrcDb.DatebaseName} /SourceUser:{Context.NotNullSyncConfig.SrcDb.User}"
|
||||
+ $" /SourcePassword:{Context.NotNullSyncConfig.SrcDb.Password} /SourceTrustServerCertificate:{Context.NotNullSyncConfig.SrcDb.TrustServerCertificate}"
|
||||
+ $" /p:ExtractReferencedServerScopedElements=False /p:IgnoreUserLoginMappings=True /p:IgnorePermissions=True";
|
||||
if (Context.NotNullSyncConfig.SrcDb.SyncTablesData != null)
|
||||
foreach (var t in Context.NotNullSyncConfig.SrcDb.SyncTablesData)
|
||||
{
|
||||
foreach (var t in Context.NotNullSyncConfig.SrcDb.SyncTablesData)
|
||||
{
|
||||
arguments += $" /p:TableData={t}";
|
||||
}
|
||||
arguments += $" /p:TableData={t}";
|
||||
}
|
||||
}
|
||||
|
||||
ProcessStartInfo startInfo =
|
||||
new()
|
||||
{
|
||||
FileName = LocalSyncServer.SqlPackageAbPath, // The command to execute (can be any command line tool)
|
||||
Arguments = arguments,
|
||||
StandardOutputEncoding = System.Text.Encoding.UTF8,
|
||||
// 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)
|
||||
ProcessStartInfo startInfo =
|
||||
new()
|
||||
{
|
||||
Context.LocalPipe.SendMsg(CreateMsg("数据库打包成功!")).Wait();
|
||||
PackAndSwitchNext();
|
||||
}
|
||||
else
|
||||
{
|
||||
Context.LocalPipe.SendMsg(CreateErrMsg(output)).Wait();
|
||||
throw new Exception("执行发布错误,错误信息参考上一条消息!");
|
||||
}
|
||||
FileName = LocalSyncServer.SqlPackageAbPath, // The command to execute (can be any command line tool)
|
||||
Arguments = arguments,
|
||||
StandardOutputEncoding = System.Text.Encoding.UTF8,
|
||||
// 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)
|
||||
{
|
||||
Context.LocalPipe.SendMsg(CreateMsg("数据库打包成功!")).Wait();
|
||||
PackAndSwitchNext();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotSupportedException("只支持windows!");
|
||||
Context.LocalPipe.SendMsg(CreateErrMsg(output)).Wait();
|
||||
throw new Exception("执行发布错误,错误信息参考上一条消息!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -410,6 +387,7 @@ public class UploadPackedHelper(LocalSyncServer context)
|
|||
$"{LocalSyncServer.TempRootFile}/{Context.NotNullSyncConfig.Id}.zip",
|
||||
(double current) =>
|
||||
{
|
||||
//这里可能需要降低获取上传进度的频率
|
||||
Context
|
||||
.LocalPipe.SendMsg(CreateMsg(current.ToString(), SyncMsgType.Process))
|
||||
.Wait();
|
||||
|
@ -449,223 +427,4 @@ public class FinallyPublishHelper(LocalSyncServer context)
|
|||
{
|
||||
Context.LocalPipe.SendMsg(msg).Wait();
|
||||
}
|
||||
}
|
||||
// /// <summary>
|
||||
// /// 0. 发布源验证密码
|
||||
// /// </summary>
|
||||
// /// <param name="context"></param>
|
||||
// public class LocalAuthorityState(LocalSyncServer context) : StateHelpBase(context)
|
||||
// {
|
||||
// public override void HandleRemoteMsg(SyncMsg? msg)
|
||||
// {
|
||||
// throw new NotImplementedException("error usage!");
|
||||
// }
|
||||
|
||||
// public override void HandleLocalMsg(SyncMsg? msg)
|
||||
// {
|
||||
// if (msg == null)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// string Pwd = msg.Body;
|
||||
// if (Pwd == "Xfs1%$@_fdYU.>>")
|
||||
// {
|
||||
// Context.LocalSocketSendMsg(new SyncMsg(SyncMsgType.Success, "源服务密码校验成功!"));
|
||||
// Context.StateHelper = new WaitingConfigInfoState(Context);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// throw new UnauthorizedAccessException("pwd error!");
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// 1. 获取配置信息,它包含目标的服务器的配置信息
|
||||
// /// </summary>
|
||||
// /// <param name="context"></param>
|
||||
// public class WaitingConfigInfoState(LocalSyncServer context) : StateHelpBase(context)
|
||||
// {
|
||||
// public override void HandleRemoteMsg(SyncMsg? msg) { }
|
||||
|
||||
// public override void HandleLocalMsg(SyncMsg? msg)
|
||||
// {
|
||||
// if (msg == null)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// string ConfigInfo = msg.Body;
|
||||
// Context.SyncConfig =
|
||||
// JsonSerializer.Deserialize<Config>(ConfigInfo)
|
||||
// ?? throw new NullReferenceException("ConfigInfo is null");
|
||||
// var task = Context.RemoteSocket.ConnectAsync(
|
||||
// new Uri(Context.SyncConfig.RemoteUrl),
|
||||
// CancellationToken.None
|
||||
// );
|
||||
// if (task.Wait(10000))
|
||||
// {
|
||||
// if (Context.RemoteSocket.State == WebSocketState.Open)
|
||||
// {
|
||||
// var state = new RemoteAuthorityState(Context);
|
||||
// state.SendPwdToRemoteServer();
|
||||
// Context.StateHelper = state;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// throw new Exception("connect remote server failed!");
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// throw new TimeoutException("connect remote server timeout");
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// 2. 目标服务器权限校验
|
||||
// /// </summary>
|
||||
// /// <param name="context"></param>
|
||||
// public class RemoteAuthorityState(LocalSyncServer context) : StateHelpBase(context)
|
||||
// {
|
||||
// public override void HandleRemoteMsg(SyncMsg? msg)
|
||||
// {
|
||||
// if (msg == null)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// if (msg.Type == SyncMsgType.Success)
|
||||
// {
|
||||
// Context.LocalSocketSendMsg(new SyncMsg(SyncMsgType.Success, "远程服务器校验成功!"));
|
||||
// var diffState = new DirFilesDiffState(Context);
|
||||
// diffState.SendSyncConfigToRemote();
|
||||
// Context.StateHelper = diffState;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// throw new Exception("远程服务器权限校验失败,请检查Local Server 的Mac地址是否在 Remote Server 的允许列表内!");
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// public override void HandleLocalMsg(SyncMsg? msg) { }
|
||||
|
||||
// public void SendPwdToRemoteServer()
|
||||
// {
|
||||
// var authorityInfo = new
|
||||
// {
|
||||
// Pwd = "xfs@#123hd??1>>|12#4",
|
||||
// MacAdr = new LocalServer.Controllers.LocalServerController(
|
||||
// Context.Factory
|
||||
// ).GetMacAddress()
|
||||
// };
|
||||
// Context.RemoteSocketSendMsg(authorityInfo);
|
||||
// }
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// 3. 文件比较
|
||||
// /// </summary>
|
||||
// /// <param name="context"></param>
|
||||
// public class DirFilesDiffState(LocalSyncServer context) : StateHelpBase(context)
|
||||
// {
|
||||
// public override void HandleRemoteMsg(SyncMsg? msg)
|
||||
// {
|
||||
// if (msg == null)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// if (msg.IsSuccess)
|
||||
// {
|
||||
// var state = new LocalPackAndUploadState(Context);
|
||||
// state.PackDiffDir(msg);
|
||||
// Context.StateHelper = state;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// throw new Exception(msg.Body);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// public override void HandleLocalMsg(SyncMsg? msg) { }
|
||||
|
||||
// public void SendSyncConfigToRemote()
|
||||
// {
|
||||
// Context.RemoteSocketSendMsg(
|
||||
// Context.SyncConfig
|
||||
// ?? throw new NullReferenceException("SyncConfig should't be null here!")
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// 4. 本地打包并上传
|
||||
// /// </summary>
|
||||
// /// <param name="context"></param>
|
||||
// public class LocalPackAndUploadState(LocalSyncServer context) : StateHelpBase(context)
|
||||
// {
|
||||
// public override void HandleRemoteMsg(SyncMsg? msg)
|
||||
// {
|
||||
// if (msg == null)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
// else { }
|
||||
// }
|
||||
|
||||
// public override void HandleLocalMsg(SyncMsg? msg) { }
|
||||
|
||||
// /// <summary>
|
||||
// /// 打包文件
|
||||
// /// </summary>
|
||||
// /// <param name="msg"></param>
|
||||
// /// <exception cref="Exception"></exception>
|
||||
// public void PackDiffDir(SyncMsg msg)
|
||||
// {
|
||||
// if (msg.IsSuccess)
|
||||
// {
|
||||
// var diff = JsonSerializer.Deserialize<Dir>(msg.Body);
|
||||
|
||||
// Context.LocalSocketSendMsg(new SyncMsg(SyncMsgType.Success, "文件打包完成!"));
|
||||
// Context.LocalSocketSendMsg(new SyncMsg(SyncMsgType.Success, "文件上传完成!"));
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// throw new Exception(msg.Body);
|
||||
// }
|
||||
// }
|
||||
|
||||
// private void UploadPackedFiles(string absolutePath)
|
||||
// {
|
||||
// //TODO 传递上传进度到前端。
|
||||
// }
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// 5. 目标服务器解包并发布
|
||||
// /// </summary>
|
||||
// /// <param name="context"></param>
|
||||
// public class RemoteUnPackAndReleaseState(LocalSyncServer context) : StateHelpBase(context)
|
||||
// {
|
||||
// public override void HandleRemoteMsg(SyncMsg? msg)
|
||||
// {
|
||||
// if (msg == null)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
// else { }
|
||||
// }
|
||||
|
||||
// public override void HandleLocalMsg(SyncMsg? msg) { }
|
||||
// }
|
||||
}
|
|
@ -24,8 +24,6 @@ public class SyncFilesController(RemoteSyncServerFactory factory, SqliteDbContex
|
|||
var webSocket = await HttpContext.WebSockets.AcceptWebSocketAsync();
|
||||
var pipeLine = new WebSocPipeLine<WebSocket>(webSocket, true);
|
||||
await Factory.CreateRemoteSyncServer(pipeLine, Name);
|
||||
|
||||
var x = 11;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -43,127 +41,11 @@ public class SyncFilesController(RemoteSyncServerFactory factory, SqliteDbContex
|
|||
HttpContext.Response.StatusCode = StatusCodes.Status400BadRequest;
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet("/GetSyncFilesLogs")]
|
||||
public IActionResult GetSyncFilesLogs(
|
||||
string? ClientName,
|
||||
int? Status,
|
||||
DateTime? SyncTimeStart,
|
||||
DateTime? SyncTimeEnd,
|
||||
int page,
|
||||
int rows
|
||||
)
|
||||
{
|
||||
var item =
|
||||
from i in _db.SyncLogHeads
|
||||
where
|
||||
(
|
||||
string.IsNullOrEmpty(ClientName)
|
||||
|| (i.ClientName != null && i.ClientName.Contains(ClientName))
|
||||
)
|
||||
&& (Status == null || i.Status == Status)
|
||||
&& (SyncTimeStart == null || i.SyncTime >= SyncTimeStart)
|
||||
&& (SyncTimeEnd == null || i.SyncTime <= SyncTimeEnd)
|
||||
orderby i.Id descending
|
||||
select new
|
||||
{
|
||||
Head = i,
|
||||
Files = (from j in _db.SyncLogFiles where j.HeadId == i.Id select j).ToList()
|
||||
};
|
||||
|
||||
return Ok(item.Skip((page - 1) * rows).Take(rows).ToList());
|
||||
}
|
||||
|
||||
public class InputFileInfo
|
||||
{
|
||||
public required string RelativePath { get; set; }
|
||||
public DateTime MTime { get; set; }
|
||||
}
|
||||
|
||||
public class OutputFileInfo : InputFileInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 0 新增 1 修改 2 删除
|
||||
/// </summary>
|
||||
public int ServerOpType { get; set; }
|
||||
}
|
||||
|
||||
public class ServerOpFileInfo : OutputFileInfo
|
||||
{
|
||||
public required string ServerRootDirPath { get; set; }
|
||||
public required string ClientRootDirPath { get; set; }
|
||||
}
|
||||
|
||||
public class InputFiles
|
||||
{
|
||||
public required string ServerRootDirPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 0 special 1 exclude
|
||||
/// </summary>
|
||||
public int Type { get; set; }
|
||||
public List<FileInfo>? Files { get; set; }
|
||||
}
|
||||
|
||||
public class ServerOpFiles
|
||||
{
|
||||
public required string ServerRootDirPath { get; set; }
|
||||
public string? ClientRootDirPath { get; set; }
|
||||
public List<OutputFileInfo>? Files { get; set; }
|
||||
}
|
||||
|
||||
[HttpPost("/GetFilesInfoByDir")]
|
||||
public IActionResult GetFilesInfoByDir([FromBody] InputFiles inputFiles)
|
||||
{
|
||||
return Ok(new { IsSuccess = true });
|
||||
}
|
||||
|
||||
[HttpPost("/InitASync")]
|
||||
public IActionResult InitASync([FromBody] SyncLogHead head)
|
||||
{
|
||||
try
|
||||
{
|
||||
var CurrentSyncTaskCount = (
|
||||
from i in _db.SyncLogHeads
|
||||
where i.Status == 0
|
||||
select i
|
||||
).Count();
|
||||
if (CurrentSyncTaskCount > 0)
|
||||
{
|
||||
throw new Exception("存在未完成的任务,请等待完成!");
|
||||
}
|
||||
head.Id = Guid.NewGuid();
|
||||
head.SyncTime = DateTime.Now;
|
||||
head.Status = 0;
|
||||
_db.SyncLogHeads.Add(head);
|
||||
_db.SaveChanges();
|
||||
return Ok(new { IsSuccess = true, head.Id });
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return Ok(new { IsSuccess = false, e.Message });
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet("/CloseASync")]
|
||||
public IActionResult CloseASync(Guid Id, string Message, int Status)
|
||||
{
|
||||
try
|
||||
{
|
||||
var current =
|
||||
(from i in _db.SyncLogHeads where i.Id == Id select i).FirstOrDefault()
|
||||
?? throw new Exception("任务不存在!");
|
||||
current.Status = Status;
|
||||
current.Message = Message;
|
||||
_db.SaveChanges();
|
||||
return Ok(new { IsSuccess = true });
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return Ok(new { IsSuccess = false, e.Message });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 上传文件
|
||||
/// </summary>
|
||||
/// <param name="file"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("/UploadFile")]
|
||||
public async Task<IActionResult> UploadFile(IFormFile file)
|
||||
{
|
||||
|
@ -199,4 +81,124 @@ public class SyncFilesController(RemoteSyncServerFactory factory, SqliteDbContex
|
|||
return StatusCode(500, new { IsSuccess = false, Message = $"上传文件失败: {ex.Message}" });
|
||||
}
|
||||
}
|
||||
|
||||
// [HttpGet("/GetSyncFilesLogs")]
|
||||
// public IActionResult GetSyncFilesLogs(
|
||||
// string? ClientName,
|
||||
// int? Status,
|
||||
// DateTime? SyncTimeStart,
|
||||
// DateTime? SyncTimeEnd,
|
||||
// int page,
|
||||
// int rows
|
||||
// )
|
||||
// {
|
||||
// var item =
|
||||
// from i in _db.SyncLogHeads
|
||||
// where
|
||||
// (
|
||||
// string.IsNullOrEmpty(ClientName)
|
||||
// || (i.ClientName != null && i.ClientName.Contains(ClientName))
|
||||
// )
|
||||
// && (Status == null || i.Status == Status)
|
||||
// && (SyncTimeStart == null || i.SyncTime >= SyncTimeStart)
|
||||
// && (SyncTimeEnd == null || i.SyncTime <= SyncTimeEnd)
|
||||
// orderby i.Id descending
|
||||
// select new
|
||||
// {
|
||||
// Head = i,
|
||||
// Files = (from j in _db.SyncLogFiles where j.HeadId == i.Id select j).ToList()
|
||||
// };
|
||||
|
||||
// return Ok(item.Skip((page - 1) * rows).Take(rows).ToList());
|
||||
// }
|
||||
|
||||
// public class InputFileInfo
|
||||
// {
|
||||
// public required string RelativePath { get; set; }
|
||||
// public DateTime MTime { get; set; }
|
||||
// }
|
||||
|
||||
// public class OutputFileInfo : InputFileInfo
|
||||
// {
|
||||
// /// <summary>
|
||||
// /// 0 新增 1 修改 2 删除
|
||||
// /// </summary>
|
||||
// public int ServerOpType { get; set; }
|
||||
// }
|
||||
|
||||
// public class ServerOpFileInfo : OutputFileInfo
|
||||
// {
|
||||
// public required string ServerRootDirPath { get; set; }
|
||||
// public required string ClientRootDirPath { get; set; }
|
||||
// }
|
||||
|
||||
// public class InputFiles
|
||||
// {
|
||||
// public required string ServerRootDirPath { get; set; }
|
||||
|
||||
// /// <summary>
|
||||
// /// 0 special 1 exclude
|
||||
// /// </summary>
|
||||
// public int Type { get; set; }
|
||||
// public List<FileInfo>? Files { get; set; }
|
||||
// }
|
||||
|
||||
// public class ServerOpFiles
|
||||
// {
|
||||
// public required string ServerRootDirPath { get; set; }
|
||||
// public string? ClientRootDirPath { get; set; }
|
||||
// public List<OutputFileInfo>? Files { get; set; }
|
||||
// }
|
||||
|
||||
// [HttpPost("/GetFilesInfoByDir")]
|
||||
// public IActionResult GetFilesInfoByDir([FromBody] InputFiles inputFiles)
|
||||
// {
|
||||
// return Ok(new { IsSuccess = true });
|
||||
// }
|
||||
|
||||
// [HttpPost("/InitASync")]
|
||||
// public IActionResult InitASync([FromBody] SyncLogHead head)
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// var CurrentSyncTaskCount = (
|
||||
// from i in _db.SyncLogHeads
|
||||
// where i.Status == 0
|
||||
// select i
|
||||
// ).Count();
|
||||
// if (CurrentSyncTaskCount > 0)
|
||||
// {
|
||||
// throw new Exception("存在未完成的任务,请等待完成!");
|
||||
// }
|
||||
// head.Id = Guid.NewGuid();
|
||||
// head.SyncTime = DateTime.Now;
|
||||
// head.Status = 0;
|
||||
// _db.SyncLogHeads.Add(head);
|
||||
// _db.SaveChanges();
|
||||
// return Ok(new { IsSuccess = true, head.Id });
|
||||
// }
|
||||
// catch (Exception e)
|
||||
// {
|
||||
// return Ok(new { IsSuccess = false, e.Message });
|
||||
// }
|
||||
// }
|
||||
|
||||
// [HttpGet("/CloseASync")]
|
||||
// public IActionResult CloseASync(Guid Id, string Message, int Status)
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// var current =
|
||||
// (from i in _db.SyncLogHeads where i.Id == Id select i).FirstOrDefault()
|
||||
// ?? throw new Exception("任务不存在!");
|
||||
// current.Status = Status;
|
||||
// current.Message = Message;
|
||||
// _db.SaveChanges();
|
||||
// return Ok(new { IsSuccess = true });
|
||||
// }
|
||||
// catch (Exception e)
|
||||
// {
|
||||
// return Ok(new { IsSuccess = false, e.Message });
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
|
|
@ -10,10 +10,6 @@ ConfigurationBuilder configurationBuilder = new();
|
|||
// Add services to the container.
|
||||
|
||||
//添加配置文件路径
|
||||
RemoteSyncServerFactory.NamePwd =
|
||||
[
|
||||
.. (builder.Configuration.GetSection("NamePwds").Get<Tuple<string, string>[]>() ?? [])
|
||||
];
|
||||
foreach (var x in builder.Configuration.GetSection("NamePwds").GetChildren())
|
||||
{
|
||||
var it = x.GetChildren();
|
||||
|
|
|
@ -7,6 +7,10 @@ public class RemoteSyncServerFactory
|
|||
private readonly object Lock = new();
|
||||
|
||||
#pragma warning disable CA2211 // Non-constant fields should not be visible
|
||||
|
||||
/// <summary>
|
||||
/// 发布的名称和密码
|
||||
/// </summary>
|
||||
public static List<Tuple<string, string>> NamePwd = [];
|
||||
#pragma warning restore CA2211 // Non-constant fields should not be visible
|
||||
|
||||
|
|
|
@ -6,13 +6,6 @@ using Common;
|
|||
|
||||
namespace RemoteServer;
|
||||
|
||||
// enum StateWhenMsg
|
||||
// {
|
||||
// Authority = 0,
|
||||
// ConfigInfo = 1,
|
||||
// LocalPackAndUpload = 2,
|
||||
// RemoteUnPackAndRelease = 3,
|
||||
// }
|
||||
|
||||
public abstract class StateHelpBase(
|
||||
RemoteSyncServer context,
|
||||
|
@ -151,8 +144,6 @@ public class FinallyPublishHelper(RemoteSyncServer context)
|
|||
public void FinallyPublish()
|
||||
{
|
||||
// 发布数据库
|
||||
if (Context.NotNullSyncConfig.IsDeployDb)
|
||||
{
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
var arguments =
|
||||
|
@ -189,11 +180,6 @@ public class FinallyPublishHelper(RemoteSyncServer context)
|
|||
Context.Pipe.SendMsg(CreateErrMsg(output)).Wait();
|
||||
throw new Exception("执行发布错误,错误信息参考上一条消息!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotSupportedException("只支持windows!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System.Runtime.InteropServices;
|
||||
using System.Text.Json;
|
||||
using Common;
|
||||
using LocalServer;
|
||||
|
@ -13,68 +14,75 @@ public class PipeTest
|
|||
[Fact]
|
||||
public async void TestCase()
|
||||
{
|
||||
var p1 = new TestPipe(false, "1");
|
||||
var x = Task.Run(async () =>
|
||||
//msbuild 只能在windows上跑
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
var rs = p1.Work(
|
||||
(byte[] b) =>
|
||||
{
|
||||
var msg = JsonSerializer.Deserialize<SyncMsg>(b);
|
||||
if (msg.Body == "发布完成!")
|
||||
{
|
||||
p1.Close("正常退出!");
|
||||
}
|
||||
Console.WriteLine(b);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
await foreach (var r in rs)
|
||||
var p1 = new TestPipe(false, "1");
|
||||
var x = Task.Run(async () =>
|
||||
{
|
||||
Console.WriteLine(r);
|
||||
var rs = p1.Work(
|
||||
(byte[] b) =>
|
||||
{
|
||||
var msg = JsonSerializer.Deserialize<SyncMsg>(b);
|
||||
#pragma warning disable CS8602 // Dereference of a possibly null reference.
|
||||
if (msg.Body == "发布完成!")
|
||||
{
|
||||
_ = p1.Close("正常退出!");
|
||||
}
|
||||
#pragma warning restore CS8602 // Dereference of a possibly null reference.
|
||||
Console.WriteLine(b);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
await foreach (var r in rs)
|
||||
{
|
||||
Console.WriteLine(r);
|
||||
}
|
||||
});
|
||||
//await p1.Close("sdf");
|
||||
//await x;
|
||||
var p2 = new TestPipe(false, "2");
|
||||
p1.Other = p2;
|
||||
p2.Other = p1;
|
||||
var p3 = new TestPipe(true, "3");
|
||||
var p4 = new TestPipe(true, "4");
|
||||
p3.Other = p4;
|
||||
p4.Other = p3;
|
||||
LocalSyncServer.TempRootFile = "D:/FileSyncTest/stemp";
|
||||
RemoteSyncServer.SqlPackageAbPath =
|
||||
"C:\\Users\\ZHAOLEI\\.dotnet\\tools\\sqlpackage.exe";
|
||||
//LocalSyncServer.MsdeployAbPath =
|
||||
// "C:\\Program Files\\IIS\\Microsoft Web Deploy V3\\msdeploy.exe";
|
||||
LocalSyncServer.SqlPackageAbPath = "C:\\Users\\ZHAOLEI\\.dotnet\\tools\\sqlpackage.exe";
|
||||
LocalSyncServer.MSBuildAbPath =
|
||||
"C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\MSBuild\\Current\\Bin\\amd64\\MSBuild.exe";
|
||||
RemoteSyncServer.TempRootFile = "D:/FileSyncTest/dtemp";
|
||||
RemoteSyncServerFactory.NamePwd = [new Tuple<string, string>("Test", "t123")];
|
||||
var lf = new LocalSyncServerFactory();
|
||||
var task1 = Task.Run(async () =>
|
||||
{
|
||||
await lf.CreateLocalSyncServer(p2, "Test", p3);
|
||||
});
|
||||
|
||||
var rf = new RemoteSyncServerFactory();
|
||||
|
||||
var task2 = Task.Run(async () =>
|
||||
{
|
||||
await rf.CreateRemoteSyncServer(p4, "Test");
|
||||
});
|
||||
TestPipe.syncServerFactory = rf;
|
||||
var starter = new SyncMsg
|
||||
{
|
||||
Body = JsonSerializer.Serialize(new PipeSeed().TestConfig),
|
||||
Type = SyncMsgType.General,
|
||||
Step = SyncProcessStep.Connect
|
||||
};
|
||||
await p1.SendMsg(starter);
|
||||
await x;
|
||||
if (p1.ErrResult != "正常退出!")
|
||||
{
|
||||
Assert.Fail(p1.ErrResult);
|
||||
}
|
||||
});
|
||||
//await p1.Close("sdf");
|
||||
//await x;
|
||||
var p2 = new TestPipe(false, "2");
|
||||
p1.Other = p2;
|
||||
p2.Other = p1;
|
||||
var p3 = new TestPipe(true, "3");
|
||||
var p4 = new TestPipe(true, "4");
|
||||
p3.Other = p4;
|
||||
p4.Other = p3;
|
||||
LocalSyncServer.TempRootFile = "D:/FileSyncTest/stemp";
|
||||
RemoteSyncServer.SqlPackageAbPath = "C:\\Users\\ZHAOLEI\\.dotnet\\tools\\sqlpackage.exe";
|
||||
//LocalSyncServer.MsdeployAbPath =
|
||||
// "C:\\Program Files\\IIS\\Microsoft Web Deploy V3\\msdeploy.exe";
|
||||
LocalSyncServer.SqlPackageAbPath = "C:\\Users\\ZHAOLEI\\.dotnet\\tools\\sqlpackage.exe";
|
||||
LocalSyncServer.MSBuildAbPath =
|
||||
"C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\MSBuild\\Current\\Bin\\amd64\\MSBuild.exe";
|
||||
RemoteSyncServer.TempRootFile = "D:/FileSyncTest/dtemp";
|
||||
RemoteSyncServerFactory.NamePwd = [new Tuple<string, string>("Test", "t123")];
|
||||
var lf = new LocalSyncServerFactory();
|
||||
var task1 = Task.Run(async () =>
|
||||
{
|
||||
await lf.CreateLocalSyncServer(p2, "Test", p3);
|
||||
});
|
||||
|
||||
var rf = new RemoteSyncServerFactory();
|
||||
|
||||
var task2 = Task.Run(async () =>
|
||||
{
|
||||
await rf.CreateRemoteSyncServer(p4, "Test");
|
||||
});
|
||||
TestPipe.syncServerFactory = rf;
|
||||
var starter = new SyncMsg
|
||||
{
|
||||
Body = JsonSerializer.Serialize(new PipeSeed().TestConfig),
|
||||
Type = SyncMsgType.General,
|
||||
Step = SyncProcessStep.Connect
|
||||
};
|
||||
await p1.SendMsg(starter);
|
||||
await x;
|
||||
if (p1.ErrResult != "正常退出!")
|
||||
{
|
||||
Assert.Fail(p1.ErrResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,9 @@ namespace ServerTest
|
|||
public TestPipe? Other;
|
||||
public string? ErrResult;
|
||||
public string Id = id;
|
||||
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable.
|
||||
public static RemoteSyncServerFactory syncServerFactory;
|
||||
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable.
|
||||
|
||||
public override async IAsyncEnumerable<int> Work(
|
||||
Func<byte[], bool> receiveCb,
|
||||
|
@ -44,7 +46,7 @@ namespace ServerTest
|
|||
//}
|
||||
Task.Run(() =>
|
||||
{
|
||||
var it = syncServerFactory.GetServerByName("Test");
|
||||
var it = syncServerFactory.GetServerByName("Test")?? throw new NullReferenceException("找不到服务名称!");
|
||||
var h = new UnPackAndReleaseHelper(it);
|
||||
it.SetStateHelpBase(h);
|
||||
h.UnPack();
|
||||
|
|
Loading…
Reference in a new issue