feat: 增加在各个步骤前后调用扩展命令
c# 异步任务里面的异常,不会在异步之外被捕获。 ``` try { Task.Run(()=>{ throw new Exception() //此异常不会被捕获 ) }; catch(Exception ex) { //将不会捕获异常 }
This commit is contained in:
parent
a0889310d7
commit
4724e96efe
14 changed files with 357 additions and 76 deletions
|
@ -1,5 +1,33 @@
|
||||||
namespace Common;
|
namespace Common;
|
||||||
|
|
||||||
|
public class ExecProcess
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 步骤
|
||||||
|
/// </summary>
|
||||||
|
public SyncProcessStep Step { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A after B before
|
||||||
|
/// </summary>
|
||||||
|
public required string StepBeforeOrAfter { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// L Local S Server
|
||||||
|
/// </summary>
|
||||||
|
public required string ExecInLocalOrServer { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 执行的应用程序名称
|
||||||
|
/// </summary>
|
||||||
|
public required string FileName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 执行的应用程序参数
|
||||||
|
/// </summary>
|
||||||
|
public required string Argumnets { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
public class DirFileConfig
|
public class DirFileConfig
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -127,4 +155,9 @@ public class Config
|
||||||
/// 同步的文件夹配置
|
/// 同步的文件夹配置
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public required List<DirFileConfig> DirFileConfigs { get; set; }
|
public required List<DirFileConfig> DirFileConfigs { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 按照步骤执行应用程序扩展列表
|
||||||
|
/// </summary>
|
||||||
|
public required List<ExecProcess> ExecProcesses { get; set; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ namespace Common;
|
||||||
|
|
||||||
public abstract class AbsPipeLine(bool isAES)
|
public abstract class AbsPipeLine(bool isAES)
|
||||||
{
|
{
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// pipeLine工作函数,生效期间永久阻塞
|
/// pipeLine工作函数,生效期间永久阻塞
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -18,6 +17,7 @@ public abstract class AbsPipeLine(bool isAES)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 监听pipeline 消息,由Work 函数调用
|
/// 监听pipeline 消息,由Work 函数调用
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -48,7 +48,6 @@ public abstract class AbsPipeLine(bool isAES)
|
||||||
/// <returns>上传完成时返回</returns>/
|
/// <returns>上传完成时返回</returns>/
|
||||||
public abstract Task UploadFile(string url, string filePath, Func<double, bool> progressCb);
|
public abstract Task UploadFile(string url, string filePath, Func<double, bool> progressCb);
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 管道消息是否使用AES加密
|
/// 管道消息是否使用AES加密
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -147,7 +146,7 @@ public class WebSocPipeLine<TSocket>(TSocket socket, bool isAES) : AbsPipeLine(i
|
||||||
new SyncMsg
|
new SyncMsg
|
||||||
{
|
{
|
||||||
Type = SyncMsgType.Error,
|
Type = SyncMsgType.Error,
|
||||||
Step = SyncProcessStep.CloseError,
|
Step = SyncProcessStep.Close,
|
||||||
Body = CloseReason ?? ""
|
Body = CloseReason ?? ""
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -16,7 +16,7 @@ public enum SyncProcessStep
|
||||||
PackSqlServer = 4,
|
PackSqlServer = 4,
|
||||||
UploadAndUnpack = 5,
|
UploadAndUnpack = 5,
|
||||||
Publish = 6,
|
Publish = 6,
|
||||||
CloseError = 7
|
Close = 7
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SyncMsg
|
public class SyncMsg
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO.Pipelines;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
using Common;
|
using Common;
|
||||||
|
|
||||||
|
@ -8,6 +10,7 @@ public class LocalSyncServer
|
||||||
#pragma warning disable CA2211 // Non-constant fields should not be visible
|
#pragma warning disable CA2211 // Non-constant fields should not be visible
|
||||||
public static string TempRootFile = "C:/TempPack";
|
public static string TempRootFile = "C:/TempPack";
|
||||||
public static string SqlPackageAbPath = "sqlpackage";
|
public static string SqlPackageAbPath = "sqlpackage";
|
||||||
|
|
||||||
// 使用msdeploy 将会打包当前可运行的内容,它很有可能不包含最新的构建
|
// 使用msdeploy 将会打包当前可运行的内容,它很有可能不包含最新的构建
|
||||||
//public static string MsdeployAbPath = "msdeploy";
|
//public static string MsdeployAbPath = "msdeploy";
|
||||||
|
|
||||||
|
@ -15,16 +18,88 @@ public class LocalSyncServer
|
||||||
//使用msbuild 会缺少.net frame的运行环境 bin\roslyn 里面的内容,第一次需要人为复制一下,后面就就好了。
|
//使用msbuild 会缺少.net frame的运行环境 bin\roslyn 里面的内容,第一次需要人为复制一下,后面就就好了。
|
||||||
public static string MSBuildAbPath = "MSBuild";
|
public static string MSBuildAbPath = "MSBuild";
|
||||||
#pragma warning restore CA2211 // Non-constant fields should not be visible
|
#pragma warning restore CA2211 // Non-constant fields should not be visible
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 连接状态,流程管理,LocalPipe 和 remotePipe 也在此处交换信息
|
/// 连接状态,流程管理,LocalPipe 和 remotePipe 也在此处交换信息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private StateHelpBase StateHelper;
|
private StateHelpBase StateHelper;
|
||||||
|
|
||||||
|
|
||||||
public void SetStateHelper(StateHelpBase helper)
|
public void SetStateHelper(StateHelpBase helper)
|
||||||
{
|
{
|
||||||
StateHelper = helper;
|
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("错误,信息参考上一条消息!");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -103,7 +178,7 @@ public class LocalSyncServer
|
||||||
public readonly AbsPipeLine LocalPipe;
|
public readonly AbsPipeLine LocalPipe;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// local server 和 remote server 的连接,它有加密
|
/// local server 和 remote server 的连接,它有加密
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly AbsPipeLine RemotePipe;
|
public readonly AbsPipeLine RemotePipe;
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
"dotnetRunMessages": true,
|
"dotnetRunMessages": true,
|
||||||
"launchBrowser": true,
|
"launchBrowser": true,
|
||||||
"launchUrl": "swagger",
|
"launchUrl": "swagger",
|
||||||
"applicationUrl": "http://localhost:5014",
|
"applicationUrl": "http://localhost:6818",
|
||||||
"environmentVariables": {
|
"environmentVariables": {
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ public abstract class StateHelpBase(
|
||||||
var syncMsg =
|
var syncMsg =
|
||||||
JsonSerializer.Deserialize<SyncMsg>(msg)
|
JsonSerializer.Deserialize<SyncMsg>(msg)
|
||||||
?? throw new NullReferenceException("msg is null");
|
?? throw new NullReferenceException("msg is null");
|
||||||
if (syncMsg.Step != Step)
|
if (syncMsg.Step != Step && syncMsg.Step != SyncProcessStep.Close)
|
||||||
{
|
{
|
||||||
throw new Exception("Sync step error!");
|
throw new Exception("Sync step error!");
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ public abstract class StateHelpBase(
|
||||||
var syncMsg =
|
var syncMsg =
|
||||||
JsonSerializer.Deserialize<SyncMsg>(msg)
|
JsonSerializer.Deserialize<SyncMsg>(msg)
|
||||||
?? throw new NullReferenceException("msg is null");
|
?? throw new NullReferenceException("msg is null");
|
||||||
if (syncMsg.Step != Step)
|
if (syncMsg.Step != Step && syncMsg.Step != SyncProcessStep.Close)
|
||||||
{
|
{
|
||||||
throw new Exception("Sync step error!");
|
throw new Exception("Sync step error!");
|
||||||
}
|
}
|
||||||
|
@ -416,7 +416,7 @@ public class FinallyPublishHelper(LocalSyncServer context)
|
||||||
{
|
{
|
||||||
protected override void HandleLocalMsg(SyncMsg msg)
|
protected override void HandleLocalMsg(SyncMsg msg)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
//throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -425,6 +425,18 @@ public class FinallyPublishHelper(LocalSyncServer context)
|
||||||
/// <param name="msg"></param>
|
/// <param name="msg"></param>
|
||||||
protected override void HandleRemoteMsg(SyncMsg msg)
|
protected override void HandleRemoteMsg(SyncMsg msg)
|
||||||
{
|
{
|
||||||
|
if (msg.Body == "发布完成!")
|
||||||
|
{
|
||||||
|
Context.SetStateHelper(new NormalCloseHelper(Context));
|
||||||
|
}
|
||||||
Context.LocalPipe.SendMsg(msg).Wait();
|
Context.LocalPipe.SendMsg(msg).Wait();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class NormalCloseHelper(LocalSyncServer context)
|
||||||
|
: StateHelpBase(context, SyncProcessStep.Close)
|
||||||
|
{
|
||||||
|
protected override void HandleRemoteMsg(SyncMsg msg) { }
|
||||||
|
|
||||||
|
protected override void HandleLocalMsg(SyncMsg msg) { }
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||||
|
-->
|
||||||
|
<Project>
|
||||||
|
<PropertyGroup>
|
||||||
|
<DeleteExistingFiles>false</DeleteExistingFiles>
|
||||||
|
<ExcludeApp_Data>false</ExcludeApp_Data>
|
||||||
|
<LaunchSiteAfterPublish>true</LaunchSiteAfterPublish>
|
||||||
|
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
|
||||||
|
<LastUsedPlatform>Any CPU</LastUsedPlatform>
|
||||||
|
<PublishProvider>FileSystem</PublishProvider>
|
||||||
|
<PublishUrl>bin\Release\net8.0\publish\</PublishUrl>
|
||||||
|
<WebPublishMethod>FileSystem</WebPublishMethod>
|
||||||
|
<_TargetId>Folder</_TargetId>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
|
@ -0,0 +1,11 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||||
|
-->
|
||||||
|
<Project>
|
||||||
|
<PropertyGroup>
|
||||||
|
<History>True|2024-10-28T10:24:22.2791029Z||;True|2024-10-28T17:30:28.6485638+08:00||;False|2024-10-28T17:29:49.7948159+08:00||;</History>
|
||||||
|
<LastFailureDetails />
|
||||||
|
<_PublishTargetUrl>D:\git\FileSqlServerSync\Server\RemoteServer\bin\Release\net8.0\publish\</_PublishTargetUrl>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
|
@ -5,5 +5,6 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<ActiveDebugProfile>http</ActiveDebugProfile>
|
<ActiveDebugProfile>http</ActiveDebugProfile>
|
||||||
|
<NameOfLastUsedPublishProfile>D:\git\FileSqlServerSync\Server\RemoteServer\Properties\PublishProfiles\FolderProfile.pubxml</NameOfLastUsedPublishProfile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -1,3 +1,4 @@
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Net.WebSockets;
|
using System.Net.WebSockets;
|
||||||
using Common;
|
using Common;
|
||||||
|
|
||||||
|
@ -13,7 +14,78 @@ public class RemoteSyncServer
|
||||||
|
|
||||||
public void SetStateHelpBase(StateHelpBase stateHelper)
|
public void SetStateHelpBase(StateHelpBase stateHelper)
|
||||||
{
|
{
|
||||||
StateHelper = stateHelper;
|
try
|
||||||
|
{
|
||||||
|
StateHelper = stateHelper;
|
||||||
|
if (SyncConfig != null)
|
||||||
|
{
|
||||||
|
var LastExec = NotNullSyncConfig.ExecProcesses.Find(x =>
|
||||||
|
{
|
||||||
|
return x.StepBeforeOrAfter == "A"
|
||||||
|
&& x.Step == (stateHelper.Step - 1)
|
||||||
|
&& x.ExecInLocalOrServer == "S";
|
||||||
|
});
|
||||||
|
ExecProcess(LastExec);
|
||||||
|
var CurrentExec = NotNullSyncConfig.ExecProcesses.Find(x =>
|
||||||
|
{
|
||||||
|
return x.StepBeforeOrAfter == "B"
|
||||||
|
&& x.Step == stateHelper.Step
|
||||||
|
&& x.ExecInLocalOrServer == "S";
|
||||||
|
});
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
Pipe.SendMsg(
|
||||||
|
StateHelper.CreateMsg(
|
||||||
|
$"{ep.Step}-{ep.StepBeforeOrAfter}-{ep.ExecInLocalOrServer}-{ep.FileName} {ep.Argumnets} 执行成功!"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.Wait();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Pipe.SendMsg(
|
||||||
|
StateHelper.CreateMsg(
|
||||||
|
$"{ep.Step}-{ep.StepBeforeOrAfter}-{ep.ExecInLocalOrServer}-{ep.FileName} {ep.Argumnets} 失败 {output}!"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.Wait();
|
||||||
|
throw new Exception("错误,信息参考上一条消息!");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public StateHelpBase GetStateHelpBase()
|
public StateHelpBase GetStateHelpBase()
|
||||||
|
|
|
@ -13,7 +13,7 @@ public abstract class StateHelpBase(
|
||||||
{
|
{
|
||||||
protected readonly RemoteSyncServer Context = context;
|
protected readonly RemoteSyncServer Context = context;
|
||||||
|
|
||||||
protected readonly SyncProcessStep Step = step;
|
public readonly SyncProcessStep Step = step;
|
||||||
|
|
||||||
public SyncMsg CreateErrMsg(string Body)
|
public SyncMsg CreateErrMsg(string Body)
|
||||||
{
|
{
|
||||||
|
@ -42,7 +42,7 @@ public abstract class StateHelpBase(
|
||||||
var syncMsg =
|
var syncMsg =
|
||||||
JsonSerializer.Deserialize<SyncMsg>(msg)
|
JsonSerializer.Deserialize<SyncMsg>(msg)
|
||||||
?? throw new NullReferenceException("msg is null");
|
?? throw new NullReferenceException("msg is null");
|
||||||
if (syncMsg.Step != Step)
|
if (syncMsg.Step != Step && syncMsg.Step != SyncProcessStep.Close)
|
||||||
{
|
{
|
||||||
throw new Exception("Sync step error!");
|
throw new Exception("Sync step error!");
|
||||||
}
|
}
|
||||||
|
@ -134,7 +134,14 @@ public class UnPackAndReleaseHelper(RemoteSyncServer context)
|
||||||
Context.Pipe.SendMsg(h.CreateMsg("将要发布数据库,可能时间会较长!")).Wait();
|
Context.Pipe.SendMsg(h.CreateMsg("将要发布数据库,可能时间会较长!")).Wait();
|
||||||
Task.Run(() =>
|
Task.Run(() =>
|
||||||
{
|
{
|
||||||
h.FinallyPublish();
|
try
|
||||||
|
{
|
||||||
|
h.FinallyPublish();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Context.Close(e.Message);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,6 +161,9 @@ public class FinallyPublishHelper(RemoteSyncServer context)
|
||||||
+ $" /TargetServerName:{Context.NotNullSyncConfig.DstDb.ServerName} /TargetDatabaseName:{Context.NotNullSyncConfig.DstDb.DatabaseName}"
|
+ $" /TargetServerName:{Context.NotNullSyncConfig.DstDb.ServerName} /TargetDatabaseName:{Context.NotNullSyncConfig.DstDb.DatabaseName}"
|
||||||
+ $" /TargetUser:{Context.NotNullSyncConfig.DstDb.User} /TargetPassword:{Context.NotNullSyncConfig.DstDb.Password} /TargetTrustServerCertificate:True";
|
+ $" /TargetUser:{Context.NotNullSyncConfig.DstDb.User} /TargetPassword:{Context.NotNullSyncConfig.DstDb.Password} /TargetTrustServerCertificate:True";
|
||||||
|
|
||||||
|
//Context
|
||||||
|
// .Pipe.SendMsg(CreateMsg($"发布脚本为: {RemoteSyncServer.SqlPackageAbPath} {arguments}"))
|
||||||
|
// .Wait();
|
||||||
ProcessStartInfo startInfo =
|
ProcessStartInfo startInfo =
|
||||||
new()
|
new()
|
||||||
{
|
{
|
||||||
|
@ -201,8 +211,15 @@ public class FinallyPublishHelper(RemoteSyncServer context)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Context.SetStateHelpBase(new NormalCloseHelper(Context));
|
||||||
Context.Pipe.SendMsg(CreateMsg("发布完成!")).Wait();
|
Context.Pipe.SendMsg(CreateMsg("发布完成!")).Wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void HandleMsg(SyncMsg msg) { }
|
protected override void HandleMsg(SyncMsg msg) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class NormalCloseHelper(RemoteSyncServer context)
|
||||||
|
: StateHelpBase(context, SyncProcessStep.Close)
|
||||||
|
{
|
||||||
|
protected override void HandleMsg(SyncMsg msg) { }
|
||||||
|
}
|
||||||
|
|
|
@ -45,6 +45,36 @@ public class PipeSeed : IDisposable
|
||||||
DirFileConfigs = new List<DirFileConfig>
|
DirFileConfigs = new List<DirFileConfig>
|
||||||
{
|
{
|
||||||
new DirFileConfig { DirPath = "/bin", Excludes = ["/roslyn", "/Views"] }
|
new DirFileConfig { DirPath = "/bin", Excludes = ["/roslyn", "/Views"] }
|
||||||
|
},
|
||||||
|
|
||||||
|
// C:/Windows/System32/inetsrv/appcmd.exe stop sites "publicserver"
|
||||||
|
// C:/Windows/System32/inetsrv/appcmd.exe start sites "publicserver"
|
||||||
|
ExecProcesses = new List<ExecProcess>
|
||||||
|
{
|
||||||
|
new ExecProcess
|
||||||
|
{
|
||||||
|
Argumnets = "ls",
|
||||||
|
FileName = "powershell",
|
||||||
|
StepBeforeOrAfter = "A",
|
||||||
|
ExecInLocalOrServer = "L",
|
||||||
|
Step = SyncProcessStep.DeployProject,
|
||||||
|
},
|
||||||
|
new ExecProcess
|
||||||
|
{
|
||||||
|
Argumnets = "ls",
|
||||||
|
FileName = "powershell",
|
||||||
|
StepBeforeOrAfter = "B",
|
||||||
|
ExecInLocalOrServer = "S",
|
||||||
|
Step = SyncProcessStep.Publish,
|
||||||
|
},
|
||||||
|
new ExecProcess
|
||||||
|
{
|
||||||
|
Argumnets = "ls",
|
||||||
|
FileName = "powershell",
|
||||||
|
StepBeforeOrAfter = "A",
|
||||||
|
ExecInLocalOrServer = "S",
|
||||||
|
Step = SyncProcessStep.Publish,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,12 @@ public class PipeTest
|
||||||
[Fact]
|
[Fact]
|
||||||
public async void TestCase()
|
public async void TestCase()
|
||||||
{
|
{
|
||||||
//msbuild 只能在windows上跑
|
//if (System.IO.File.Exists("Pipe.txt"))
|
||||||
|
//{
|
||||||
|
// System.IO.File.Delete("Pipe.txt");
|
||||||
|
//}
|
||||||
|
//System.IO.File.Create("Pipe.txt");
|
||||||
|
//msbuild ÖťÄÜÔÚwindowsÉĎĹÜ
|
||||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||||
{
|
{
|
||||||
var p1 = new TestPipe(false, "1");
|
var p1 = new TestPipe(false, "1");
|
||||||
|
@ -27,9 +32,18 @@ public class PipeTest
|
||||||
#pragma warning disable CS8602 // Dereference of a possibly null reference.
|
#pragma warning disable CS8602 // Dereference of a possibly null reference.
|
||||||
if (msg.Body == "·¢²¼Íê³É£¡")
|
if (msg.Body == "·¢²¼Íê³É£¡")
|
||||||
{
|
{
|
||||||
_ = p1.Close("正常退出!");
|
Task.Run(() =>
|
||||||
|
{
|
||||||
|
Task.Delay(1000).Wait();
|
||||||
|
_ = p1.Close("ŐýłŁÍËłöŁĄ");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
#pragma warning restore CS8602 // Dereference of a possibly null reference.
|
#pragma warning restore CS8602 // Dereference of a possibly null reference.
|
||||||
|
System.IO.File.AppendAllText(
|
||||||
|
"Pipe.txt",
|
||||||
|
$"{msg.Step}-{msg.Type}:{msg.Body}\n"
|
||||||
|
);
|
||||||
|
|
||||||
Console.WriteLine(b);
|
Console.WriteLine(b);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,21 +7,21 @@ const LocalHost = "127.0.0.1";
|
||||||
//这是个例子,请在`config`中写你的配置
|
//这是个例子,请在`config`中写你的配置
|
||||||
const example_config = {
|
const example_config = {
|
||||||
//发布的名称,每个项目具有唯一的一个名称
|
//发布的名称,每个项目具有唯一的一个名称
|
||||||
Name: "Test",
|
Name: "FYMF",
|
||||||
RemotePwd: "t123",
|
RemotePwd: "FYMF",
|
||||||
//远程服务器地址,也就是发布的目的地,它是正式环境
|
//远程服务器地址,也就是发布的目的地,它是正式环境
|
||||||
RemoteUrl: "127.0.0.1:6819",
|
RemoteUrl: "127.0.0.1:8007",
|
||||||
//是否发布数据库 sqlserver
|
//是否发布数据库 sqlserver
|
||||||
IsDeployDb: false,
|
IsDeployDb: false,
|
||||||
//是否发布前重新构建项目
|
//是否发布前重新构建项目
|
||||||
IsDeployProject: false,
|
IsDeployProject: true,
|
||||||
//项目地址
|
//项目地址
|
||||||
LocalProjectAbsolutePath:
|
LocalProjectAbsolutePath:
|
||||||
"D:/git/HMES-H7-HNFY/HMES-H7-HNFYMF/HMES-H7-HNFYMF.WEB",
|
"D:/git/HMES-H7-HNFY/HMES-H7-HNFYMF/HMES-H7-HNFYMF.WEB",
|
||||||
//源文件目录地址,是要发布的文件根目录,它是绝对路径,!执行发布时将发布到这个目录!
|
//源文件目录地址,是要发布的文件根目录,它是绝对路径,!执行发布时将发布到这个目录!
|
||||||
LocalRootPath: "D:/FileSyncTest/src",
|
LocalRootPath: "D:/FileSyncTest/src",
|
||||||
//目标文件目录地址,也就是部署服务的机器上的项目文件根目录,它是绝对路径
|
//目标文件目录地址,也就是部署服务的机器上的项目文件根目录,它是绝对路径
|
||||||
RemoteRootPath: "D:/FileSyncTest/dst",
|
RemoteRootPath: "D:/FYMF",
|
||||||
//源数据库配置 SqlServer,将会同步数据库的结构
|
//源数据库配置 SqlServer,将会同步数据库的结构
|
||||||
SrcDb: {
|
SrcDb: {
|
||||||
//Host
|
//Host
|
||||||
|
@ -45,7 +45,7 @@ const example_config = {
|
||||||
ServerName: "127.0.0.1",
|
ServerName: "127.0.0.1",
|
||||||
DatabaseName: "HMES_H7_HNFYMF",
|
DatabaseName: "HMES_H7_HNFYMF",
|
||||||
User: "sa",
|
User: "sa",
|
||||||
Password: "0",
|
Password: "Yuanmo520...",
|
||||||
TrustServerCertificate: "True",
|
TrustServerCertificate: "True",
|
||||||
},
|
},
|
||||||
//子目录配置,每个子目录都有自己不同的发布策略,它是相对路径,即相对于LocalRootPath和RemoteRootPath(注意 '/',这将拼成一个完整的路径),文件数据依此进行,
|
//子目录配置,每个子目录都有自己不同的发布策略,它是相对路径,即相对于LocalRootPath和RemoteRootPath(注意 '/',这将拼成一个完整的路径),文件数据依此进行,
|
||||||
|
@ -60,58 +60,58 @@ const example_config = {
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
const config = {
|
const config = {
|
||||||
//发布的名称,每个项目具有唯一的一个名称
|
//发布的名称,每个项目具有唯一的一个名称
|
||||||
Name: "Test",
|
Name: "FYMF",
|
||||||
RemotePwd: "t123",
|
RemotePwd: "FYMF",
|
||||||
//远程服务器地址,也就是发布的目的地,它是正式环境
|
//远程服务器地址,也就是发布的目的地,它是正式环境
|
||||||
RemoteUrl: "127.0.0.1:6819",
|
RemoteUrl: "127.0.0.1:8007",
|
||||||
//是否发布数据库 sqlserver
|
//是否发布数据库 sqlserver
|
||||||
IsDeployDb: true,
|
IsDeployDb: true,
|
||||||
//是否发布前重新构建项目
|
//是否发布前重新构建项目
|
||||||
IsDeployProject: true,
|
IsDeployProject: false,
|
||||||
//项目地址
|
//项目地址
|
||||||
LocalProjectAbsolutePath:
|
LocalProjectAbsolutePath:
|
||||||
"D:/git/HMES-H7-HNFY/HMES-H7-HNFYMF/HMES-H7-HNFYMF.WEB",
|
"D:/git/HMES-H7-HNFY/HMES-H7-HNFYMF/HMES-H7-HNFYMF.WEB",
|
||||||
//源文件目录地址,是要发布的文件根目录,它是绝对路径,!执行发布时将发布到这个目录!
|
//源文件目录地址,是要发布的文件根目录,它是绝对路径,!执行发布时将发布到这个目录!
|
||||||
LocalRootPath: "D:/FileSyncTest/src",
|
LocalRootPath: "D:/FileSyncTest/src",
|
||||||
//目标文件目录地址,也就是部署服务的机器上的项目文件根目录,它是绝对路径
|
//目标文件目录地址,也就是部署服务的机器上的项目文件根目录,它是绝对路径
|
||||||
RemoteRootPath: "D:/FileSyncTest/dst",
|
RemoteRootPath: "D:/FYMF",
|
||||||
//源数据库配置 SqlServer,将会同步数据库的结构
|
//源数据库配置 SqlServer,将会同步数据库的结构
|
||||||
SrcDb: {
|
SrcDb: {
|
||||||
//Host
|
//Host
|
||||||
ServerName: "172.16.12.2",
|
ServerName: "172.16.12.2",
|
||||||
//数据库名
|
//数据库名
|
||||||
DatabaseName: "HMES_H7_HNFYMF",
|
DatabaseName: "HMES_H7_HNFYMF",
|
||||||
User: "hmes-h7",
|
User: "hmes-h7",
|
||||||
Password: "Hmes-h7666",
|
Password: "Hmes-h7666",
|
||||||
//是否信任服务器证书
|
//是否信任服务器证书
|
||||||
TrustServerCertificate: "True",
|
TrustServerCertificate: "True",
|
||||||
//同步的数据,这些数据将会同步
|
//同步的数据,这些数据将会同步
|
||||||
SyncTablesData: [
|
SyncTablesData: [
|
||||||
"dbo.sys_Button",
|
"dbo.sys_Button",
|
||||||
"dbo.sys_Menu",
|
"dbo.sys_Menu",
|
||||||
"dbo.sys_Module",
|
"dbo.sys_Module",
|
||||||
"dbo.sys_Page",
|
"dbo.sys_Page",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
//目标数据库配置 sqlserver
|
//目标数据库配置 sqlserver
|
||||||
DstDb: {
|
DstDb: {
|
||||||
ServerName: "127.0.0.1",
|
ServerName: "127.0.0.1",
|
||||||
DatabaseName: "HMES_H7_HNFYMF",
|
DatabaseName: "HMES_H7_HNFYMF",
|
||||||
User: "sa",
|
User: "sa",
|
||||||
Password: "0",
|
Password: "Yuanmo520...",
|
||||||
TrustServerCertificate: "True",
|
TrustServerCertificate: "True",
|
||||||
},
|
},
|
||||||
//子目录配置,每个子目录都有自己不同的发布策略,它是相对路径,即相对于LocalRootPath和RemoteRootPath(注意 '/',这将拼成一个完整的路径),文件数据依此进行,
|
//子目录配置,每个子目录都有自己不同的发布策略,它是相对路径,即相对于LocalRootPath和RemoteRootPath(注意 '/',这将拼成一个完整的路径),文件数据依此进行,
|
||||||
DirFileConfigs: [
|
DirFileConfigs: [
|
||||||
{
|
{
|
||||||
DirPath: "/bin",
|
DirPath: "/bin",
|
||||||
//排除的文件或目录,它是相对路径,相对于!!!LocalRootPath和RemoteRootPath!!!
|
//排除的文件或目录,它是相对路径,相对于!!!LocalRootPath和RemoteRootPath!!!
|
||||||
Excludes: ["/roslyn", "/Views"],
|
Excludes: ["/roslyn", "/Views"],
|
||||||
//只追踪文件或目录,它是相对路径,相对于!!!LocalRootPath和RemoteRootPath!!!,它的优先级最高,如果你指定了它的值,Excludes将会失效
|
//只追踪文件或目录,它是相对路径,相对于!!!LocalRootPath和RemoteRootPath!!!,它的优先级最高,如果你指定了它的值,Excludes将会失效
|
||||||
// CherryPicks:[]
|
// CherryPicks:[]
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue