public async Task TestVMScaleSetVMOperations_RunCommand() { EnsureClientsInitialized(DefaultLocation); InitializeCommon(); instanceId = "0"; bool passed = false; var storageAccountOutput = await CreateStorageAccount(rgName, storageAccountName); var getTwoVirtualMachineScaleSet = await CreateVMScaleSet_NoAsyncTracking( rgName, vmssName, storageAccountOutput, imageRef, createWithManagedDisks : true); VirtualMachineScaleSet vmScaleSet = getTwoVirtualMachineScaleSet.Item1; inputVMScaleSet = getTwoVirtualMachineScaleSet.Item2; await WaitForCompletionAsync(await VirtualMachineScaleSetVMsOperations.StartStartAsync(rgName, vmScaleSet.Name, instanceId)); RunCommandResult result = (await WaitForCompletionAsync(await VirtualMachineScaleSetVMsOperations.StartRunCommandAsync(rgName, vmScaleSet.Name, instanceId, new RunCommandInput("ipconfig")))).Value; Assert.NotNull(result); Assert.NotNull(result.Value); Assert.True(result.Value.Count > 0); passed = true; Assert.True(passed); }
public static RunCommandResult RunCommandWithResult(string fileName, string args, int timeOut = 60000) { Process p = new Process(); p.StartInfo = new ProcessStartInfo(fileName, args); p.StartInfo.RedirectStandardOutput = true; p.StartInfo.RedirectStandardError = true; p.Start(); RunCommandResult result = new RunCommandResult(); if (p.WaitForExit(timeOut)) { result.ExitCode = p.ExitCode; result.StdOut = p.StandardOutput.ReadToEnd(); result.StdErr = p.StandardError.ReadToEnd(); if (VerboseLogging) { TestContext.Out.WriteLine($"Command run finished. {fileName} {args} {timeOut}. Output: {result.StdOut} Error: {result.StdErr}"); } } else { throw new TimeoutException($"Command run timed out. {fileName} {args} {timeOut}"); } return(result); }
public void TestVMOperations_RunCommand() { using (MockContext context = MockContext.Start(this.GetType())) { EnsureClientsInitialized(context); ImageReference imageRef = GetPlatformVMImage(useWindowsImage: true); // Create resource group string rg1Name = ComputeManagementTestUtilities.GenerateName(TestPrefix) + 1; string as1Name = ComputeManagementTestUtilities.GenerateName("as"); string storageAccountName = ComputeManagementTestUtilities.GenerateName(TestPrefix); VirtualMachine inputVM1; try { // Create Storage Account, so that both the VMs can share it var storageAccountOutput = CreateStorageAccount(rg1Name, storageAccountName); VirtualMachine vm1 = CreateVM(rg1Name, as1Name, storageAccountOutput, imageRef, out inputVM1); var runCommandImput = new RunCommandInput() { CommandId = "RunPowerShellScript", Script = new List <string>() { "param(", " [string]$arg1,", " [string]$arg2", ")", "echo This is a sample script with parameters $arg1 $arg2" }, Parameters = new List <RunCommandInputParameter>() { new RunCommandInputParameter("arg1", "value1"), new RunCommandInputParameter("arg2", "value2"), } }; RunCommandResult result = m_CrpClient.VirtualMachines.RunCommand(rg1Name, vm1.Name, runCommandImput); Assert.NotNull(result); Assert.NotNull(result.Value); Assert.True(result.Value.Count > 0); } finally { // Cleanup the created resources. But don't wait since it takes too long, and it's not the purpose // of the test to cover deletion. CSM does persistent retrying over all RG resources. m_ResourcesClient.ResourceGroups.Delete(rg1Name); } } }
public static bool RunCommand(string fileName, string args = "", int timeOut = 60000) { RunCommandResult result = RunCommandWithResult(fileName, args, timeOut); if (result.ExitCode != 0) { TestContext.Out.WriteLine($"Command failed with: {result.ExitCode}"); return(false); } else { return(true); } }
// This method is used when the test is run in an OS that does not support AppExecutionAlias. E,g, our build machine. // There is not any existing API that'll activate a packaged app and wait for result, and not possible to capture the stdIn and stdOut. // This method tries to call Invoke-CommandInDesktopPackage PS command to make test executable run in packaged context. // Since Invoke-CommandInDesktopPackage just launches the executable and return, we use cmd pipe to get execution results. // The final constructed command will look like: // Invoke-CommandInDesktopPackage ...... -Command cmd.exe -Args '-c <cmd command>' // where <cmd command> will look like: "echo stdIn | appinst.exe args > stdout.txt 2> stderr.txt & echo %ERRORLEVEL% > exitcode.txt" // Then this method will read the piped result and return as RunCommandResult. public static RunCommandResult RunAICLICommandViaInvokeCommandInDesktopPackage(string command, string parameters, string stdIn = null, int timeOut = 60000) { string cmdCommandPiped = ""; if (!string.IsNullOrEmpty(stdIn)) { cmdCommandPiped += $"echo {stdIn} | "; } string workDirectory = GetRandomTestDir(); string exitCodeFile = Path.Combine(workDirectory, "ExitCode.txt"); string stdOutFile = Path.Combine(workDirectory, "StdOut.txt"); string stdErrFile = Path.Combine(workDirectory, "StdErr.txt"); cmdCommandPiped += $"{AICLIPath} {command} {parameters} > {stdOutFile} 2> {stdErrFile} & call echo %^ERRORLEVEL% > {exitCodeFile}"; string psCommand = $"Invoke-CommandInDesktopPackage -PackageFamilyName {Constants.AICLIPackageFamilyName} -AppId {Constants.AICLIAppId} -PreventBreakaway -Command cmd.exe -Args '/c \"{cmdCommandPiped}\"'"; var psInvokeResult = RunCommandWithResult("powershell", psCommand); if (psInvokeResult.ExitCode != 0) { // PS invocation failed, return result and no need to check piped output. return(psInvokeResult); } // The PS command just launches the app and immediately returns, we'll have to wait for up to the timeOut specified here int waitedTime = 0; while (!File.Exists(exitCodeFile) && waitedTime <= timeOut) { Thread.Sleep(1000); waitedTime += 1000; } if (waitedTime >= timeOut) { throw new TimeoutException("Command run timed out."); } RunCommandResult result = new RunCommandResult(); result.ExitCode = File.Exists(exitCodeFile) ? int.Parse(File.ReadAllText(exitCodeFile).Trim()) : unchecked ((int)0x80004005); result.StdOut = File.Exists(stdOutFile) ? File.ReadAllText(stdOutFile) : ""; result.StdErr = File.Exists(stdErrFile) ? File.ReadAllText(stdErrFile) : ""; return(result); }
public static RunCommandResult RunAICLICommandViaDirectProcess(string command, string parameters, string stdIn = null, int timeOut = 60000) { RunCommandResult result = new RunCommandResult(); Process p = new Process(); p.StartInfo = new ProcessStartInfo(AICLIPath, command + ' ' + parameters); p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardOutput = true; p.StartInfo.RedirectStandardError = true; if (!string.IsNullOrEmpty(stdIn)) { p.StartInfo.RedirectStandardInput = true; } p.Start(); if (!string.IsNullOrEmpty(stdIn)) { p.StandardInput.Write(stdIn); } if (p.WaitForExit(timeOut)) { result.ExitCode = p.ExitCode; result.StdOut = p.StandardOutput.ReadToEnd(); result.StdErr = p.StandardError.ReadToEnd(); TestContext.Out.WriteLine("Command run completed with exit code: " + result.ExitCode); if (!string.IsNullOrEmpty(result.StdErr)) { TestContext.Error.WriteLine("Command run error. Error: " + result.StdErr); } if (VerboseLogging && !string.IsNullOrEmpty(result.StdOut)) { TestContext.Out.WriteLine("Command run output. Output: " + result.StdOut); } } else { throw new TimeoutException("Command run timed out."); } return(result); }
public override void ExecuteCmdlet() { base.ExecuteCmdlet(); switch (ParameterSetName) { case IdParameterSet: { var resource = new ResourceIdentifier(Id); ResourceGroupName = resource.ResourceGroupName; Name = resource.ResourceName; break; } case InputObjectParameterSet: { var resource = new ResourceIdentifier(InputObject.Id); ResourceGroupName = resource.ResourceGroupName; Name = resource.ResourceName; break; } } var msg = $"{Name} in {ResourceGroupName}"; ConfirmAction(Force.IsPresent, string.Format(Resources.DoYouWantToExecuteCommandOnCluster, Name), string.Format(Resources.ExecutingCommandOnCluster, Name), msg, () => { ManagedCluster cluster = Client.ManagedClusters.Get(ResourceGroupName, Name); RunCommandRequest request = new RunCommandRequest { Command = Command, Context = GetCommandContext() }; if (cluster.AadProfile != null && cluster.AadProfile.Managed != null) { request.ClusterToken = GetClusterToken(); } RunCommandResult response = Client.ManagedClusters.RunCommand(ResourceGroupName, Name, request); WriteObject(PSMapper.Instance.Map <PSRunCommandResult>(response)); }); }
private void WriteInvalidOptionOrArgument(RunCommandResult runCommandResult) { var message = new StringBuilder(); message.AppendLine($"The Command could not be run. The following errors occured: "); foreach (var option in runCommandResult.InvalidOptions) { message.AppendLine($"- Invalid value for Option: {option.Key}"); } foreach (var argument in runCommandResult.InvalidArguments) { message.AppendLine($"- Invalid value for Argument: {argument.Key}"); } Console.WriteLine(message.ToString()); }
private void AnalyseRunCommandResult(RunCommandResult runCommandResult) { // Two cases: // 1. There are non optional parameters which are not marked as either Option or Argument. // This is an exception-case because that is a wrong declaration of a Command-method. // 2. There are invalid Options or Arguments. // This is NOT an exception-case because that is an error by the user which provided wrong input. // Case 1: if (runCommandResult.NonOptionalUnknownParameters.Any()) { WriteNonOptionalUnknownParametersError(runCommandResult.NonOptionalUnknownParameters); } // Case 2: if (runCommandResult.InvalidOptions.Any() || runCommandResult.InvalidArguments.Any()) { WriteInvalidOptionOrArgument(runCommandResult); } }
public void TestVMScaleSetVMOperations_RunCommand() { using (MockContext context = MockContext.Start(this.GetType())) { InitializeCommon(context); instanceId = "0"; bool passed = false; try { var storageAccountOutput = CreateStorageAccount(rgName, storageAccountName); VirtualMachineScaleSet vmScaleSet = CreateVMScaleSet_NoAsyncTracking( rgName, vmssName, storageAccountOutput, imageRef, out inputVMScaleSet, createWithManagedDisks: true); m_CrpClient.VirtualMachineScaleSetVMs.Start(rgName, vmScaleSet.Name, instanceId); RunCommandResult result = m_CrpClient.VirtualMachineScaleSetVMs.RunCommand(rgName, vmScaleSet.Name, instanceId, new RunCommandInput() { CommandId = "ipconfig" }); Assert.NotNull(result); Assert.NotNull(result.Value); Assert.True(result.Value.Count > 0); passed = true; } finally { // Cleanup the created resources. But don't wait since it takes too long, and it's not the purpose // of the test to cover deletion. CSM does persistent retrying over all RG resources. m_ResourcesClient.ResourceGroups.Delete(rgName); } Assert.True(passed); } }
public void TestVMOperations() { using (MockContext context = MockContext.Start(this.GetType().FullName)) { EnsureClientsInitialized(context); ImageReference imageRef = GetPlatformVMImage(useWindowsImage: true); // Create resource group string rg1Name = ComputeManagementTestUtilities.GenerateName(TestPrefix) + 1; string as1Name = ComputeManagementTestUtilities.GenerateName("as"); string storageAccountName = ComputeManagementTestUtilities.GenerateName(TestPrefix); VirtualMachine inputVM1; try { // Create Storage Account, so that both the VMs can share it var storageAccountOutput = CreateStorageAccount(rg1Name, storageAccountName); VirtualMachine vm1 = CreateVM(rg1Name, as1Name, storageAccountOutput, imageRef, out inputVM1); m_CrpClient.VirtualMachines.Start(rg1Name, vm1.Name); m_CrpClient.VirtualMachines.Redeploy(rg1Name, vm1.Name); m_CrpClient.VirtualMachines.Restart(rg1Name, vm1.Name); var runCommandImput = new RunCommandInput() { CommandId = "RunPowerShellScript", Script = new List <string>() { "param(", " [string]$arg1,", " [string]$arg2", ")", "echo This is a sample script with parameters $arg1 $arg2" }, Parameters = new List <RunCommandInputParameter>() { new RunCommandInputParameter("arg1", "value1"), new RunCommandInputParameter("arg2", "value2"), } }; RunCommandResult result = m_CrpClient.VirtualMachines.RunCommand(rg1Name, vm1.Name, runCommandImput); Assert.NotNull(result); Assert.NotNull(result.Value); Assert.True(result.Value.Count > 0); m_CrpClient.VirtualMachines.PowerOff(rg1Name, vm1.Name); m_CrpClient.VirtualMachines.Deallocate(rg1Name, vm1.Name); m_CrpClient.VirtualMachines.Generalize(rg1Name, vm1.Name); VirtualMachine ephemeralVM; string as2Name = as1Name + "_ephemeral"; CreateVM(rg1Name, as2Name, storageAccountName, imageRef, out ephemeralVM, hasManagedDisks: true, hasDiffDisks: true, vmSize: VirtualMachineSizeTypes.StandardDS1V2, osDiskStorageAccountType: StorageAccountTypes.StandardLRS, dataDiskStorageAccountType: StorageAccountTypes.StandardLRS); m_CrpClient.VirtualMachines.Reimage(rg1Name, ephemeralVM.Name, tempDisk: true); var captureParams = new VirtualMachineCaptureParameters { DestinationContainerName = ComputeManagementTestUtilities.GenerateName(TestPrefix), VhdPrefix = ComputeManagementTestUtilities.GenerateName(TestPrefix), OverwriteVhds = true }; var captureResponse = m_CrpClient.VirtualMachines.Capture(rg1Name, vm1.Name, captureParams); Assert.NotNull(captureResponse); Assert.True(captureResponse.Resources.Count > 0); string resource = captureResponse.Resources[0].ToString(); Assert.Contains(captureParams.DestinationContainerName.ToLowerInvariant(), resource.ToLowerInvariant()); Assert.Contains(captureParams.VhdPrefix.ToLowerInvariant(), resource.ToLowerInvariant()); Resource template = JsonConvert.DeserializeObject <Resource>(resource); string imageUri = template.Properties.StorageProfile.OSDisk.Image.Uri; Assert.False(string.IsNullOrEmpty(imageUri)); // Create 3rd VM from the captured image // TODO : Provisioning Time-out Issues VirtualMachine inputVM2; string as3Name = as1Name + "b"; VirtualMachine vm3 = CreateVM(rg1Name, as3Name, storageAccountOutput, imageRef, out inputVM2, vm => { vm.StorageProfile.ImageReference = null; vm.StorageProfile.OsDisk.Image = new VirtualHardDisk { Uri = imageUri }; vm.StorageProfile.OsDisk.Vhd.Uri = vm.StorageProfile.OsDisk.Vhd.Uri.Replace(".vhd", "copy.vhd"); vm.StorageProfile.OsDisk.OsType = OperatingSystemTypes.Windows; }, false, false); Assert.True(vm3.StorageProfile.OsDisk.Image.Uri == imageUri); } finally { // Cleanup the created resources. But don't wait since it takes too long, and it's not the purpose // of the test to cover deletion. CSM does persistent retrying over all RG resources. m_ResourcesClient.ResourceGroups.Delete(rg1Name); } } }
// This method is used when the test is run in an OS that does not support AppExecutionAlias. E,g, our build machine. // There is not any existing API that'll activate a packaged app and wait for result, and not possible to capture the stdIn and stdOut. // This method tries to call Invoke-CommandInDesktopPackage PS command to make test executable run in packaged context. // Since Invoke-CommandInDesktopPackage just launches the executable and return, we use cmd pipe to get execution results. // The final constructed command will look like: // Invoke-CommandInDesktopPackage ...... -Command cmd.exe -Args '-c <cmd command>' // where <cmd command> will look like: "echo stdIn | appinst.exe args > stdout.txt 2> stderr.txt & echo %ERRORLEVEL% > exitcode.txt" // Then this method will read the piped result and return as RunCommandResult. public static RunCommandResult RunAICLICommandViaInvokeCommandInDesktopPackage(string command, string parameters, string stdIn = null, int timeOut = 60000) { string cmdCommandPiped = ""; if (!string.IsNullOrEmpty(stdIn)) { cmdCommandPiped += $"echo {stdIn} | "; } string workDirectory = GetRandomTestDir(); string tempBatchFile = Path.Combine(workDirectory, "Batch.cmd"); string exitCodeFile = Path.Combine(workDirectory, "ExitCode.txt"); string stdOutFile = Path.Combine(workDirectory, "StdOut.txt"); string stdErrFile = Path.Combine(workDirectory, "StdErr.txt"); // First change the codepage so that the rest of the batch file works cmdCommandPiped += $"chcp 65001\n{AICLIPath} {command} {parameters} > {stdOutFile} 2> {stdErrFile}\necho %ERRORLEVEL% > {exitCodeFile}"; File.WriteAllText(tempBatchFile, cmdCommandPiped, new System.Text.UTF8Encoding(false)); string psCommand = $"Invoke-CommandInDesktopPackage -PackageFamilyName {Constants.AICLIPackageFamilyName} -AppId {Constants.AICLIAppId} -PreventBreakaway -Command cmd.exe -Args '/c \"{tempBatchFile}\"'"; var psInvokeResult = RunCommandWithResult("powershell", psCommand); if (psInvokeResult.ExitCode != 0) { // PS invocation failed, return result and no need to check piped output. return(psInvokeResult); } // The PS command just launches the app and immediately returns, we'll have to wait for up to the timeOut specified here int waitedTime = 0; while (!File.Exists(exitCodeFile) && waitedTime <= timeOut) { Thread.Sleep(1000); waitedTime += 1000; } if (waitedTime >= timeOut) { throw new TimeoutException($"Packaged winget command run timed out: {command} {parameters}"); } RunCommandResult result = new RunCommandResult(); // Sometimes the files are still in use; allow for this with a wait and retry loop. for (int retryCount = 0; retryCount < 4; ++retryCount) { bool success = false; try { result.ExitCode = File.Exists(exitCodeFile) ? int.Parse(File.ReadAllText(exitCodeFile).Trim()) : unchecked ((int)0x80004005); result.StdOut = File.Exists(stdOutFile) ? File.ReadAllText(stdOutFile) : ""; result.StdErr = File.Exists(stdErrFile) ? File.ReadAllText(stdErrFile) : ""; success = true; } catch (Exception e) { TestContext.Out.WriteLine("Failed to access files: " + e.Message); } if (success) { break; } else { Thread.Sleep(250); } } return(result); }
public async Task TestVMOperations() { EnsureClientsInitialized(DefaultLocation); ImageReference imageRef = await GetPlatformVMImage(useWindowsImage : true); // Create resource group string rg1Name = Recording.GenerateAssetName(TestPrefix) + 1; string as1Name = Recording.GenerateAssetName("as"); string storageAccountName = Recording.GenerateAssetName(TestPrefix); VirtualMachine inputVM1; // Create Storage Account, so that both the VMs can share it var storageAccountOutput = await CreateStorageAccount(rg1Name, storageAccountName); var returnTwovm = await CreateVM(rg1Name, as1Name, storageAccountOutput, imageRef); var vm1 = returnTwovm.Item1; inputVM1 = returnTwovm.Item2; await WaitForCompletionAsync(await VirtualMachinesOperations.StartStartAsync(rg1Name, vm1.Name)); await WaitForCompletionAsync(await VirtualMachinesOperations.StartRedeployAsync(rg1Name, vm1.Name)); await WaitForCompletionAsync(await VirtualMachinesOperations.StartRestartAsync(rg1Name, vm1.Name)); var runCommandImput = new RunCommandInput("RunPowerShellScript") { Script = { "param(", " [string]$arg1,", " [string]$arg2", ")", "echo This is a sample script with parameters $arg1 $arg2" }, Parameters = { new RunCommandInputParameter("arg1", "value1"), new RunCommandInputParameter("arg2", "value2"), } }; RunCommandResult result = (await WaitForCompletionAsync(await VirtualMachinesOperations.StartRunCommandAsync(rg1Name, vm1.Name, runCommandImput))).Value; Assert.NotNull(result); Assert.NotNull(result.Value); Assert.True(result.Value.Count > 0); await WaitForCompletionAsync(await VirtualMachinesOperations.StartPowerOffAsync(rg1Name, vm1.Name)); await WaitForCompletionAsync(await VirtualMachinesOperations.StartDeallocateAsync(rg1Name, vm1.Name)); await VirtualMachinesOperations.GeneralizeAsync(rg1Name, vm1.Name); VirtualMachine ephemeralVM; string as2Name = as1Name + "_ephemeral"; var returnTwoVM = await CreateVM(rg1Name, as2Name, storageAccountName, imageRef, hasManagedDisks : true, hasDiffDisks : true, vmSize : VirtualMachineSizeTypes.StandardDS5V2.ToString(), osDiskStorageAccountType : StorageAccountTypes.StandardLRS.ToString(), dataDiskStorageAccountType : StorageAccountTypes.StandardLRS.ToString()); ephemeralVM = returnTwoVM.Item2; await WaitForCompletionAsync(await VirtualMachinesOperations.StartReimageAsync(rg1Name, ephemeralVM.Name)); var captureParams = new VirtualMachineCaptureParameters(Recording.GenerateAssetName(TestPrefix), Recording.GenerateAssetName(TestPrefix), true); var captureResponse = await WaitForCompletionAsync(await VirtualMachinesOperations.StartCaptureAsync(rg1Name, vm1.Name, captureParams)); Assert.NotNull(captureResponse); Assert.True(captureResponse.Value.Resources.Count > 0); string resource = captureResponse.Value.Resources[0].ToString(); Assert.IsTrue(resource.ToLowerInvariant().Contains(captureParams.DestinationContainerName.ToLowerInvariant())); Assert.IsTrue(resource.ToLowerInvariant().Contains(captureParams.VhdPrefix.ToLowerInvariant())); Resource template = JsonSerializer.Deserialize <Resource>(resource); string imageUri = template.Properties.StorageProfile.OSDisk.Image.Uri; Assert.False(string.IsNullOrEmpty(imageUri)); // Create 3rd VM from the captured image // TODO : Provisioning Time-out Issues VirtualMachine inputVM2; string as3Name = as1Name + "b"; returnTwovm = await CreateVM(rg1Name, as3Name, storageAccountOutput, imageRef, vm => { vm.StorageProfile.ImageReference = null; vm.StorageProfile.OsDisk.Image = new VirtualHardDisk { Uri = imageUri }; vm.StorageProfile.OsDisk.Vhd.Uri = vm.StorageProfile.OsDisk.Vhd.Uri.Replace(".vhd", "copy.vhd"); vm.StorageProfile.OsDisk.OsType = OperatingSystemTypes.Windows; }, false, false); var vm3 = returnTwovm.Item1; inputVM2 = returnTwovm.Item2; Assert.True(vm3.StorageProfile.OsDisk.Image.Uri == imageUri); }
} //从左到右,第一位:代表大版本迭代 ,第二位:代表大版本下的大更新 第三位:代表bug修复次数 /// <summary> /// 命令执行方法约定 /// </summary> public void TryExecute() { try { ShowCommandLog("----------------------" + DateTime.Now + ":开始执行命令-----------------------------------------"); DateTime startTime = DateTime.Now; Stopwatch sw = new Stopwatch(); RunCommandResult r; sw.Start(); try { r = Execute(); int retryCount = 0; while (r.ExecuteStatus == ExecuteStatus.ExecuteException && retryCount < this.CommandDetail.maxexeceptionretrycount) { int ct = retryCount + 1; ShowCommandLog("**********第" + ct + "次重试 Start**********"); r = Execute(); retryCount += 1; ShowCommandLog("**********第" + ct + "次重试 End**********"); } r.RetryCount += retryCount; } catch (Exception ex) { r = new RunCommandResult() { ExecuteStatus = ExecuteStatus.ExecuteException, Message = ex.Message, Ex = ex }; ShowCommandLog("执行命令异常,异常信息:" + JsonConvert.SerializeObject(ex)); } sw.Stop(); ShowCommandLog("----------------------" + DateTime.Now + ":执行命令完成-----------------------------------------"); DateTime endTime = DateTime.Now; TimeSpan ts = sw.Elapsed; long times = sw.ElapsedMilliseconds / 1000;//秒 AddCommandExecuteLogRequest addLogReq = new AddCommandExecuteLogRequest() { NodeId = GlobalNodeConfig.NodeID, Source = Source.Node, CommandEndTime = endTime.ToString("yyyy-MM-dd HH:mm:ss"), CommandExecuteLog = strLog.ToString(), CommandParams = JsonConvert.SerializeObject(this.AppConfig), CommandQueueId = CommandQueue.id, CommandResult = JsonConvert.SerializeObject(r), ExecuteStatus = (int)r.ExecuteStatus, CommandStartTime = startTime.ToString("yyyy-MM-dd HH:mm:ss"), TotalTime = times.ToString(), CommandDetailId = CommandDetail.id, }; //上报命令执行日志和执行结果 var r2 = NodeProxy.PostToServer <EmptyResponse, AddCommandExecuteLogRequest>(ProxyUrl.AddCommandExecuteLog_Url, addLogReq); if (r2.Status != ResponesStatus.Success) { ShowCommandLog("上报命令(" + CommandDetail.commandmainclassname + ")的执行日志失败,请求地址:" + ProxyUrl.AddCommandExecuteLog_Url + ",请求参数:" + JsonConvert.SerializeObject(addLogReq) + ",服务器返回参数:" + JsonConvert.SerializeObject(r2)); } if (r.ExecuteStatus == ExecuteStatus.ExecuteException)//命令执行异常,报警 { string title = "当前命令队列(" + CommandQueue.id + ")执行失败,请及时处理"; StringBuilder strContent = new StringBuilder(); strContent.AppendLine("节点编号:" + GlobalNodeConfig.NodeID); strContent.AppendLine("命令队列编号/命令编号:" + CommandQueue.id + "/" + CommandDetail.id.ToString()); strContent.AppendLine("命令执行参数:" + JsonConvert.SerializeObject(this.AppConfig)); strContent.AppendLine("命令执行起/止时间:" + startTime.ToString("yyyy-MM-dd HH:mm:ss") + "/" + endTime.ToString("yyyy-MM-dd HH:mm:ss")); strContent.AppendLine("命令执行耗时(s):" + times.ToString()); strContent.AppendLine("命令执行结果,状态:" + r.ExecuteStatus.description() + ",执行结果:" + JsonConvert.SerializeObject(r)); AlarmHelper.AlarmAsync(GlobalNodeConfig.NodeInfo.isenablealarm, (AlarmType)GlobalNodeConfig.NodeInfo.alarmtype, GlobalNodeConfig.Alarm, title, strContent.ToString()); } } catch (Exception ex) { ShowCommandLog("执行命令异常,异常信息:" + JsonConvert.SerializeObject(ex)); ShowCommandLog("----------------------" + DateTime.Now + ":执行命令完成-----------------------------------------"); log.Error(strLog.ToString()); } finally { strLog.Clear();//正常执行完情况strLog日志 } }