public Registration_Form() { InitializeComponent(); db = new DBFunction(); student = new Student(); su = new StringUtil(); enterBtnPress = false; }
public Export_Form() { InitializeComponent(); db = new DBFunction(); su = new StringUtil(); db.LoadEventList(); eventList = db.GetEventList; FormPrepare(); }
public Register_Form() { InitializeComponent(); db = new DBFunction(); student = new Student(); eventList = new List<Event>(); su = new StringUtil(); btn_Add.Hide(); db.LoadEventList(); eventList = db.GetEventList; id = new Int32[eventList.Count]; name = new String[eventList.Count]; FormPrepare(); }
// renders input view items private string RenderItems(IEnumerable <Item> items) { Assert.ArgumentNotNull((object)items, "items"); HtmlTextWriter writer = new HtmlTextWriter((TextWriter) new StringWriter()); writer.Write("<ul id='sort-list'>"); foreach (Item obj in items) { bool flag = IsEditable(obj); string sortBy = obj.Fields["First Name"].Value + " " + obj.Fields["Last Name"].Value; string jobTitle = obj.Fields["Job Title"].Value.Replace("'", ""); string str = !flag?Translate.Text("You cannot edit this item because you do not have write access to it.") : sortBy; writer.Write("<li id='{0}' class='sort-item {1}' title='{2}'>", (object)obj.ID.ToShortID(), flag ? (object)"editable" : (object)"non-editable", (object)jobTitle); writer.Write("<img src='/sitecore/shell/Themes/Standard/Images/draghandle9x15.png' class='drag-handle' />"); writer.Write("<img src='{0}' class='item-icon' />", (object)Images.GetThemedImageSource(obj.Appearance.Icon, ImageDimension.id16x16)); writer.Write("<span unselectable='on' class='item-name'>{0}</span>", "Name: " + (object)StringUtil.Clip(sortBy, 40, true)); writer.Write("</li>"); } writer.Write("</ul>"); return(writer.InnerWriter.ToString()); }
public async Task StartContainersAsync(IExecutionContext executionContext, object data) { Trace.Entering(); ArgUtil.NotNull(executionContext, nameof(executionContext)); List <ContainerInfo> containers = data as List <ContainerInfo>; ArgUtil.NotNull(containers, nameof(containers)); containers = containers.FindAll(c => c != null); // attempt to mitigate issue #11902 filed in azure-pipelines-task repo // Check whether we are inside a container. // Our container feature requires to map working directory from host to the container. // If we are already inside a container, we will not able to find out the real working direcotry path on the host. if (PlatformUtil.RunningOnRHEL6) { // Red Hat and CentOS 6 do not support the container feature throw new NotSupportedException(StringUtil.Loc("AgentDoesNotSupportContainerFeatureRhel6")); } ThrowIfAlreadyInContainer(); ThrowIfWrongWindowsVersion(executionContext); // Check docker client/server version DockerVersion dockerVersion = await _dockerManger.DockerVersion(executionContext); ArgUtil.NotNull(dockerVersion.ServerVersion, nameof(dockerVersion.ServerVersion)); ArgUtil.NotNull(dockerVersion.ClientVersion, nameof(dockerVersion.ClientVersion)); Version requiredDockerEngineAPIVersion = PlatformUtil.RunningOnWindows ? new Version(1, 30) // Docker-EE version 17.6 : new Version(1, 35); // Docker-CE version 17.12 if (dockerVersion.ServerVersion < requiredDockerEngineAPIVersion) { throw new NotSupportedException(StringUtil.Loc("MinRequiredDockerServerVersion", requiredDockerEngineAPIVersion, _dockerManger.DockerPath, dockerVersion.ServerVersion)); } if (dockerVersion.ClientVersion < requiredDockerEngineAPIVersion) { throw new NotSupportedException(StringUtil.Loc("MinRequiredDockerClientVersion", requiredDockerEngineAPIVersion, _dockerManger.DockerPath, dockerVersion.ClientVersion)); } // Clean up containers left by previous runs executionContext.Debug($"Delete stale containers from previous jobs"); var staleContainers = await _dockerManger.DockerPS(executionContext, $"--all --quiet --no-trunc --filter \"label={_dockerManger.DockerInstanceLabel}\""); foreach (var staleContainer in staleContainers) { int containerRemoveExitCode = await _dockerManger.DockerRemove(executionContext, staleContainer); if (containerRemoveExitCode != 0) { executionContext.Warning($"Delete stale containers failed, docker rm fail with exit code {containerRemoveExitCode} for container {staleContainer}"); } } executionContext.Debug($"Delete stale container networks from previous jobs"); int networkPruneExitCode = await _dockerManger.DockerNetworkPrune(executionContext); if (networkPruneExitCode != 0) { executionContext.Warning($"Delete stale container networks failed, docker network prune fail with exit code {networkPruneExitCode}"); } // We need to pull the containers first before setting up the network foreach (var container in containers) { await PullContainerAsync(executionContext, container); } // Create local docker network for this job to avoid port conflict when multiple agents run on same machine. // All containers within a job join the same network await CreateContainerNetworkAsync(executionContext, _containerNetwork); containers.ForEach(container => container.ContainerNetwork = _containerNetwork); foreach (var container in containers) { await StartContainerAsync(executionContext, container); } foreach (var container in containers.Where(c => !c.IsJobContainer)) { await ContainerHealthcheck(executionContext, container); } }
private async Task DownloadArtifacts(IExecutionContext executionContext, IList <AgentArtifactDefinition> agentArtifactDefinitions, string artifactsWorkingFolder) { Trace.Entering(); CreateArtifactsFolder(executionContext, artifactsWorkingFolder); executionContext.Output(StringUtil.Loc("RMDownloadingArtifact")); foreach (AgentArtifactDefinition agentArtifactDefinition in agentArtifactDefinitions) { // We don't need to check if its old style artifact anymore. All the build data has been fixed and all the build artifact has Alias now. ArgUtil.NotNullOrEmpty(agentArtifactDefinition.Alias, nameof(agentArtifactDefinition.Alias)); var extensionManager = HostContext.GetService <IExtensionManager>(); IArtifactExtension extension = (extensionManager.GetExtensions <IArtifactExtension>()).FirstOrDefault(x => agentArtifactDefinition.ArtifactType == x.ArtifactType); if (extension == null) { throw new InvalidOperationException(StringUtil.Loc("RMArtifactTypeNotSupported", agentArtifactDefinition.ArtifactType)); } Trace.Info($"Found artifact extension of type {extension.ArtifactType}"); executionContext.Output(StringUtil.Loc("RMStartArtifactsDownload")); ArtifactDefinition artifactDefinition = ConvertToArtifactDefinition(agentArtifactDefinition, executionContext, extension); executionContext.Output(StringUtil.Loc("RMArtifactDownloadBegin", agentArtifactDefinition.Alias, agentArtifactDefinition.ArtifactType)); // Get the local path where this artifact should be downloaded. string downloadFolderPath = Path.GetFullPath(Path.Combine(artifactsWorkingFolder, agentArtifactDefinition.Alias ?? string.Empty)); // download the artifact to this path. RetryExecutor retryExecutor = new RetryExecutor(); retryExecutor.ShouldRetryAction = (ex) => { executionContext.Output(StringUtil.Loc("RMErrorDuringArtifactDownload", ex)); bool retry = true; if (ex is ArtifactDownloadException) { retry = false; } else { executionContext.Output(StringUtil.Loc("RMRetryingArtifactDownload")); Trace.Warning(ex.ToString()); } return(retry); }; await retryExecutor.ExecuteAsync( async() => { var releaseFileSystemManager = HostContext.GetService <IReleaseFileSystemManager>(); executionContext.Output(StringUtil.Loc("RMEnsureArtifactFolderExistsAndIsClean", downloadFolderPath)); releaseFileSystemManager.EnsureEmptyDirectory(downloadFolderPath, executionContext.CancellationToken); await extension.DownloadAsync(executionContext, artifactDefinition, downloadFolderPath); }); executionContext.Output(StringUtil.Loc("RMArtifactDownloadFinished", agentArtifactDefinition.Alias)); } executionContext.Output(StringUtil.Loc("RMArtifactsDownloadFinished")); }
// parameters: // strRequirFuncList 要求必须具备的功能列表。逗号间隔的字符串 // strStyle 风格 // reinput 如果序列号不满足要求,是否直接出现对话框让用户重新输入序列号 // reset 执行重设序列号任务。意思就是无论当前序列号是否可用,都直接出现序列号对话框 // return: // -1 出错 // 0 正确 public static int VerifySerialCode( string strTitle, string strRequirFuncList, string strStyle, out string strError) { strError = ""; int nRet = 0; bool bReinput = StringUtil.IsInList("reinput", strStyle); bool bReset = StringUtil.IsInList("reset", strStyle); string strFirstMac = ""; List <string> macs = SerialCodeForm.GetMacAddress(); if (macs.Count != 0) { strFirstMac = macs[0]; } string strSerialCode = ClientInfo.Config.Get("sn", "sn", ""); // 首次运行 if (string.IsNullOrEmpty(strSerialCode) == true) { } REDO_VERIFY: if (bReset == false && SerialNumberMode != "must" && strSerialCode == "community") { if (string.IsNullOrEmpty(strRequirFuncList) == true) { CommunityMode = true; ClientInfo.Config.Set("main_form", "last_mode", "community"); return(0); } } if (bReset == true || CheckFunction(GetEnvironmentString(""), strRequirFuncList) == false || MatchLocalString(strSerialCode) == false || String.IsNullOrEmpty(strSerialCode) == true) { if (bReinput == false && bReset == false) { strError = "序列号无效"; return(-1); } if (bReset == false) { if (String.IsNullOrEmpty(strSerialCode) == false) { MessageBox.Show(MainForm, "序列号无效。请重新输入"); } else if (CheckFunction(GetEnvironmentString(""), strRequirFuncList) == false) { MessageBox.Show(MainForm, "序列号中 function 参数无效。请重新输入"); } } // 出现设置序列号对话框 nRet = ResetSerialCode( strTitle, false, strSerialCode, GetEnvironmentString(strFirstMac)); if (nRet == 0) { strError = "放弃"; return(-1); } strSerialCode = ClientInfo.Config.Get("sn", "sn", ""); goto REDO_VERIFY; } return(0); }
internal override void ToCompactString(StringBuilder builder) { builder.Append('<'); StringUtil.ToCommaSeparatedString(builder, m_members); builder.Append('>'); }
public async Task StartContainersAsync(IExecutionContext executionContext, object data) { Trace.Entering(); ArgUtil.NotNull(executionContext, nameof(executionContext)); List <ContainerInfo> containers = data as List <ContainerInfo>; ArgUtil.NotNull(containers, nameof(containers)); // Check whether we are inside a container. // Our container feature requires to map working directory from host to the container. // If we are already inside a container, we will not able to find out the real working direcotry path on the host. #if OS_WINDOWS // service CExecSvc is Container Execution Agent. ServiceController[] scServices = ServiceController.GetServices(); if (scServices.Any(x => String.Equals(x.ServiceName, "cexecsvc", StringComparison.OrdinalIgnoreCase) && x.Status == ServiceControllerStatus.Running)) { throw new NotSupportedException(StringUtil.Loc("AgentAlreadyInsideContainer")); } #elif OS_RHEL6 // Red Hat and CentOS 6 do not support the container feature throw new NotSupportedException(StringUtil.Loc("AgentDoesNotSupportContainerFeatureRhel6")); #else try { var initProcessCgroup = File.ReadLines("/proc/1/cgroup"); if (initProcessCgroup.Any(x => x.IndexOf(":/docker/", StringComparison.OrdinalIgnoreCase) >= 0)) { throw new NotSupportedException(StringUtil.Loc("AgentAlreadyInsideContainer")); } } catch (Exception ex) when(ex is FileNotFoundException || ex is DirectoryNotFoundException) { // if /proc/1/cgroup doesn't exist, we are not inside a container } #endif #if OS_WINDOWS // Check OS version (Windows server 1803 is required) object windowsInstallationType = Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion", "InstallationType", defaultValue: null); ArgUtil.NotNull(windowsInstallationType, nameof(windowsInstallationType)); object windowsReleaseId = Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion", "ReleaseId", defaultValue: null); ArgUtil.NotNull(windowsReleaseId, nameof(windowsReleaseId)); executionContext.Debug($"Current Windows version: '{windowsReleaseId} ({windowsInstallationType})'"); if (int.TryParse(windowsReleaseId.ToString(), out int releaseId)) { if (!windowsInstallationType.ToString().StartsWith("Server", StringComparison.OrdinalIgnoreCase) || releaseId < 1803) { throw new NotSupportedException(StringUtil.Loc("ContainerWindowsVersionRequirement")); } } else { throw new ArgumentOutOfRangeException(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ReleaseId"); } #endif // Check docker client/server version DockerVersion dockerVersion = await _dockerManger.DockerVersion(executionContext); ArgUtil.NotNull(dockerVersion.ServerVersion, nameof(dockerVersion.ServerVersion)); ArgUtil.NotNull(dockerVersion.ClientVersion, nameof(dockerVersion.ClientVersion)); #if OS_WINDOWS Version requiredDockerEngineAPIVersion = new Version(1, 30); // Docker-EE version 17.6 #else Version requiredDockerEngineAPIVersion = new Version(1, 35); // Docker-CE version 17.12 #endif if (dockerVersion.ServerVersion < requiredDockerEngineAPIVersion) { throw new NotSupportedException(StringUtil.Loc("MinRequiredDockerServerVersion", requiredDockerEngineAPIVersion, _dockerManger.DockerPath, dockerVersion.ServerVersion)); } if (dockerVersion.ClientVersion < requiredDockerEngineAPIVersion) { throw new NotSupportedException(StringUtil.Loc("MinRequiredDockerClientVersion", requiredDockerEngineAPIVersion, _dockerManger.DockerPath, dockerVersion.ClientVersion)); } // Clean up containers left by previous runs executionContext.Debug($"Delete stale containers from previous jobs"); var staleContainers = await _dockerManger.DockerPS(executionContext, $"--all --quiet --no-trunc --filter \"label={_dockerManger.DockerInstanceLabel}\""); foreach (var staleContainer in staleContainers) { int containerRemoveExitCode = await _dockerManger.DockerRemove(executionContext, staleContainer); if (containerRemoveExitCode != 0) { executionContext.Warning($"Delete stale containers failed, docker rm fail with exit code {containerRemoveExitCode} for container {staleContainer}"); } } executionContext.Debug($"Delete stale container networks from previous jobs"); int networkPruneExitCode = await _dockerManger.DockerNetworkPrune(executionContext); if (networkPruneExitCode != 0) { executionContext.Warning($"Delete stale container networks failed, docker network prune fail with exit code {networkPruneExitCode}"); } // Create local docker network for this job to avoid port conflict when multiple agents run on same machine. // All containers within a job join the same network await CreateContainerNetworkAsync(executionContext, _containerNetwork); containers.ForEach(container => container.ContainerNetwork = _containerNetwork); foreach (var container in containers) { await StartContainerAsync(executionContext, container); } foreach (var container in containers.Where(c => !c.IsJobContainer)) { await ContainerHealthcheck(executionContext, container); } }
private TrackingConfig LoadIfExists( IExecutionContext executionContext, string file) { Trace.Entering(); Trace.Verbose($"Loading {file}"); // The tracking config will not exist for a new definition. if (!File.Exists(file)) { Trace.Verbose($"Tracking file does not exist: {file}"); return null; } TrackingConfig result = null; // Load the content and distinguish between tracking config file // version 1 and file version 2. string content = File.ReadAllText(file); string fileFormatVersionJsonProperty = StringUtil.Format( @"""{0}""", TrackingConfig.FileFormatVersionJsonProperty); if (content.Contains(fileFormatVersionJsonProperty)) { // The config is the new format. Trace.Verbose("Parsing new tracking config format."); result = JsonConvert.DeserializeObject<TrackingConfig>(content); if (result != null) { // if RepositoryTrackingInfo is empty, then we should create an entry so the rest // of the logic after this will act correctly if (result.RepositoryTrackingInfo.Count == 0) { result.RepositoryTrackingInfo.Add(new Build.RepositoryTrackingInfo { Identifier = RepositoryUtil.DefaultPrimaryRepositoryName, RepositoryType = result.RepositoryType, RepositoryUrl = result.RepositoryUrl, SourcesDirectory = result.SourcesDirectory, }); } } } else { // Attempt to parse the legacy format. Trace.Verbose("Parsing legacy tracking config format."); var legacyTrackingConfig = LegacyTrackingConfig.TryParse(content); if (legacyTrackingConfig == null) { executionContext.Warning(StringUtil.Loc("UnableToParseBuildTrackingConfig0", content)); } else { // Convert legacy format to the new format. result = ConvertToNewFormat( executionContext, legacyTrackingConfig, RepositoryUtil.GetCloneDirectory(legacyTrackingConfig.RepositoryUrl), RepositoryUtil.GuessRepositoryType(legacyTrackingConfig.RepositoryUrl)); } } if (result != null) { result.FileLocation = file; } return result; }
/// <summary> /// 关闭庆功宴 /// </summary> public void CloseQingGongYan() { // 销毁怪物 if (null != QingGongYanMonster) { GameManager.MonsterMgr.DeadMonsterImmediately(QingGongYanMonster); QingGongYanMonster = null; } QingGongYanOpenFlag = false; // log it... // 档次没有配置 QingGongYanInfo InfoData = GetInfoData(); if (null != InfoData) { return; } if (InfoData.ZuanShiCoe <= 0) { return; } int JoinMoney = Convert.ToInt32(GameManager.GameConfigMgr.GetGameConfigItemStr("qinggongyan_joinmoney", "0")); if (JoinMoney <= 0) { return; } int ZuanShiAward = JoinMoney / InfoData.ZuanShiCoe; if (ZuanShiAward <= 0) { return; } int DBRoleID = Convert.ToInt32(GameManager.GameConfigMgr.GetGameConfigItemStr("qinggongyan_roleid", "0")); if (DBRoleID <= 0) { return; } //string sContent = "您在2015年02月02日 20:00举办的宴会已成功结束,共获得收益200钻石。"; string sContent = string.Format("您在{0:0000}年{1:00}月{2:00}日 {3}举办的宴会已成功结束,共获得收益{4}钻石。", DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, InfoData.BeginTime); Global.UseMailGivePlayerAward3(DBRoleID, null, sContent, "庆功宴", ZuanShiAward); // 清空记录 GameManager.GameConfigMgr.SetGameConfigItem("qinggongyan_roleid", "0"); GameManager.GameConfigMgr.SetGameConfigItem("qinggongyan_startday", "0"); GameManager.GameConfigMgr.SetGameConfigItem("qinggongyan_grade", "0"); GameManager.GameConfigMgr.SetGameConfigItem("qinggongyan_joincount", "0"); GameManager.GameConfigMgr.SetGameConfigItem("qinggongyan_joinmoney", "0"); string roleName = GameManager.GameConfigMgr.GetGameConfigItemStr("qinggongyan_rolename", "神秘人"); string broadCastMsg = StringUtil.substitute(Global.GetLang("{0}举办的庆功宴刚刚结束了,大家快去参加呀"), roleName); //播放用户行为消息 Global.BroadcastRoleActionMsg(null, RoleActionsMsgTypes.Bulletin, broadCastMsg, true, GameInfoTypeIndexes.Hot, ShowGameInfoTypes.SysHintAndChatBox); }
public override string ToString() { return(StringUtil.FormatInvariant("{0}({1})", ExprType, _children)); }
// parameters: // reader_name_list 读卡器名字列表。形态为 "*" 或 "name1,name2" 或 "name1:1|2|3|4,name2" // style 如果为 "getTagInfo",表示要在结果中返回 TagInfo ListTagsResult _listTags(string reader_name_list, string style) { InventoryResult result = new InventoryResult(); if (Program.MainForm.ErrorState != "normal") { return new ListTagsResult { Value = -1, ErrorInfo = $"{Program.MainForm.ErrorStateInfo}", ErrorCode = $"state:{Program.MainForm.ErrorState}" } } ; List <OneTag> tags = new List <OneTag>(); // uid --> OneTag Hashtable uid_table = new Hashtable(); foreach (Reader reader in Program.Rfid.Readers) { #if NO if (reader_name == "*" || reader.Name == reader_name) { } else { continue; } #endif // 顺便要从 reader_name_list 中解析出天线部分 if (Reader.MatchReaderName(reader_name_list, reader.Name, out string antenna_list) == false) { continue; } InventoryResult inventory_result = Program.Rfid.Inventory(reader.Name, antenna_list, style // "" ); /* * // testing * inventory_result.Value = -1; * inventory_result.ErrorInfo = "模拟 inventory 出错"; * inventory_result.ErrorCode = "test"; */ if (inventory_result.Value == -1) { // TODO: 统计单位时间内出错的总数,如果超过一定限度则重新初始化全部读卡器 _ = _compactLog.Add("inventory 出错: {0}", new object[] { inventory_result.ErrorInfo }); _inventoryErrorCount++; // 每隔一段时间写入日志一次 if (DateTime.Now - _lastCompactTime > _compactLength) { _compactLog?.WriteToLog((text) => { Log.Logger.Error(text); Program.MainForm.OutputHistory(text, 2); }); _lastCompactTime = DateTime.Now; if (_inventoryErrorCount > 10) { // 发出信号,重启 Program.MainForm.RestartRfidDriver($"因最近阶段内 inventory 出错次数为 {_inventoryErrorCount}"); _inventoryErrorCount = 0; } } return(new ListTagsResult { Value = -1, ErrorInfo = inventory_result.ErrorInfo, ErrorCode = inventory_result.ErrorCode }); } foreach (InventoryInfo info in inventory_result.Results) { OneTag tag = null; if (uid_table.ContainsKey(info.UID)) { // 重复出现的,追加 读卡器名字 tag = (OneTag)uid_table[info.UID]; tag.ReaderName += "," + reader.Name; } else { // 首次出现 tag = new OneTag { Protocol = info.Protocol, ReaderName = reader.Name, UID = info.UID, DSFID = info.DsfID, AntennaID = info.AntennaID, // 2019/9/25 // InventoryInfo = info // 有些冗余的字段 }; /* * // testing * tag.AntennaID = _currenAntenna; * if (DateTime.Now - _lastTime > TimeSpan.FromSeconds(5)) * { * _currenAntenna++; * if (_currenAntenna > 50) * _currenAntenna = 1; * _lastTime = DateTime.Now; * } */ uid_table[info.UID] = tag; tags.Add(tag); } if (StringUtil.IsInList("getTagInfo", style) && tag.TagInfo == null) { // TODO: 这里要利用 Hashtable 缓存 GetTagInfoResult result0 = Program.Rfid.GetTagInfo(reader.Name, info); if (result0.Value == -1) { tag.TagInfo = null; // TODO: 如何报错?写入操作历史? // $"读取标签{info.UID}信息时出错:{result0.ToString()}" } else { tag.TagInfo = result0.TagInfo; } } #if NO GetTagInfoResult result0 = Program.Rfid.GetTagInfo(reader.Name, info); if (result0.Value == -1) { // TODO: 如何报错?写入操作历史? Program.MainForm.OutputText($"读取标签{info.UID}信息时出错:{result0.ToString()}", 2); continue; } LogicChip chip = LogicChip.From(result0.TagInfo.Bytes, (int)result0.TagInfo.BlockSize, "" // result0.TagInfo.LockStatus ); Element pii = chip.FindElement(ElementOID.PII); if (pii == null) { Program.MainForm.Invoke((Action)(() => { // 发送 UID SendKeys.SendWait($"uid:{info.UID}\r"); })); } else { Program.MainForm.Invoke((Action)(() => { // 发送 PII SendKeys.SendWait($"pii:{pii.Text}\r"); })); } #endif } } return(new ListTagsResult { Results = tags }); #if NO InventoryResult result = new InventoryResult(); List <OneTag> tags = new List <OneTag>(); _lockTagList.EnterReadLock(); try { foreach (OneTag tag in _tagList) { if (reader_name == "*" || tag.ReaderName == reader_name) { tags.Add(tag); } } return(new ListTagsResult { Results = tags }); } finally { _lockTagList.ExitReadLock(); } #endif }
/* * // 兼容以前的 API * public NormalResult SetEAS( * string reader_name, * string tag_name, * bool enable) * { * return SetEAS(reader_name, tag_name, 0, enable); * } */ // parameters: // reader_name 读卡器名字。也可以为 "*",表示所有读卡器 // tag_name 标签名字。为 pii:xxxx 或者 uid:xxxx 形态。若没有冒号,则默认为是 UID // style 如果标签所在的天线不是 1 号天线,要用 antenna:1|2|3|4 来进行调用(列出一个或者多个可能的天线号) // return result.Value: // -1 出错 // 0 没有找到指定的标签 // 1 找到,并成功修改 EAS public NormalResult SetEAS( string reader_name, string tag_name, uint antenna_id, bool enable) { string uid = ""; List <string> parts = StringUtil.ParseTwoPart(tag_name, ":"); if (parts[0] == "pii") { // 2019/9/24 // 天线列表 // 1|2|3|4 这样的形态 FindTagResult result = Program.Rfid.FindTagByPII( reader_name, InventoryInfo.ISO15693, // 只有 ISO15693 才有 EAS (2019/8/28) antenna_id.ToString(), parts[1]); if (result.Value != 1) { return new NormalResult { Value = result.Value, ErrorInfo = result.ErrorInfo, ErrorCode = result.ErrorCode } } ; uid = result.UID; reader_name = result.ReaderName; // 假如最初 reader_name 为 '*',此处可以改为具体的读卡器名字,会加快后面设置的速度 } else if (parts[0] == "uid" || string.IsNullOrEmpty(parts[0])) { uid = parts[1]; } else { return new NormalResult { Value = -1, ErrorInfo = $"未知的 tag_name 前缀 '{parts[0]}'", ErrorCode = "unknownPrefix" } }; { // TODO: 检查 uid 字符串内容是否合法。应为 hex 数字 // return result.Value // -1 出错 // 0 成功 NormalResult result = Program.Rfid.SetEAS( reader_name, uid, antenna_id, enable); if (result.Value == -1) { return(result); } return(new NormalResult { Value = 1 }); } }
// 增加了无标签时延迟等待功能。敏捷响应 // parameters: // style 风格。逗号间隔的字符串内容 // session:会话ID // dont_delay 不根据 session 来进行探测、延迟。也就是说确保要做一次 invetnory 并且立即返回 public ListTagsResult ListTags(string reader_name, string style) { if (Program.Rfid.Pause) { return new ListTagsResult { Value = -1, ErrorInfo = "RFID 功能处于暂停状态", ErrorCode = "paused" } } ; string lockNameList = StringUtil.GetParameterByPrefix(style, "getLockState"); if (lockNameList != null) { lockNameList = StringUtil.UnescapeString(lockNameList); } bool output_time = false; Program.Rfid.IncApiCount(); try { if (Program.Rfid.Pause) { return new ListTagsResult { Value = -1, ErrorInfo = "RFID 功能处于暂停状态", ErrorCode = "paused" } } ; // 2019/12/15 bool dont_delay = StringUtil.IsInList("dont_delay", style); string session_id = StringUtil.GetParameterByPrefix(style, "session"); if (output_time) { Program.MainForm.OutputHistory($"session start: {session_id}, reader_name={reader_name}, style={style}"); } TimeSpan length = TimeSpan.FromSeconds(2); ListTagsResult result = null; GetLockStateResult lock_result = null; string current_uids = ""; DateTime start = DateTime.Now; while (DateTime.Now - start < length || result == null) { Stopwatch watch = null; // 执行 inventory if (string.IsNullOrEmpty(reader_name) == false) { if (output_time) { watch = new Stopwatch(); } else { watch = null; } watch?.Start(); result = _listTags(reader_name, style); // testing //if (reader_name.StartsWith("M201")) // Thread.Sleep(5000); watch?.Stop(); if (output_time) { Program.MainForm.OutputHistory($"{session_id} inventory time:{watch.Elapsed.TotalSeconds}, count:{result.Results?.Count}"); } } else { if (output_time) { Program.MainForm.OutputHistory($"{session_id} inventory skipped"); } result = new ListTagsResult(); } // 执行门锁状态获取 // 目前是 1:1 次数分配 if (lockNameList != null) { Thread.Sleep(100); if (output_time) { watch = new Stopwatch(); } else { watch = null; } watch?.Start(); lock_result = GetShelfLockState(lockNameList); watch?.Stop(); if (output_time) { Program.MainForm.OutputHistory($"{session_id} getLockState time:{watch.Elapsed.TotalSeconds}, count:{lock_result.States?.Count}"); } // 从此开始 result.GetLockStateResult 就有值了 result.GetLockStateResult = lock_result; } else { if (output_time) { Program.MainForm.OutputHistory($"{session_id} getLockState skipped"); } } // 判断 inventory 结果 if (string.IsNullOrEmpty(reader_name) == false) { // 立即返回 if (dont_delay) { return(result); } if (result != null && result.Results != null) { current_uids = BuildUids(result.Results); } else { current_uids = ""; } // TODO: 这里的比较应该按照 Session 来进行 // 只要本次和上次 tag 数不同,立刻就返回 if (CompareLastUids(session_id, current_uids)) { SetLastUids(session_id, current_uids); return(result); } if (result.Value == -1) { return(result); } } // 判断门锁状态 if (lockNameList != null) { // 这里的疑问是,如果 _listTags 没有出错,是否应该坚持返回正确结果? if (lock_result.Value != -1) { string current_states = BuildStateString(lock_result.States); if (CompareLastUids(session_id + "_lock", current_states)) { SetLastUids(session_id + "_lock", current_states); return(result); } } } /* * // TODO: 如果本次和上次都是 2,是否立即返回?可否先对比一下 uid,有差别再返回? * if (result.Results != null * && result.Results.Count > 0) * { * SetLastUids(current_uids); * return result; * } */ Thread.Sleep(10); // 10? 200? } SetLastUids(session_id, current_uids); return(result); } catch (Exception ex) { return(new ListTagsResult { Value = -1, // TODO: 如何返回异常信息? ErrorInfo = $"ListTags() 出现异常:{ExceptionUtil.GetDebugText(ex)}" }); } finally { Program.Rfid.DecApiCount(); } }
async Task DoInventory() { Program.MainForm.OutputHistory("开始捕获", 0); /* * if (Program.Rfid.Readers.Count == 0) * Program.MainForm.OutputHistory("当前没有可用的读卡器", 2); * else * { * List<string> names = new List<string>(); * Program.Rfid.Readers.ForEach((o) => names.Add(o.Name)); * Program.MainForm.OutputHistory($"当前读卡器数量 {Program.Rfid.Readers.Count}。包括: \r\n{StringUtil.MakePathList(names, "\r\n")}", 0); * } */ if (Program.Rfid.ShelfLocks.Count > 0) { List <string> names = new List <string>(); Program.Rfid.ShelfLocks.ForEach((o) => names.Add(o.Name)); Program.MainForm.OutputHistory($"当前锁控数量 {Program.Rfid.ShelfLocks.Count}。包括: \r\n{StringUtil.MakePathList(names, "\r\n")}", 0); } _cancelInventory = new CancellationTokenSource(); bool bFirst = true; try { // uid --> Driver Name // Hashtable uid_table = new Hashtable(); while (_cancelInventory.IsCancellationRequested == false) { await Task.Delay(200, _cancelInventory.Token).ConfigureAwait(false); ClearIdleTag(TimeSpan.FromSeconds(1)); // 1 秒的防误触发时间 FlushCompactLog(); //if (_captureEnabled.Value == false) // continue; // uid_table.Clear(); foreach (Reader reader in Program.Rfid.Readers) { if (reader == null) { continue; } if (Program.Rfid.Pause) { continue; } if (string.IsNullOrEmpty(Program.Rfid.State) == false) { break; } InventoryResult inventory_result = null; //Program.Rfid.IncApiCount(); try { inventory_result = Program.Rfid.Inventory( reader.Name, bFirst ? "" : "only_new"); // bFirst = false; } finally { //Program.Rfid.DecApiCount(); } if (inventory_result.Value == -1) { _compactLog?.Add("*** 读卡器 {0} 点选标签时出错: {1}", new object[] { reader.Name, inventory_result.ToString() } ); continue; // ioError 要主动卸载有问题的 reader? // 如何报错?写入操作历史? // Program.MainForm.OutputHistory($"读卡器{reader.Name}点选标签时出错:{inventory_result.ToString()}\r\n已停止捕获过程", 2); // return; } foreach (InventoryInfo info in inventory_result.Results) { //if (uid_table.ContainsKey(info.UID)) // continue; //uid_table[info.UID] = reader.Name; AddToTagList(reader.Name, info.UID, info.DsfID, info.Protocol); } } } } catch (TaskCanceledException) { } finally { _cancelInventory = null; Program.MainForm.OutputHistory("结束捕获", 0); } }
public async Task <int> RunAsync(string pipeIn, string pipeOut) { // Validate args. ArgUtil.NotNullOrEmpty(pipeIn, nameof(pipeIn)); ArgUtil.NotNullOrEmpty(pipeOut, nameof(pipeOut)); var agentWebProxy = HostContext.GetService <IVstsAgentWebProxy>(); var agentCertManager = HostContext.GetService <IAgentCertificateManager>(); VssUtil.InitializeVssClientSettings(HostContext.UserAgent, agentWebProxy.WebProxy, agentCertManager.VssClientCertificateManager); var jobRunner = HostContext.CreateService <IJobRunner>(); using (var channel = HostContext.CreateService <IProcessChannel>()) using (var jobRequestCancellationToken = CancellationTokenSource.CreateLinkedTokenSource(HostContext.AgentShutdownToken)) using (var channelTokenSource = new CancellationTokenSource()) { // Start the channel. channel.StartClient(pipeIn, pipeOut); // Wait for up to 30 seconds for a message from the channel. HostContext.WritePerfCounter("WorkerWaitingForJobMessage"); Trace.Info("Waiting to receive the job message from the channel."); WorkerMessage channelMessage; using (var csChannelMessage = new CancellationTokenSource(_workerStartTimeout)) { channelMessage = await channel.ReceiveAsync(csChannelMessage.Token); } // Deserialize the job message. Trace.Info("Message received."); ArgUtil.Equal(MessageType.NewJobRequest, channelMessage.MessageType, nameof(channelMessage.MessageType)); ArgUtil.NotNullOrEmpty(channelMessage.Body, nameof(channelMessage.Body)); var jobMessage = JsonUtility.FromString <Pipelines.AgentJobRequestMessage>(channelMessage.Body); ArgUtil.NotNull(jobMessage, nameof(jobMessage)); HostContext.WritePerfCounter($"WorkerJobMessageReceived_{jobMessage.RequestId.ToString()}"); // Initialize the secret masker and set the thread culture. InitializeSecretMasker(jobMessage); SetCulture(jobMessage); // Start the job. Trace.Info($"Job message:{Environment.NewLine} {StringUtil.ConvertToJson(WorkerUtilities.ScrubPiiData(jobMessage))}"); Task <TaskResult> jobRunnerTask = jobRunner.RunAsync(jobMessage, jobRequestCancellationToken.Token); // Start listening for a cancel message from the channel. Trace.Info("Listening for cancel message from the channel."); Task <WorkerMessage> channelTask = channel.ReceiveAsync(channelTokenSource.Token); // Wait for one of the tasks to complete. Trace.Info("Waiting for the job to complete or for a cancel message from the channel."); Task.WaitAny(jobRunnerTask, channelTask); // Handle if the job completed. if (jobRunnerTask.IsCompleted) { Trace.Info("Job completed."); channelTokenSource.Cancel(); // Cancel waiting for a message from the channel. return(TaskResultUtil.TranslateToReturnCode(await jobRunnerTask)); } // Otherwise a cancel message was received from the channel. Trace.Info("Cancellation/Shutdown message received."); channelMessage = await channelTask; switch (channelMessage.MessageType) { case MessageType.CancelRequest: jobRequestCancellationToken.Cancel(); // Expire the host cancellation token. break; case MessageType.AgentShutdown: HostContext.ShutdownAgent(ShutdownReason.UserCancelled); break; case MessageType.OperatingSystemShutdown: HostContext.ShutdownAgent(ShutdownReason.OperatingSystemShutdown); break; default: throw new ArgumentOutOfRangeException(nameof(channelMessage.MessageType), channelMessage.MessageType, nameof(channelMessage.MessageType)); } // Await the job. return(TaskResultUtil.TranslateToReturnCode(await jobRunnerTask)); } }
} // ProcessRecord #endregion Command code private void WriteMatches(string value, string parametersetname) { // First get the alias table (from the proper scope if necessary) IDictionary <string, AliasInfo> aliasTable = null; //get the command origin CommandOrigin origin = MyInvocation.CommandOrigin; string displayString = "name"; if (!String.IsNullOrEmpty(Scope)) { // This can throw PSArgumentException and PSArgumentOutOfRangeException // but just let them go as this is terminal for the pipeline and the // exceptions are already properly adorned with an ErrorRecord. aliasTable = SessionState.Internal.GetAliasTableAtScope(Scope); } else { aliasTable = SessionState.Internal.GetAliasTable(); } bool matchfound = false; bool ContainsWildcard = WildcardPattern.ContainsWildcardCharacters(value); WildcardPattern wcPattern = WildcardPattern.Get(value, WildcardOptions.IgnoreCase); // excluding patter for Default paramset. Collection <WildcardPattern> excludePatterns = SessionStateUtilities.CreateWildcardsFromStrings( _excludes, WildcardOptions.IgnoreCase); List <AliasInfo> results = new List <AliasInfo>(); foreach (KeyValuePair <string, AliasInfo> tableEntry in aliasTable) { if (parametersetname.Equals("Definition", StringComparison.OrdinalIgnoreCase)) { displayString = "definition"; if (!wcPattern.IsMatch(tableEntry.Value.Definition)) { continue; } if (SessionStateUtilities.MatchesAnyWildcardPattern(tableEntry.Value.Definition, excludePatterns, false)) { continue; } } else { if (!wcPattern.IsMatch(tableEntry.Key)) { continue; } //excludes pattern if (SessionStateUtilities.MatchesAnyWildcardPattern(tableEntry.Key, excludePatterns, false)) { continue; } } if (ContainsWildcard) { // Only write the command if it is visible to the requestor if (SessionState.IsVisible(origin, tableEntry.Value)) { matchfound = true; results.Add(tableEntry.Value); } } else { // For specifically named elements, generate an error for elements that aren't visible... try { SessionState.ThrowIfNotVisible(origin, tableEntry.Value); results.Add(tableEntry.Value); matchfound = true; } catch (SessionStateException sessionStateException) { WriteError( new ErrorRecord( sessionStateException.ErrorRecord, sessionStateException)); // Even though it resulted in an error, a result was found // so we don't want to generate the nothing found error // at the end... matchfound = true; continue; } } } results.Sort( delegate(AliasInfo left, AliasInfo right) { return(StringComparer.CurrentCultureIgnoreCase.Compare(left.Name, right.Name)); }); foreach (AliasInfo alias in results) { this.WriteObject(alias); } if (!matchfound && !ContainsWildcard && (excludePatterns == null || excludePatterns.Count == 0)) { // Need to write an error if the user tries to get an alias // tat doesn't exist and they are not globbing. ItemNotFoundException itemNotFound = new ItemNotFoundException(StringUtil.Format(AliasCommandStrings.NoAliasFound, displayString, value)); ErrorRecord er = new ErrorRecord(itemNotFound, "ItemNotFoundException", ErrorCategory.ObjectNotFound, value); WriteError(er); } }
// 同步 // 注:中途遇到异常(例如 Loader 抛出异常),可能会丢失 INSERT_BATCH 条以内的日志记录写入 operlog 表 // parameters: // strLastDate 处理中断或者结束时返回最后处理过的日期 // last_index 处理或中断返回时最后处理过的位置。以后继续处理的时候可以从这个偏移开始 // return: // -1 出错 // 0 中断 // 1 完成 public ReplicationResult DoReplication( LibraryChannel channel, string strStartDate, string strEndDate, LogType logType, CancellationToken token) { string strLastDate = ""; long last_index = -1; // -1 表示尚未处理 // bool bUserChanged = false; // strStartDate 里面可能会包含 ":1-100" 这样的附加成分 StringUtil.ParseTwoPart(strStartDate, ":", out string strLeft, out string strRight); strStartDate = strLeft; if (string.IsNullOrEmpty(strStartDate) == true) { return(new ReplicationResult { Value = -1, ErrorInfo = "DoReplication() 出错: strStartDate 参数值不应为空" }); } try { List <string> dates = null; int nRet = OperLogLoader.MakeLogFileNames(strStartDate, strEndDate, true, // 是否包含扩展名 ".log" out dates, out string strWarning, out string strError); if (nRet == -1) { return(new ReplicationResult { Value = -1, ErrorInfo = strError }); } if (dates.Count > 0 && string.IsNullOrEmpty(strRight) == false) { dates[0] = dates[0] + ":" + strRight; } channel.Timeout = new TimeSpan(0, 1, 0); // 一分钟 // using (SQLiteConnection connection = new SQLiteConnection(this._connectionString)) { ProgressEstimate estimate = new ProgressEstimate(); OperLogLoader loader = new OperLogLoader { Channel = channel, Stop = null, // this.Progress; // loader.owner = this; Estimate = estimate, Dates = dates, Level = 2, // Program.MainForm.OperLogLevel; AutoCache = false, CacheDir = "", LogType = logType, Filter = "setReaderInfo" }; loader.Prompt += Loader_Prompt; try { // int nRecCount = 0; string strLastItemDate = ""; long lLastItemIndex = -1; foreach (OperLogItem item in loader) { token.ThrowIfCancellationRequested(); //if (stop != null) // stop.SetMessage("正在同步 " + item.Date + " " + item.Index.ToString() + " " + estimate.Text + "..."); if (string.IsNullOrEmpty(item.Xml) == true) { goto CONTINUE; } XmlDocument dom = new XmlDocument(); try { dom.LoadXml(item.Xml); } catch (Exception ex) { if (this.HasLoaderPrompt()) { strError = logType.ToString() + "日志记录 " + item.Date + " " + item.Index.ToString() + " XML 装入 DOM 的时候发生错误: " + ex.Message; MessagePromptEventArgs e = new MessagePromptEventArgs { MessageText = strError + "\r\n\r\n是否跳过此条继续处理?\r\n\r\n(确定: 跳过; 取消: 停止全部操作)", IncludeOperText = true, // + "\r\n\r\n是否跳过此条继续处理?", Actions = "yes,cancel" }; Loader_Prompt(channel, e); if (e.ResultAction == "cancel") { throw new ChannelException(channel.ErrorCode, strError); } else if (e.ResultAction == "yes") { continue; } else { // no 也是抛出异常。因为继续下一批代价太大 throw new ChannelException(channel.ErrorCode, strError); } } else { throw new ChannelException(channel.ErrorCode, strError); } } string strOperation = DomUtil.GetElementText(dom.DocumentElement, "operation"); if (strOperation == "setReaderInfo") { nRet = TraceSetReaderInfo( dom, out strError); } else { continue; } if (nRet == -1) { strError = "同步 " + item.Date + " " + item.Index.ToString() + " 时出错: " + strError; if (this.HasLoaderPrompt()) { MessagePromptEventArgs e = new MessagePromptEventArgs { MessageText = strError + "\r\n\r\n是否跳过此条继续处理?\r\n\r\n(确定: 跳过; 取消: 停止全部操作)", IncludeOperText = true, // + "\r\n\r\n是否跳过此条继续处理?", Actions = "yes,cancel" }; Loader_Prompt(channel, e); if (e.ResultAction == "cancel") { throw new Exception(strError); } else if (e.ResultAction == "yes") { continue; } else { // no 也是抛出异常。因为继续下一批代价太大 throw new Exception(strError); } } else { throw new ChannelException(channel.ErrorCode, strError); } } // lProcessCount++; CONTINUE: // 便于循环外获得这些值 strLastItemDate = item.Date; lLastItemIndex = item.Index + 1; // index = 0; // 第一个日志文件后面的,都从头开始了 } // 记忆 strLastDate = strLastItemDate; last_index = lLastItemIndex; } finally { loader.Prompt -= Loader_Prompt; } } return(new ReplicationResult { Value = last_index == -1 ? 0 : 1, LastDate = strLastDate, LastIndex = last_index }); } catch (ChannelException ex) { return(new ReplicationResult { Value = -1, ErrorInfo = ex.Message }); } catch (Exception ex) { string strError = "ReportForm DoReplication() exception: " + ExceptionUtil.GetDebugText(ex); return(new ReplicationResult { Value = -1, ErrorInfo = strError }); } }
private async Task StartContainerAsync(IExecutionContext executionContext, ContainerInfo container) { Trace.Entering(); ArgUtil.NotNull(executionContext, nameof(executionContext)); ArgUtil.NotNull(container, nameof(container)); ArgUtil.NotNullOrEmpty(container.ContainerImage, nameof(container.ContainerImage)); Trace.Info($"Container name: {container.ContainerName}"); Trace.Info($"Container image: {container.ContainerImage}"); Trace.Info($"Container registry: {container.ContainerRegistryEndpoint.ToString()}"); Trace.Info($"Container options: {container.ContainerCreateOptions}"); Trace.Info($"Skip container image pull: {container.SkipContainerImagePull}"); foreach (var port in container.UserPortMappings) { Trace.Info($"User provided port: {port.Value}"); } foreach (var volume in container.UserMountVolumes) { Trace.Info($"User provided volume: {volume.Value}"); } // Login to private docker registry string registryServer = string.Empty; if (container.ContainerRegistryEndpoint != Guid.Empty) { var registryEndpoint = executionContext.Endpoints.FirstOrDefault(x => x.Type == "dockerregistry" && x.Id == container.ContainerRegistryEndpoint); ArgUtil.NotNull(registryEndpoint, nameof(registryEndpoint)); string username = string.Empty; string password = string.Empty; string registryType = string.Empty; registryEndpoint.Data?.TryGetValue("registrytype", out registryType); if (string.Equals(registryType, "ACR", StringComparison.OrdinalIgnoreCase)) { string loginServer = string.Empty; registryEndpoint.Authorization?.Parameters?.TryGetValue("loginServer", out loginServer); if (loginServer != null) { loginServer = loginServer.ToLower(); } registryEndpoint.Authorization?.Parameters?.TryGetValue("serviceprincipalid", out username); registryEndpoint.Authorization?.Parameters?.TryGetValue("serviceprincipalkey", out password); registryServer = $"https://{loginServer}"; } else { registryEndpoint.Authorization?.Parameters?.TryGetValue("registry", out registryServer); registryEndpoint.Authorization?.Parameters?.TryGetValue("username", out username); registryEndpoint.Authorization?.Parameters?.TryGetValue("password", out password); } ArgUtil.NotNullOrEmpty(registryServer, nameof(registryServer)); ArgUtil.NotNullOrEmpty(username, nameof(username)); ArgUtil.NotNullOrEmpty(password, nameof(password)); int loginExitCode = await _dockerManger.DockerLogin(executionContext, registryServer, username, password); if (loginExitCode != 0) { throw new InvalidOperationException($"Docker login fail with exit code {loginExitCode}"); } } try { if (!container.SkipContainerImagePull) { if (!string.IsNullOrEmpty(registryServer) && registryServer.IndexOf("index.docker.io", StringComparison.OrdinalIgnoreCase) < 0) { var registryServerUri = new Uri(registryServer); if (!container.ContainerImage.StartsWith(registryServerUri.Authority, StringComparison.OrdinalIgnoreCase)) { container.ContainerImage = $"{registryServerUri.Authority}/{container.ContainerImage}"; } } // Pull down docker image with retry up to 3 times int retryCount = 0; int pullExitCode = 0; while (retryCount < 3) { pullExitCode = await _dockerManger.DockerPull(executionContext, container.ContainerImage); if (pullExitCode == 0) { break; } else { retryCount++; if (retryCount < 3) { var backOff = BackoffTimerHelper.GetRandomBackoff(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(10)); executionContext.Warning($"Docker pull failed with exit code {pullExitCode}, back off {backOff.TotalSeconds} seconds before retry."); await Task.Delay(backOff); } } } if (retryCount == 3 && pullExitCode != 0) { throw new InvalidOperationException($"Docker pull failed with exit code {pullExitCode}"); } } // Mount folder into container #if OS_WINDOWS container.MountVolumes.Add(new MountVolume(HostContext.GetDirectory(WellKnownDirectory.Externals), container.TranslateToContainerPath(HostContext.GetDirectory(WellKnownDirectory.Externals)))); container.MountVolumes.Add(new MountVolume(HostContext.GetDirectory(WellKnownDirectory.Work), container.TranslateToContainerPath(HostContext.GetDirectory(WellKnownDirectory.Work)))); container.MountVolumes.Add(new MountVolume(HostContext.GetDirectory(WellKnownDirectory.Tools), container.TranslateToContainerPath(HostContext.GetDirectory(WellKnownDirectory.Tools)))); #else string defaultWorkingDirectory = executionContext.Variables.Get(Constants.Variables.System.DefaultWorkingDirectory); if (string.IsNullOrEmpty(defaultWorkingDirectory)) { throw new NotSupportedException(StringUtil.Loc("ContainerJobRequireSystemDefaultWorkDir")); } string workingDirectory = Path.GetDirectoryName(defaultWorkingDirectory.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)); container.MountVolumes.Add(new MountVolume(container.TranslateToHostPath(workingDirectory), workingDirectory)); container.MountVolumes.Add(new MountVolume(HostContext.GetDirectory(WellKnownDirectory.Temp), container.TranslateToContainerPath(HostContext.GetDirectory(WellKnownDirectory.Temp)))); container.MountVolumes.Add(new MountVolume(HostContext.GetDirectory(WellKnownDirectory.Tools), container.TranslateToContainerPath(HostContext.GetDirectory(WellKnownDirectory.Tools)))); container.MountVolumes.Add(new MountVolume(HostContext.GetDirectory(WellKnownDirectory.Tasks), container.TranslateToContainerPath(HostContext.GetDirectory(WellKnownDirectory.Tasks)))); container.MountVolumes.Add(new MountVolume(HostContext.GetDirectory(WellKnownDirectory.Externals), container.TranslateToContainerPath(HostContext.GetDirectory(WellKnownDirectory.Externals)), true)); // Ensure .taskkey file exist so we can mount it. string taskKeyFile = Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Work), ".taskkey"); if (!File.Exists(taskKeyFile)) { File.WriteAllText(taskKeyFile, string.Empty); } container.MountVolumes.Add(new MountVolume(taskKeyFile, container.TranslateToContainerPath(taskKeyFile))); #endif if (container.IsJobContainer) { // See if this container brings its own Node.js container.ContainerBringNodePath = await _dockerManger.DockerInspect(context : executionContext, dockerObject : container.ContainerImage, options : $"--format=\"{{{{index .Config.Labels \\\"{_nodeJsPathLabel}\\\"}}}}\""); string node; if (!string.IsNullOrEmpty(container.ContainerBringNodePath)) { node = container.ContainerBringNodePath; } else { node = container.TranslateToContainerPath(Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Externals), "node", "bin", $"node{IOUtil.ExeExtension}")); } string sleepCommand = $"\"{node}\" -e \"setInterval(function(){{}}, 24 * 60 * 60 * 1000);\""; container.ContainerCommand = sleepCommand; } container.ContainerId = await _dockerManger.DockerCreate(executionContext, container); ArgUtil.NotNullOrEmpty(container.ContainerId, nameof(container.ContainerId)); if (container.IsJobContainer) { executionContext.Variables.Set(Constants.Variables.Agent.ContainerId, container.ContainerId); } // Start container int startExitCode = await _dockerManger.DockerStart(executionContext, container.ContainerId); if (startExitCode != 0) { throw new InvalidOperationException($"Docker start fail with exit code {startExitCode}"); } } finally { // Logout for private registry if (!string.IsNullOrEmpty(registryServer)) { int logoutExitCode = await _dockerManger.DockerLogout(executionContext, registryServer); if (logoutExitCode != 0) { executionContext.Error($"Docker logout fail with exit code {logoutExitCode}"); } } } try { // Make sure container is up and running var psOutputs = await _dockerManger.DockerPS(executionContext, $"--all --filter id={container.ContainerId} --filter status=running --no-trunc --format \"{{{{.ID}}}} {{{{.Status}}}}\""); if (psOutputs.FirstOrDefault(x => !string.IsNullOrEmpty(x))?.StartsWith(container.ContainerId) != true) { // container is not up and running, pull docker log for this container. await _dockerManger.DockerPS(executionContext, $"--all --filter id={container.ContainerId} --no-trunc --format \"{{{{.ID}}}} {{{{.Status}}}}\""); int logsExitCode = await _dockerManger.DockerLogs(executionContext, container.ContainerId); if (logsExitCode != 0) { executionContext.Warning($"Docker logs fail with exit code {logsExitCode}"); } executionContext.Warning($"Docker container {container.ContainerId} is not in running state."); } } catch (Exception ex) { // pull container log is best effort. Trace.Error("Catch exception when check container log and container status."); Trace.Error(ex); } // Get port mappings of running container if (executionContext.Container == null && !container.IsJobContainer) { container.AddPortMappings(await _dockerManger.DockerPort(executionContext, container.ContainerId)); foreach (var port in container.PortMappings) { executionContext.Variables.Set( $"{Constants.Variables.Agent.ServicePortPrefix}.{container.ContainerNetworkAlias}.ports.{port.ContainerPort}", $"{port.HostPort}"); } } #if !OS_WINDOWS if (container.IsJobContainer) { // Ensure bash exist in the image int execWhichBashExitCode = await _dockerManger.DockerExec(executionContext, container.ContainerId, string.Empty, $"sh -c \"command -v bash\""); if (execWhichBashExitCode != 0) { throw new InvalidOperationException($"Docker exec fail with exit code {execWhichBashExitCode}"); } // Get current username container.CurrentUserName = (await ExecuteCommandAsync(executionContext, "whoami", string.Empty)).FirstOrDefault(); ArgUtil.NotNullOrEmpty(container.CurrentUserName, nameof(container.CurrentUserName)); // Get current userId container.CurrentUserId = (await ExecuteCommandAsync(executionContext, "id", $"-u {container.CurrentUserName}")).FirstOrDefault(); ArgUtil.NotNullOrEmpty(container.CurrentUserId, nameof(container.CurrentUserId)); executionContext.Output(StringUtil.Loc("CreateUserWithSameUIDInsideContainer", container.CurrentUserId)); // Create an user with same uid as the agent run as user inside the container. // All command execute in docker will run as Root by default, // this will cause the agent on the host machine doesn't have permission to any new file/folder created inside the container. // So, we create a user account with same UID inside the container and let all docker exec command run as that user. string containerUserName = string.Empty; // We need to find out whether there is a user with same UID inside the container List <string> userNames = new List <string>(); int execGrepExitCode = await _dockerManger.DockerExec(executionContext, container.ContainerId, string.Empty, $"bash -c \"grep {container.CurrentUserId} /etc/passwd | cut -f1 -d:\"", userNames); if (execGrepExitCode != 0) { throw new InvalidOperationException($"Docker exec fail with exit code {execGrepExitCode}"); } if (userNames.Count > 0) { // check all potential username that might match the UID. foreach (string username in userNames) { int execIdExitCode = await _dockerManger.DockerExec(executionContext, container.ContainerId, string.Empty, $"id -u {username}"); if (execIdExitCode == 0) { containerUserName = username; break; } } } // Create a new user with same UID if (string.IsNullOrEmpty(containerUserName)) { containerUserName = $"{container.CurrentUserName}_azpcontainer"; int execUseraddExitCode = await _dockerManger.DockerExec(executionContext, container.ContainerId, string.Empty, $"useradd -m -u {container.CurrentUserId} {containerUserName}"); if (execUseraddExitCode != 0) { throw new InvalidOperationException($"Docker exec fail with exit code {execUseraddExitCode}"); } } executionContext.Output(StringUtil.Loc("GrantContainerUserSUDOPrivilege", containerUserName)); // Create a new group for giving sudo permission int execGroupaddExitCode = await _dockerManger.DockerExec(executionContext, container.ContainerId, string.Empty, $"groupadd azure_pipelines_sudo"); if (execGroupaddExitCode != 0) { throw new InvalidOperationException($"Docker exec fail with exit code {execGroupaddExitCode}"); } // Add the new created user to the new created sudo group. int execUsermodExitCode = await _dockerManger.DockerExec(executionContext, container.ContainerId, string.Empty, $"usermod -a -G azure_pipelines_sudo {containerUserName}"); if (execUsermodExitCode != 0) { throw new InvalidOperationException($"Docker exec fail with exit code {execUsermodExitCode}"); } // Allow the new sudo group run any sudo command without providing password. int execEchoExitCode = await _dockerManger.DockerExec(executionContext, container.ContainerId, string.Empty, $"su -c \"echo '%azure_pipelines_sudo ALL=(ALL:ALL) NOPASSWD:ALL' >> /etc/sudoers\""); if (execUsermodExitCode != 0) { throw new InvalidOperationException($"Docker exec fail with exit code {execEchoExitCode}"); } bool setupDockerGroup = executionContext.Variables.GetBoolean("VSTS_SETUP_DOCKERGROUP") ?? StringUtil.ConvertToBoolean(Environment.GetEnvironmentVariable("VSTS_SETUP_DOCKERGROUP"), true); if (setupDockerGroup) { executionContext.Output(StringUtil.Loc("AllowContainerUserRunDocker", containerUserName)); // Get docker.sock group id on Host string dockerSockGroupId = (await ExecuteCommandAsync(executionContext, "stat", $"-c %g /var/run/docker.sock")).FirstOrDefault(); // We need to find out whether there is a group with same GID inside the container string existingGroupName = null; List <string> groupsOutput = new List <string>(); int execGroupGrepExitCode = await _dockerManger.DockerExec(executionContext, container.ContainerId, string.Empty, $"bash -c \"cat /etc/group\"", groupsOutput); if (execGroupGrepExitCode != 0) { throw new InvalidOperationException($"Docker exec fail with exit code {execGroupGrepExitCode}"); } if (groupsOutput.Count > 0) { // check all potential groups that might match the GID. foreach (string groupOutput in groupsOutput) { if (!string.IsNullOrEmpty(groupOutput)) { var groupSegments = groupOutput.Split(':'); if (groupSegments.Length != 4) { Trace.Warning($"Unexpected output from /etc/group: '{groupOutput}'"); } else { // the output of /etc/group should looks like `group:x:gid:` var groupName = groupSegments[0]; var groupId = groupSegments[2]; if (string.Equals(dockerSockGroupId, groupId)) { existingGroupName = groupName; break; } } } } } if (string.IsNullOrEmpty(existingGroupName)) { // create a new group with same gid existingGroupName = "azure_pipelines_docker"; int execDockerGroupaddExitCode = await _dockerManger.DockerExec(executionContext, container.ContainerId, string.Empty, $"groupadd -g {dockerSockGroupId} azure_pipelines_docker"); if (execDockerGroupaddExitCode != 0) { throw new InvalidOperationException($"Docker exec fail with exit code {execDockerGroupaddExitCode}"); } } // Add the new created user to the docker socket group. int execGroupUsermodExitCode = await _dockerManger.DockerExec(executionContext, container.ContainerId, string.Empty, $"usermod -a -G {existingGroupName} {containerUserName}"); if (execGroupUsermodExitCode != 0) { throw new InvalidOperationException($"Docker exec fail with exit code {execGroupUsermodExitCode}"); } } } #endif }
// parameters: // return: // -1 出错 // >=0 成功。返回实际初始化的事项 public NormalResult InitFingerprintCache( LibraryChannel channel, string strDir, CancellationToken token) { string strError = ""; try { // 清空以前的全部缓存内容,以便重新建立 // return: // -1 出错 // >=0 实际发送给接口程序的事项数目 int nRet = CreateFingerprintCache(null, out strError); if (nRet == -1 || nRet == -2) { return new NormalResult { Value = nRet, ErrorInfo = strError } } ; // this.Prompt("正在初始化指纹缓存 ...\r\n请不要关闭本窗口\r\n\r\n(在此过程中,与指纹识别无关的窗口和功能不受影响,可前往使用)\r\n"); nRet = GetCurrentOwnerReaderNameList( channel, out List <string> readerdbnames, out strError); if (nRet == -1) { return(new NormalResult { Value = -1, ErrorInfo = strError, ErrorCode = channel.ErrorCode.ToString() }); } if (readerdbnames.Count == 0) { strError = $"因当前用户没有管辖任何读者库,初始化{this.BioTypeName}缓存的操作无法完成"; return(new NormalResult { Value = -1, ErrorInfo = strError }); } this.SetProgress(0, readerdbnames.Count); int nCount = 0; // 对这些读者库逐个进行高速缓存的初始化 // 使用 特殊的 browse 格式,以便获得读者记录中的 fingerprint timestamp字符串,或者兼获得 fingerprint string // <fingerprint timestamp='XXXX'></fingerprint> int i = 0; foreach (string strReaderDbName in readerdbnames) { // 初始化一个读者库的指纹缓存 // return: // -1 出错 // >=0 实际发送给接口程序的事项数目 nRet = BuildOneDbCache( channel, strDir, strReaderDbName, token, out strError); if (nRet == -1) { return new NormalResult { Value = -1, ErrorInfo = strError } } ; nCount += nRet; i++; this.SetProgress(i, readerdbnames.Count); } #if NO if (nCount == 0) { strError = "因当前用户管辖的读者库 " + StringUtil.MakePathList(readerdbnames) + " 中没有任何具有指纹信息的读者记录,初始化指纹缓存的操作没有完成"; return(-1); } #endif if (nCount == 0) { strError = $"当前用户管辖的读者库 { StringUtil.MakePathList(readerdbnames) } 中没有任何具有{this.BioTypeName}信息的读者记录,{this.BioTypeName}缓存为空"; return(new NormalResult()); } this.ShowMessage($"{this.BioTypeName}缓存初始化成功"); return(new NormalResult { Value = nCount }); } catch (Exception ex) { strError = ex.Message; return(new NormalResult { Value = -1, ErrorInfo = strError }); } }
private static string BuildMessage(string commandName) { return(StringUtil.Format(DiscoveryExceptions.RequiresElevation, commandName)); }
public override string ToString() { return StringUtil.ToString(Items); }
private static bool AreEqualPlaceholders(string lhsPlaceholderKey, string rhsPlaceholderKey) { if (lhsPlaceholderKey == null || rhsPlaceholderKey == null) { return(string.Equals(lhsPlaceholderKey, rhsPlaceholderKey, StringComparison.InvariantCulture)); } int num1 = lhsPlaceholderKey.LastIndexOf('/'); int num2 = rhsPlaceholderKey.LastIndexOf('/'); if (num1 >= 0 && num2 >= 0) { return(lhsPlaceholderKey.Equals(rhsPlaceholderKey, StringComparison.InvariantCultureIgnoreCase)); } return((num1 >= 0 ? StringUtil.Mid(lhsPlaceholderKey, num1 + 1) : lhsPlaceholderKey).Equals(num2 >= 0 ? StringUtil.Mid(rhsPlaceholderKey, num2 + 1) : rhsPlaceholderKey, StringComparison.InvariantCultureIgnoreCase)); }
public IEnumerator GetEnumerator() { List <string> batch = new List <string>(); for (int index = 0; index < m_recpaths.Count; index++) { string s = m_recpaths[index]; batch.Add(s); // 每100个一批,或者最后一次 if (batch.Count >= 100 || (index == m_recpaths.Count - 1 && batch.Count > 0)) { REDO: #if NO string[] paths = new string[batch.Count]; batch.CopyTo(paths); #endif string[] paths = batch.ToArray(); DigitalPlatform.LibraryClient.localhost.Record[] searchresults = null; string strError = ""; long lRet = Channel.GetBrowseRecords( this.Stop, paths, this.Format, // "id,cols", out searchresults, out strError); if (lRet == -1) { // throw new Exception(strError); if (this.Prompt != null) { MessagePromptEventArgs e = new MessagePromptEventArgs(); e.MessageText = "获得浏览记录时发生错误: " + strError + "\r\npaths='" + StringUtil.MakePathList(paths) + "' (" + this.Format + ")"; e.Actions = "yes,no,cancel"; this.Prompt(this, e); if (e.ResultAction == "cancel") { throw new ChannelException(Channel.ErrorCode, strError); } else if (e.ResultAction == "yes") { goto REDO; } else { // no 也是抛出异常。因为继续下一批代价太大 throw new ChannelException(Channel.ErrorCode, strError); } } else { throw new ChannelException(Channel.ErrorCode, strError); } } if (searchresults == null) { strError = "searchresults == null"; throw new Exception(strError); } for (int i = 0; i < searchresults.Length; i++) { DigitalPlatform.LibraryClient.localhost.Record record = searchresults[i]; if (batch[i] != record.Path) { throw new Exception("下标 " + i + " 的 batch 元素 '" + batch[i] + "' 和返回的该下标位置 GetBrowseRecords() 结果路径 '" + record.Path + "' 不匹配"); } Debug.Assert(batch[i] == record.Path, ""); yield return(record); } // CONTINUE: if (batch.Count > searchresults.Length) { // 有本次没有获取到的记录 batch.RemoveRange(0, searchresults.Length); if (index == m_recpaths.Count - 1) { goto REDO; // 当前已经是最后一轮了,需要继续做完 } // 否则可以留给下一轮处理 } else { batch.Clear(); } } } }
// return: // 0 Cancel // 1 OK static int ResetSerialCode( string strTitle, bool bAllowSetBlank, string strOldSerialCode, string strOriginCode) { Hashtable ext_table = StringUtil.ParseParameters(strOriginCode); string strMAC = (string)ext_table["mac"]; if (string.IsNullOrEmpty(strMAC) == true) { strOriginCode = "!error"; } else { Debug.Assert(string.IsNullOrEmpty(CopyrightKey) == false); strOriginCode = Cryptography.Encrypt(strOriginCode, CopyrightKey); } SerialCodeForm dlg = new SerialCodeForm(); dlg.Text = strTitle; dlg.Font = MainForm.Font; if (SerialNumberMode == "loose") { dlg.DefaultCodes = new List <string>(new string[] { "community|社区版" }); } dlg.SerialCode = strOldSerialCode; dlg.StartPosition = FormStartPosition.CenterScreen; dlg.OriginCode = strOriginCode; REDO: dlg.ShowDialog(MainForm); if (dlg.DialogResult != DialogResult.OK) { return(0); } if (string.IsNullOrEmpty(dlg.SerialCode) == true) { if (bAllowSetBlank == true) { DialogResult result = MessageBox.Show(MainForm, $"确实要将序列号设置为空?\r\n\r\n(一旦将序列号设置为空,{ProductName} 将自动退出,下次启动需要重新设置序列号)", $"{ProductName}", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2); if (result == System.Windows.Forms.DialogResult.No) { return(0); } } else { MessageBox.Show(MainForm, "序列号不允许为空。请重新设置"); goto REDO; } } ClientInfo.Config.Set("sn", "sn", dlg.SerialCode); ClientInfo.Config.Save(); return(1); }
internal override FormattingCommandLineParameters GetCommandLineParameters() { FormattingCommandLineParameters parameters = new(); if (_prop != null) { ParameterProcessor processor = new(new FormatWideParameterDefinition()); TerminatingErrorContext invocationContext = new(this); parameters.mshParameterList = processor.ProcessParameters(new object[] { _prop }, invocationContext); } if (!string.IsNullOrEmpty(this.View)) { // we have a view command line switch if (parameters.mshParameterList.Count != 0) { ReportCannotSpecifyViewAndProperty(); } parameters.viewName = this.View; } // we cannot specify -column and -autosize, they are mutually exclusive if (_autosize.HasValue && _column.HasValue) { if (_autosize.Value) { // the user specified -autosize:true AND a column number string msg = StringUtil.Format(FormatAndOut_format_xxx.CannotSpecifyAutosizeAndColumnsError); ErrorRecord errorRecord = new( new InvalidDataException(), "FormatCannotSpecifyAutosizeAndColumns", ErrorCategory.InvalidArgument, null); errorRecord.ErrorDetails = new ErrorDetails(msg); this.ThrowTerminatingError(errorRecord); } } parameters.groupByParameter = this.ProcessGroupByParameter(); parameters.forceFormattingAlsoOnOutOfBand = this.Force; if (this.showErrorsAsMessages.HasValue) { parameters.showErrorsAsMessages = this.showErrorsAsMessages; } if (this.showErrorsInFormattedOutput.HasValue) { parameters.showErrorsInFormattedOutput = this.showErrorsInFormattedOutput; } parameters.expansion = ProcessExpandParameter(); if (_autosize.HasValue) { parameters.autosize = _autosize.Value; } WideSpecificParameters wideSpecific = new(); parameters.shapeParameters = wideSpecific; if (_column.HasValue) { wideSpecific.columns = _column.Value; } return(parameters); }
private async Task StartContainerAsync(IExecutionContext executionContext, ContainerInfo container) { Trace.Entering(); ArgUtil.NotNull(executionContext, nameof(executionContext)); ArgUtil.NotNull(container, nameof(container)); ArgUtil.NotNullOrEmpty(container.ContainerImage, nameof(container.ContainerImage)); Trace.Info($"Container name: {container.ContainerName}"); Trace.Info($"Container image: {container.ContainerImage}"); Trace.Info($"Container registry: {container.ContainerRegistryEndpoint.ToString()}"); Trace.Info($"Container options: {container.ContainerCreateOptions}"); Trace.Info($"Skip container image pull: {container.SkipContainerImagePull}"); foreach (var port in container.UserPortMappings) { Trace.Info($"User provided port: {port.Value}"); } foreach (var volume in container.UserMountVolumes) { Trace.Info($"User provided volume: {volume.Value}"); } if (container.ImageOS != PlatformUtil.OS.Windows) { string defaultWorkingDirectory = executionContext.Variables.Get(Constants.Variables.System.DefaultWorkingDirectory); defaultWorkingDirectory = container.TranslateContainerPathForImageOS(PlatformUtil.HostOS, container.TranslateToContainerPath(defaultWorkingDirectory)); if (string.IsNullOrEmpty(defaultWorkingDirectory)) { throw new NotSupportedException(StringUtil.Loc("ContainerJobRequireSystemDefaultWorkDir")); } string workingDirectory = IOUtil.GetDirectoryName(defaultWorkingDirectory.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar), container.ImageOS); string mountWorkingDirectory = container.TranslateToHostPath(workingDirectory); executionContext.Debug($"Default Working Directory {defaultWorkingDirectory}"); executionContext.Debug($"Working Directory {workingDirectory}"); executionContext.Debug($"Mount Working Directory {mountWorkingDirectory}"); if (!string.IsNullOrEmpty(workingDirectory)) { container.MountVolumes.Add(new MountVolume(mountWorkingDirectory, workingDirectory)); } container.MountVolumes.Add(new MountVolume(HostContext.GetDirectory(WellKnownDirectory.Temp), container.TranslateToContainerPath(HostContext.GetDirectory(WellKnownDirectory.Temp)))); container.MountVolumes.Add(new MountVolume(HostContext.GetDirectory(WellKnownDirectory.Tasks), container.TranslateToContainerPath(HostContext.GetDirectory(WellKnownDirectory.Tasks)))); } else { container.MountVolumes.Add(new MountVolume(HostContext.GetDirectory(WellKnownDirectory.Work), container.TranslateToContainerPath(HostContext.GetDirectory(WellKnownDirectory.Work)))); } container.MountVolumes.Add(new MountVolume(HostContext.GetDirectory(WellKnownDirectory.Tools), container.TranslateToContainerPath(HostContext.GetDirectory(WellKnownDirectory.Tools)))); bool externalReadOnly = container.ImageOS != PlatformUtil.OS.Windows; // This code was refactored to use PlatformUtils. The previous implementation did not have the externals directory mounted read-only for Windows. // That seems wrong, but to prevent any potential backwards compatibility issues, we are keeping the same logic container.MountVolumes.Add(new MountVolume(HostContext.GetDirectory(WellKnownDirectory.Externals), container.TranslateToContainerPath(HostContext.GetDirectory(WellKnownDirectory.Externals)), externalReadOnly)); if (container.ImageOS != PlatformUtil.OS.Windows) { // Ensure .taskkey file exist so we can mount it. string taskKeyFile = Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Work), ".taskkey"); if (!File.Exists(taskKeyFile)) { File.WriteAllText(taskKeyFile, string.Empty); } container.MountVolumes.Add(new MountVolume(taskKeyFile, container.TranslateToContainerPath(taskKeyFile))); } if (container.IsJobContainer) { // See if this container brings its own Node.js container.CustomNodePath = await _dockerManger.DockerInspect(context : executionContext, dockerObject : container.ContainerImage, options : $"--format=\"{{{{index .Config.Labels \\\"{_nodeJsPathLabel}\\\"}}}}\""); string node; if (!string.IsNullOrEmpty(container.CustomNodePath)) { node = container.CustomNodePath; } else { node = container.TranslateToContainerPath(Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Externals), "node", "bin", $"node{IOUtil.ExeExtension}")); // if on Mac OS X, require container to have node if (PlatformUtil.RunningOnMacOS) { container.CustomNodePath = "node"; node = container.CustomNodePath; } // if running on Windows, and attempting to run linux container, require container to have node else if (PlatformUtil.RunningOnWindows && container.ImageOS == PlatformUtil.OS.Linux) { container.CustomNodePath = "node"; node = container.CustomNodePath; } } string sleepCommand = $"\"{node}\" -e \"setInterval(function(){{}}, 24 * 60 * 60 * 1000);\""; container.ContainerCommand = sleepCommand; } container.ContainerId = await _dockerManger.DockerCreate(executionContext, container); ArgUtil.NotNullOrEmpty(container.ContainerId, nameof(container.ContainerId)); if (container.IsJobContainer) { executionContext.Variables.Set(Constants.Variables.Agent.ContainerId, container.ContainerId); } // Start container int startExitCode = await _dockerManger.DockerStart(executionContext, container.ContainerId); if (startExitCode != 0) { throw new InvalidOperationException($"Docker start fail with exit code {startExitCode}"); } try { // Make sure container is up and running var psOutputs = await _dockerManger.DockerPS(executionContext, $"--all --filter id={container.ContainerId} --filter status=running --no-trunc --format \"{{{{.ID}}}} {{{{.Status}}}}\""); if (psOutputs.FirstOrDefault(x => !string.IsNullOrEmpty(x))?.StartsWith(container.ContainerId) != true) { // container is not up and running, pull docker log for this container. await _dockerManger.DockerPS(executionContext, $"--all --filter id={container.ContainerId} --no-trunc --format \"{{{{.ID}}}} {{{{.Status}}}}\""); int logsExitCode = await _dockerManger.DockerLogs(executionContext, container.ContainerId); if (logsExitCode != 0) { executionContext.Warning($"Docker logs fail with exit code {logsExitCode}"); } executionContext.Warning($"Docker container {container.ContainerId} is not in running state."); } } catch (Exception ex) { // pull container log is best effort. Trace.Error("Catch exception when check container log and container status."); Trace.Error(ex); } // Get port mappings of running container if (!container.IsJobContainer) { container.AddPortMappings(await _dockerManger.DockerPort(executionContext, container.ContainerId)); foreach (var port in container.PortMappings) { executionContext.Variables.Set( $"{Constants.Variables.Agent.ServicePortPrefix}.{container.ContainerNetworkAlias}.ports.{port.ContainerPort}", $"{port.HostPort}"); } } if (!PlatformUtil.RunningOnWindows) { if (container.IsJobContainer) { // Ensure bash exist in the image int execWhichBashExitCode = await _dockerManger.DockerExec(executionContext, container.ContainerId, string.Empty, $"sh -c \"command -v bash\""); if (execWhichBashExitCode != 0) { throw new InvalidOperationException($"Docker exec fail with exit code {execWhichBashExitCode}"); } // Get current username container.CurrentUserName = (await ExecuteCommandAsync(executionContext, "whoami", string.Empty)).FirstOrDefault(); ArgUtil.NotNullOrEmpty(container.CurrentUserName, nameof(container.CurrentUserName)); // Get current userId container.CurrentUserId = (await ExecuteCommandAsync(executionContext, "id", $"-u {container.CurrentUserName}")).FirstOrDefault(); ArgUtil.NotNullOrEmpty(container.CurrentUserId, nameof(container.CurrentUserId)); executionContext.Output(StringUtil.Loc("CreateUserWithSameUIDInsideContainer", container.CurrentUserId)); // Create an user with same uid as the agent run as user inside the container. // All command execute in docker will run as Root by default, // this will cause the agent on the host machine doesn't have permission to any new file/folder created inside the container. // So, we create a user account with same UID inside the container and let all docker exec command run as that user. string containerUserName = string.Empty; // We need to find out whether there is a user with same UID inside the container List <string> userNames = new List <string>(); int execGrepExitCode = await _dockerManger.DockerExec(executionContext, container.ContainerId, string.Empty, $"bash -c \"getent passwd {container.CurrentUserId} | cut -d: -f1 \"", userNames); if (execGrepExitCode != 0) { throw new InvalidOperationException($"Docker exec fail with exit code {execGrepExitCode}"); } if (userNames.Count > 0) { // check all potential username that might match the UID. foreach (string username in userNames) { int execIdExitCode = await _dockerManger.DockerExec(executionContext, container.ContainerId, string.Empty, $"id -u {username}"); if (execIdExitCode == 0) { containerUserName = username; break; } } } // Create a new user with same UID if (string.IsNullOrEmpty(containerUserName)) { containerUserName = $"{container.CurrentUserName}_azpcontainer"; int execUseraddExitCode = await _dockerManger.DockerExec(executionContext, container.ContainerId, string.Empty, $"useradd -m -u {container.CurrentUserId} {containerUserName}"); if (execUseraddExitCode != 0) { throw new InvalidOperationException($"Docker exec fail with exit code {execUseraddExitCode}"); } } executionContext.Output(StringUtil.Loc("GrantContainerUserSUDOPrivilege", containerUserName)); // Create a new group for giving sudo permission int execGroupaddExitCode = await _dockerManger.DockerExec(executionContext, container.ContainerId, string.Empty, $"groupadd azure_pipelines_sudo"); if (execGroupaddExitCode != 0) { throw new InvalidOperationException($"Docker exec fail with exit code {execGroupaddExitCode}"); } // Add the new created user to the new created sudo group. int execUsermodExitCode = await _dockerManger.DockerExec(executionContext, container.ContainerId, string.Empty, $"usermod -a -G azure_pipelines_sudo {containerUserName}"); if (execUsermodExitCode != 0) { throw new InvalidOperationException($"Docker exec fail with exit code {execUsermodExitCode}"); } // Allow the new sudo group run any sudo command without providing password. int execEchoExitCode = await _dockerManger.DockerExec(executionContext, container.ContainerId, string.Empty, $"su -c \"echo '%azure_pipelines_sudo ALL=(ALL:ALL) NOPASSWD:ALL' >> /etc/sudoers\""); if (execUsermodExitCode != 0) { throw new InvalidOperationException($"Docker exec fail with exit code {execEchoExitCode}"); } if (AgentKnobs.SetupDockerGroup.GetValue(executionContext).AsBoolean()) { executionContext.Output(StringUtil.Loc("AllowContainerUserRunDocker", containerUserName)); // Get docker.sock group id on Host string statFormatOption = "-c %g"; if (PlatformUtil.RunningOnMacOS) { statFormatOption = "-f %g"; } string dockerSockGroupId = (await ExecuteCommandAsync(executionContext, "stat", $"{statFormatOption} /var/run/docker.sock")).FirstOrDefault(); // We need to find out whether there is a group with same GID inside the container string existingGroupName = null; List <string> groupsOutput = new List <string>(); int execGroupGrepExitCode = await _dockerManger.DockerExec(executionContext, container.ContainerId, string.Empty, $"bash -c \"cat /etc/group\"", groupsOutput); if (execGroupGrepExitCode != 0) { throw new InvalidOperationException($"Docker exec fail with exit code {execGroupGrepExitCode}"); } if (groupsOutput.Count > 0) { // check all potential groups that might match the GID. foreach (string groupOutput in groupsOutput) { if (!string.IsNullOrEmpty(groupOutput)) { var groupSegments = groupOutput.Split(':'); if (groupSegments.Length != 4) { Trace.Warning($"Unexpected output from /etc/group: '{groupOutput}'"); } else { // the output of /etc/group should looks like `group:x:gid:` var groupName = groupSegments[0]; var groupId = groupSegments[2]; if (string.Equals(dockerSockGroupId, groupId)) { existingGroupName = groupName; break; } } } } } if (string.IsNullOrEmpty(existingGroupName)) { // create a new group with same gid existingGroupName = "azure_pipelines_docker"; int execDockerGroupaddExitCode = await _dockerManger.DockerExec(executionContext, container.ContainerId, string.Empty, $"groupadd -g {dockerSockGroupId} azure_pipelines_docker"); if (execDockerGroupaddExitCode != 0) { throw new InvalidOperationException($"Docker exec fail with exit code {execDockerGroupaddExitCode}"); } } // Add the new created user to the docker socket group. int execGroupUsermodExitCode = await _dockerManger.DockerExec(executionContext, container.ContainerId, string.Empty, $"usermod -a -G {existingGroupName} {containerUserName}"); if (execGroupUsermodExitCode != 0) { throw new InvalidOperationException($"Docker exec fail with exit code {execGroupUsermodExitCode}"); } // if path to node is just 'node', with no path, let's make sure it is actually there if (string.Equals(container.CustomNodePath, "node", StringComparison.OrdinalIgnoreCase)) { List <string> nodeVersionOutput = new List <string>(); int execNodeVersionExitCode = await _dockerManger.DockerExec(executionContext, container.ContainerId, string.Empty, $"bash -c \"node -v\"", nodeVersionOutput); if (execNodeVersionExitCode != 0) { throw new InvalidOperationException($"Unable to get node version on container {container.ContainerId}. Got exit code {execNodeVersionExitCode} from docker exec"); } if (nodeVersionOutput.Count > 0) { executionContext.Output($"Detected Node Version: {nodeVersionOutput[0]}"); Trace.Info($"Using node version {nodeVersionOutput[0]} in container {container.ContainerId}"); } else { throw new InvalidOperationException($"Unable to get node version on container {container.ContainerId}. No output from node -v"); } } } } } }
public String AddStudent(int studentID, string lName, string fName, string year, string course, int gender, int member, int oldMember, DateTime birthday, string contactNo, string email, string houseHold, string committee, int paid) { string returnMessage = ""; su = new StringUtil(); MySqlConnection myConn = OpenDBConnection(); string cmd = "INSERT INTO yfc.new_student_t (student_id, last_name, first_name, year, course, gender, member, old_member, birthday, contact_no, email, household, committee, paid) VALUES (@StudentID, @LastName, @Firstname, @Year, @Course, @Gender, @Member, @OldMember, @Birthday, @ContactNo, @Email, @HouseHold, @Committee, @Paid)"; //Passes the command into the database connection MySqlCommand InsertCommand = new MySqlCommand(cmd, myConn); InsertCommand.Parameters.AddWithValue("@StudentID", studentID); InsertCommand.Parameters.AddWithValue("@LastName", lName); InsertCommand.Parameters.AddWithValue("@FirstName", fName); InsertCommand.Parameters.AddWithValue("@Year", year); InsertCommand.Parameters.AddWithValue("@Course", course); InsertCommand.Parameters.AddWithValue("@Gender", gender); InsertCommand.Parameters.AddWithValue("@Member", member); InsertCommand.Parameters.AddWithValue("@OldMember", oldMember); InsertCommand.Parameters.AddWithValue("@Birthday", birthday); InsertCommand.Parameters.AddWithValue("@ContactNo", contactNo); InsertCommand.Parameters.AddWithValue("@Email", email); InsertCommand.Parameters.AddWithValue("@HouseHold", houseHold); InsertCommand.Parameters.AddWithValue("@Committee", committee); InsertCommand.Parameters.AddWithValue("@Paid", paid); try { myConn.Open(); InsertCommand.ExecuteNonQuery(); studentList.Add(new Student(studentID, lName, fName, year, course, gender, member, oldMember, birthday, contactNo, email, houseHold, committee, paid)); GetMemberList = studentList; returnMessage = "Successfully added the student into the database"; } catch (Exception) { su.SetSystemMessage("Error! Please make sure all of the inputted data are in the correct format"); returnMessage = "Error! Please make sure all of the inputted data are in the correct format"; } return returnMessage; }
/// <summary> /// The expression will be executed in the remote computer if a /// remote runspace parameter or computer name is specified. If /// none other than command parameter is specified, then it /// just executes the command locally without creating a new /// remote runspace object. /// </summary> protected override void ProcessRecord() { if (ParameterSetName == DefinitionNameParameterSet) { // Get the Job2 object from the Job Manager for this definition name and start the job. string resolvedPath = null; if (!string.IsNullOrEmpty(_definitionPath)) { ProviderInfo provider = null; System.Collections.ObjectModel.Collection <string> paths = this.Context.SessionState.Path.GetResolvedProviderPathFromPSPath(_definitionPath, out provider); // Only file system paths are allowed. if (!provider.NameEquals(this.Context.ProviderNames.FileSystem)) { string message = StringUtil.Format(RemotingErrorIdStrings.StartJobDefinitionPathInvalidNotFSProvider, _definitionName, _definitionPath, provider.FullName); WriteError(new ErrorRecord(new RuntimeException(message), "StartJobFromDefinitionNamePathInvalidNotFileSystemProvider", ErrorCategory.InvalidArgument, null)); return; } // Only a single file path is allowed. if (paths.Count != 1) { string message = StringUtil.Format(RemotingErrorIdStrings.StartJobDefinitionPathInvalidNotSingle, _definitionName, _definitionPath); WriteError(new ErrorRecord(new RuntimeException(message), "StartJobFromDefinitionNamePathInvalidNotSingle", ErrorCategory.InvalidArgument, null)); return; } resolvedPath = paths[0]; } List <Job2> jobs = JobManager.GetJobToStart(_definitionName, resolvedPath, _definitionType, this, false); if (jobs.Count == 0) { string message = (_definitionType != null) ? StringUtil.Format(RemotingErrorIdStrings.StartJobDefinitionNotFound2, _definitionType, _definitionName) : StringUtil.Format(RemotingErrorIdStrings.StartJobDefinitionNotFound1, _definitionName); WriteError(new ErrorRecord(new RuntimeException(message), "StartJobFromDefinitionNameNotFound", ErrorCategory.ObjectNotFound, null)); return; } if (jobs.Count > 1) { string message = StringUtil.Format(RemotingErrorIdStrings.StartJobManyDefNameMatches, _definitionName); WriteError(new ErrorRecord(new RuntimeException(message), "StartJobFromDefinitionNameMoreThanOneMatch", ErrorCategory.InvalidResult, null)); return; } // Start job. Job2 job = jobs[0]; job.StartJob(); // Write job object to host. WriteObject(job); return; } if (_firstProcessRecord) { _firstProcessRecord = false; PSRemotingJob job = new PSRemotingJob(ResolvedComputerNames, Operations, ScriptBlock.ToString(), ThrottleLimit, _name); job.PSJobTypeName = s_startJobType; this.JobRepository.Add(job); WriteObject(job); } // inject input if (InputObject != AutomationNull.Value) { foreach (IThrottleOperation operation in Operations) { ExecutionCmdletHelper helper = (ExecutionCmdletHelper)operation; helper.Pipeline.Input.Write(InputObject); } } }
public async Task GetSourceAsync( IExecutionContext executionContext, ServiceEndpoint endpoint, CancellationToken cancellationToken) { Trace.Entering(); // Validate args. ArgUtil.NotNull(executionContext, nameof(executionContext)); ArgUtil.NotNull(endpoint, nameof(endpoint)); ISvnCommandManager svn = HostContext.CreateService <ISvnCommandManager>(); svn.Init(executionContext, endpoint, cancellationToken); // Determine the sources directory. string sourcesDirectory = GetEndpointData(endpoint, Constants.EndpointData.SourcesDirectory); executionContext.Debug($"sourcesDirectory={sourcesDirectory}"); ArgUtil.NotNullOrEmpty(sourcesDirectory, nameof(sourcesDirectory)); string sourceBranch = GetEndpointData(endpoint, Constants.EndpointData.SourceBranch); executionContext.Debug($"sourceBranch={sourceBranch}"); string revision = GetEndpointData(endpoint, Constants.EndpointData.SourceVersion); if (string.IsNullOrWhiteSpace(revision)) { revision = "HEAD"; } executionContext.Debug($"revision={revision}"); bool clean = endpoint.Data.ContainsKey(EndpointData.Clean) && StringUtil.ConvertToBoolean(endpoint.Data[EndpointData.Clean], defaultValue: false); executionContext.Debug($"clean={clean}"); // Get the definition mappings. List <SvnMappingDetails> allMappings = JsonConvert.DeserializeObject <SvnWorkspace> (endpoint.Data[EndpointData.SvnWorkspaceMapping]).Mappings; if (executionContext.Variables.System_Debug.HasValue && executionContext.Variables.System_Debug.Value) { allMappings.ForEach(m => executionContext.Debug($"ServerPath: {m.ServerPath}, LocalPath: {m.LocalPath}, Depth: {m.Depth}, Revision: {m.Revision}, IgnoreExternals: {m.IgnoreExternals}")); } Dictionary <string, SvnMappingDetails> normalizedMappings = svn.NormalizeMappings(allMappings); if (executionContext.Variables.System_Debug.HasValue && executionContext.Variables.System_Debug.Value) { executionContext.Debug($"Normalized mappings count: {normalizedMappings.Count}"); normalizedMappings.ToList().ForEach(p => executionContext.Debug($" [{p.Key}] ServerPath: {p.Value.ServerPath}, LocalPath: {p.Value.LocalPath}, Depth: {p.Value.Depth}, Revision: {p.Value.Revision}, IgnoreExternals: {p.Value.IgnoreExternals}")); } string normalizedBranch = svn.NormalizeRelativePath(sourceBranch, '/', '\\'); executionContext.Output(StringUtil.Loc("SvnSyncingRepo", endpoint.Name)); string effectiveRevision = await svn.UpdateWorkspace( sourcesDirectory, normalizedMappings, clean, normalizedBranch, revision); executionContext.Output(StringUtil.Loc("SvnBranchCheckedOut", normalizedBranch, endpoint.Name, effectiveRevision)); Trace.Verbose("Leaving SvnSourceProvider.GetSourceAsync"); }
public override void InitializeJobExtension(IExecutionContext executionContext, IList <JobStep> steps, WorkspaceOptions workspace) { Trace.Entering(); ArgUtil.NotNull(executionContext, nameof(executionContext)); executionContext.Output(StringUtil.Loc("PrepareReleasesDir")); var directoryManager = HostContext.GetService <IReleaseDirectoryManager>(); ReleaseId = executionContext.Variables.GetInt(Constants.Variables.Release.ReleaseId) ?? 0; TeamProjectId = executionContext.Variables.GetGuid(Constants.Variables.System.TeamProjectId) ?? Guid.Empty; SkipArtifactsDownload = executionContext.Variables.GetBoolean(Constants.Variables.Release.SkipArtifactsDownload) ?? false; string releaseDefinitionName = executionContext.Variables.Get(Constants.Variables.Release.ReleaseDefinitionName); // TODO: Should we also write to log in executionContext.Output methods? so that we don't have to repeat writing into logs? // Log these values here to debug scenarios where downloading the artifact fails. executionContext.Output($"ReleaseId={ReleaseId}, TeamProjectId={TeamProjectId}, ReleaseDefinitionName={releaseDefinitionName}"); var releaseDefinition = executionContext.Variables.Get(Constants.Variables.Release.ReleaseDefinitionId); if (string.IsNullOrEmpty(releaseDefinition)) { string pattern = new string(Path.GetInvalidFileNameChars()) + new string(Path.GetInvalidPathChars()); Regex regex = new Regex(string.Format("[{0}]", Regex.Escape(pattern))); releaseDefinition = regex.Replace(releaseDefinitionName, string.Empty); } var releaseTrackingConfig = directoryManager.PrepareArtifactsDirectory( HostContext.GetDirectory(WellKnownDirectory.Work), executionContext.Variables.System_CollectionId, executionContext.Variables.System_TeamProjectId.ToString(), releaseDefinition); ReleaseWorkingFolder = releaseTrackingConfig.ReleaseDirectory; ArtifactsWorkingFolder = Path.Combine( HostContext.GetDirectory(WellKnownDirectory.Work), releaseTrackingConfig.ReleaseDirectory, Constants.Release.Path.ArtifactsDirectory); executionContext.Output($"Release folder: {ArtifactsWorkingFolder}"); // Ensure directory exist if (!Directory.Exists(ArtifactsWorkingFolder)) { Trace.Info($"Creating {ArtifactsWorkingFolder}."); Directory.CreateDirectory(ArtifactsWorkingFolder); } SetLocalVariables(executionContext, ArtifactsWorkingFolder); // Log the environment variables available after populating the variable service with our variables LogEnvironmentVariables(executionContext); if (SkipArtifactsDownload) { // If this is the first time the agent is executing a task, we need to create the artifactsFolder // otherwise Process.StartWithCreateProcess() will fail with the error "The directory name is invalid" // because the working folder doesn't exist CreateWorkingFolderIfRequired(executionContext, ArtifactsWorkingFolder); // log the message that the user chose to skip artifact download and move on executionContext.Output(StringUtil.Loc("RMUserChoseToSkipArtifactDownload")); Trace.Info("Skipping artifact download based on the setting specified."); } else { ReleaseArtifacts = GetReleaseArtifacts(executionContext); if (!ReleaseArtifacts.Any()) { CreateArtifactsFolder(executionContext, ArtifactsWorkingFolder); Trace.Info("No artifacts found to be downloaded by agent."); } } CheckForAvailableDiskSpace(executionContext); }
public override string ToString() { StringBuilder buffer = new StringBuilder(); buffer.Append("[EXTENDEDFORMAT]\n"); if (XFType == XF_STYLE) { buffer.Append(" STYLE_RECORD_TYPE\n"); } else if (XFType == XF_CELL) { buffer.Append(" CELL_RECORD_TYPE\n"); } buffer.Append(" .fontindex = ") .Append(StringUtil.ToHexString(FontIndex)).Append("\n"); buffer.Append(" .formatindex = ") .Append(StringUtil.ToHexString(FormatIndex)).Append("\n"); buffer.Append(" .celloptions = ") .Append(StringUtil.ToHexString(CellOptions)).Append("\n"); buffer.Append(" .Islocked = ").Append(IsLocked) .Append("\n"); buffer.Append(" .Ishidden = ").Append(IsHidden) .Append("\n"); buffer.Append(" .recordtype= ") .Append(StringUtil.ToHexString(XFType)).Append("\n"); buffer.Append(" .parentidx = ") .Append(StringUtil.ToHexString(ParentIndex)).Append("\n"); buffer.Append(" .alignmentoptions= ") .Append(StringUtil.ToHexString(AlignmentOptions)).Append("\n"); buffer.Append(" .alignment = ").Append(Alignment) .Append("\n"); buffer.Append(" .wraptext = ").Append(WrapText) .Append("\n"); buffer.Append(" .valignment= ") .Append(StringUtil.ToHexString(VerticalAlignment)).Append("\n"); buffer.Append(" .justlast = ") .Append(StringUtil.ToHexString(JustifyLast)).Append("\n"); buffer.Append(" .rotation = ") .Append(StringUtil.ToHexString(Rotation)).Append("\n"); buffer.Append(" .indentionoptions= ") .Append(StringUtil.ToHexString(IndentionOptions)).Append("\n"); buffer.Append(" .indent = ") .Append(StringUtil.ToHexString(Indent)).Append("\n"); buffer.Append(" .shrinktoft= ").Append(ShrinkToFit) .Append("\n"); buffer.Append(" .mergecells= ").Append(MergeCells) .Append("\n"); buffer.Append(" .Readngordr= ") .Append(StringUtil.ToHexString(ReadingOrder)).Append("\n"); buffer.Append(" .formatflag= ") .Append(IsIndentNotParentFormat).Append("\n"); buffer.Append(" .fontflag = ") .Append(IsIndentNotParentFont).Append("\n"); buffer.Append(" .prntalgnmt= ") .Append(IsIndentNotParentAlignment).Append("\n"); buffer.Append(" .borderflag= ") .Append(IsIndentNotParentBorder).Append("\n"); buffer.Append(" .paternflag= ") .Append(IsIndentNotParentPattern).Append("\n"); buffer.Append(" .celloption= ") .Append(IsIndentNotParentCellOptions).Append("\n"); buffer.Append(" .borderoptns = ") .Append(StringUtil.ToHexString(BorderOptions)).Append("\n"); buffer.Append(" .lftln = ") .Append(StringUtil.ToHexString(BorderLeft)).Append("\n"); buffer.Append(" .rgtln = ") .Append(StringUtil.ToHexString(BorderRight)).Append("\n"); buffer.Append(" .topln = ") .Append(StringUtil.ToHexString(BorderTop)).Append("\n"); buffer.Append(" .btmln = ") .Append(StringUtil.ToHexString(BorderBottom)).Append("\n"); buffer.Append(" .paleteoptns = ") .Append(StringUtil.ToHexString(PaletteOptions)).Append("\n"); buffer.Append(" .leftborder= ") .Append(StringUtil.ToHexString(LeftBorderPaletteIdx)) .Append("\n"); buffer.Append(" .rghtborder= ") .Append(StringUtil.ToHexString(RightBorderPaletteIdx)) .Append("\n"); buffer.Append(" .diag = ") .Append(StringUtil.ToHexString(Diagonal)).Append("\n"); buffer.Append(" .paleteoptn2 = ") .Append(StringUtil.ToHexString(AdtlPaletteOptions)) .Append("\n"); buffer.Append(" .topborder = ") .Append(StringUtil.ToHexString(TopBorderPaletteIdx)) .Append("\n"); buffer.Append(" .botmborder= ") .Append(StringUtil.ToHexString(BottomBorderPaletteIdx)) .Append("\n"); buffer.Append(" .adtldiag = ") .Append(StringUtil.ToHexString(AdtlDiagBorderPaletteIdx)).Append("\n"); buffer.Append(" .diaglnstyl= ") .Append(StringUtil.ToHexString(AdtlDiagLineStyle)).Append("\n"); buffer.Append(" .Fillpattrn= ") .Append(StringUtil.ToHexString(AdtlFillPattern)).Append("\n"); buffer.Append(" .Fillpaloptn = ") .Append(StringUtil.ToHexString(FillPaletteOptions)) .Append("\n"); buffer.Append(" .foreground= ") .Append(StringUtil.ToHexString(FillForeground)).Append("\n"); buffer.Append(" .background= ") .Append(StringUtil.ToHexString(FillBackground)).Append("\n"); buffer.Append("[/EXTENDEDFORMAT]\n"); return(buffer.ToString()); }
public override string ToString() { if (IsOne()) { return("_1_"); } if (IsZero()) { return("_0_"); } return(String.Format(CultureInfo.InvariantCulture, "<{0}, {1}>", Variable, StringUtil.ToCommaSeparatedString(Children))); }
public Form_TestConnection() { InitializeComponent(); db = new DBFunction(); su = new StringUtil(); }