using Aitex.Common.Util; using Aitex.Core.RT.Event; using Aitex.Core.RT.Log; using Aitex.Core.Util; using Aitex.Core.Utilities; using Aitex.Core.WCF; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.Properties; using MECF.Framework.Common.RecipeCenter; using System; using System.Collections.Generic; using System.IO; using System.Text; using System.Text.RegularExpressions; using System.Xml; using System.Xml.Schema; using CyberX8_Core; using System.Linq; using System.Collections.ObjectModel; using Aitex.Core.RT.Routine; using System.Windows.Media.Converters; namespace Aitex.Core.RT.RecipeCenter { public class RecipeFileManager : Singleton { //sequence文件 统一放在 Recipes/Sequence 文件夹下面 public const string SequenceFolder = "Sequence"; public const string SourceModule = "Recipe"; public const string ProductionFolder = "Production"; public const string EngineeringFolder = "Engineering"; private bool _recipeIsValid; private List _validationErrors = new List(); private List _validationWarnings = new List(); IRecipeFileContext _rcpContext; private ISequenceFileContext _seqContext; public void Initialize(IRecipeFileContext context) { Initialize(context, null, true); } public void Initialize(IRecipeFileContext context, bool enableService) { Initialize(context, null, enableService); } public void Initialize(IRecipeFileContext rcpContext, ISequenceFileContext seqContext, bool enableService) { _rcpContext = rcpContext == null ? new DefaultRecipeFileContext() : rcpContext; _seqContext = seqContext == null ? new DefaultSequenceFileContext() : seqContext; CultureSupported.UpdateCoreCultureResource(CultureSupported.English); //if (enableService) //{ // Singleton.Instance.Initialize(new Type[] // { // typeof(RecipeService) // }); //} var dir = string.Format("{0}{1}\\", PathManager.GetRecipeDir(), SequenceFolder); DirectoryInfo di = new DirectoryInfo(dir); if (!di.Exists) { di.Create(); } } private void ValidationEventHandler(object sender, ValidationEventArgs e) { switch (e.Severity) { case XmlSeverityType.Error: _validationErrors.Add(e.Message); _recipeIsValid = false; break; case XmlSeverityType.Warning: _validationWarnings.Add(e.Message); break; } } /// /// XML schema checking /// /// /// /// /// /// public bool ValidateRecipe(string chamberId, string recipeName, string recipeContent, out List reason) { try { XmlDocument document = new XmlDocument(); document.LoadXml(recipeContent); MemoryStream schemaStream = new MemoryStream(ASCIIEncoding.ASCII.GetBytes(GetRecipeSchema(chamberId))); XmlReader xmlSchemaReader = XmlReader.Create(schemaStream); XmlSchema schema1 = XmlSchema.Read(xmlSchemaReader, ValidationEventHandler); document.Schemas.Add(schema1); document.LoadXml(recipeContent); ValidationEventHandler eventHandler = new ValidationEventHandler(ValidationEventHandler); _recipeIsValid = true; _validationErrors = new List(); _validationWarnings = new List(); // Validates recipe. document.Validate(eventHandler); } catch (Exception ex) { LOG.WriteExeption(ex); _recipeIsValid = false; } if (!_recipeIsValid && _validationErrors.Count == 0) { _validationErrors.Add(Resources.RecipeFileManager_ValidateRecipe_XMLSchemaValidateFailed); } reason = _validationErrors; return _recipeIsValid; } /// /// This method will be invoked by two places: /// (1) Load a recipe from server to GUI for editing (do not need validation when loading, do validation when saving); /// (2) Load a recipe from recipe engine to run process(always do a validation before run recipe); /// /// /// indicate whether a recipe format validation is needed or not /// public string LoadRecipe(string chamberId, string recipeName, bool needValidation) { string rcp = string.Empty; try { using (StreamReader fs = new StreamReader(GenerateRecipeFilePath(chamberId, recipeName))) { rcp = fs.ReadToEnd(); fs.Close(); } } catch (Exception ex) { LOG.WriteExeption($"load recipe file failed, {recipeName}", ex); rcp = string.Empty; } return rcp; } public string LoadRecipeByPath(string path) { string rcp = string.Empty; try { using (StreamReader fs = new StreamReader(path)) { rcp = fs.ReadToEnd(); fs.Close(); } } catch (Exception ex) { // LOG.WriteExeption($"load recipe file failed, {recipeName}", ex); rcp = string.Empty; } return rcp; } /// /// Get recipe list /// /// /// /// public IEnumerable GetRecipes(string chamberId, bool includingUsedRecipe) { return _rcpContext.GetRecipes(chamberId, includingUsedRecipe); } /// /// 加载工程指定类型Recipe /// /// /// public ObservableCollection GetEngineeringRecipesByType(string recipeType) { try { ObservableCollection treeNodes = new ObservableCollection(); string recipePath = PathManager.GetRecipeDir(); var di = new DirectoryInfo(recipePath); DirectoryInfo[] infos = di.GetDirectories(); var recipes = new List(); foreach (var info in infos) { if (info.Name == "Engineering") { FileInfo[] files = info.GetFiles(); recipes.Add(info.Name); foreach (FileInfo file in files) { if (file.Name.Contains($".{recipeType}.")) { RecipeNode childNode = new RecipeNode(); childNode.Name = file.Name.Substring(0, file.Name.IndexOf($".{recipeType}")); childNode.NodeType = RecipeNodeType.File; childNode.RecipeLocation = info.Name; childNode.FileName = file.Name; childNode.RecipeFullFileName = file.FullName; treeNodes.Add(childNode); } } } } return treeNodes; } catch (Exception ex) { LOG.WriteExeption(ex); return new ObservableCollection(); } } /// /// 加载指定类型的Recipe /// /// /// public ObservableCollection GetRecipesByType(string recipeType) { try { ObservableCollection treeNodes = new ObservableCollection(); string recipePath = PathManager.GetRecipeDir() ; var di = new DirectoryInfo(recipePath); DirectoryInfo[] infos= di.GetDirectories(); var recipes = new List(); foreach (var info in infos) { RecipeNode treeNode = new RecipeNode(); treeNode.Name = info.Name; treeNode.NodeType = RecipeNodeType.Directory; treeNode.Children =new ObservableCollection(); FileInfo[] files = info.GetFiles(); recipes.Add(info.Name); foreach(FileInfo file in files) { if (file.Name.Contains($".{recipeType}.")) { RecipeNode childNode = new RecipeNode(); childNode.Name = file.Name.Substring(0,file.Name.IndexOf($".{recipeType}")); childNode.NodeType = RecipeNodeType.File; childNode.RecipeLocation = info.Name; childNode.FileName = file.Name; childNode.RecipeFullFileName = file.FullName; treeNode.Children.Add(childNode); } } treeNodes.Add(treeNode); } return treeNodes; } catch (Exception ex) { LOG.WriteExeption(ex); return new ObservableCollection(); } } /// /// 获取目录集合节点 /// /// /// public ObservableCollection GetRecipeByDirectoryList(List directories) { try { ObservableCollection treeNodes = new ObservableCollection(); string recipePath = PathManager.GetRecipeDir(); var di = new DirectoryInfo(recipePath); DirectoryInfo[] infos = di.GetDirectories(); var recipes = new List(); foreach (var info in infos) { if (directories.Contains(info.Name)) { RecipeNode treeNode = new RecipeNode(); treeNode.Name = info.Name; treeNode.NodeType = RecipeNodeType.Directory; treeNode.Children = new ObservableCollection(); FileInfo[] files = info.GetFiles(); recipes.Add(info.Name); foreach (FileInfo file in files) { if (file.Name.EndsWith($".rcp")) { RecipeNode childNode = new RecipeNode(); string recipeTypeName = file.Name.Substring(0, file.Name.IndexOf($".rcp")); int recipeTypeIndex = recipeTypeName.LastIndexOf("."); if (recipeTypeIndex != -1) { childNode.Name = recipeTypeName.Substring(0, recipeTypeIndex); childNode.NodeType = RecipeNodeType.File; childNode.RecipeLocation = info.Name; childNode.FileName = file.Name; childNode.RecipeFullFileName = file.FullName; treeNode.Children.Add(childNode); } } } treeNodes.Add(treeNode); } } return treeNodes; } catch (Exception ex) { LOG.WriteExeption(ex); return new ObservableCollection(); } } /// /// 删除Recipe文件 /// /// /// public bool DeleteRecipeByFullPath(string fullPath) { try { if (File.Exists(fullPath)) { File.Delete(fullPath); } } catch (Exception ex) { LOG.WriteExeption("delete recipe file error", ex); return false; } return true; } public bool PromoteRecipe(List FilePaths) { try { foreach (var SourceFilePath in FilePaths) { string TargetFilePath = SourceFilePath.Replace("Engineering", "Production"); File.Copy(SourceFilePath, TargetFilePath, true); } } catch (Exception ex) { LOG.WriteExeption("Promote recipe file error", ex); return false; } return true; } /// /// 加载Recipe /// /// /// /// public T LoadGenericityRecipe(string recipeFileFullName) { try { return CustomXmlSerializer.Deserialize(new FileInfo(recipeFileFullName)); } catch { return default(T); } } /// /// Get recipe list in xml format /// /// /// /// public string GetXmlRecipeList(string chamberId, bool includingUsedRecipe) { XmlDocument doc = new XmlDocument(); var baseFolderPath = getRecipeDirPath(chamberId); DirectoryInfo curFolderInfo = new DirectoryInfo(baseFolderPath); doc.AppendChild(GenerateRecipeList(chamberId, curFolderInfo, doc, includingUsedRecipe)); return doc.OuterXml; } /// /// generate recipe list information in current directory /// /// /// /// /// XmlElement GenerateRecipeList(string chamberId, DirectoryInfo currentDir, XmlDocument doc, bool includingUsedRecipe) { int trimLength = getRecipeDirPath(chamberId).Length; XmlElement folderEle = doc.CreateElement("Folder"); folderEle.SetAttribute("Name", currentDir.FullName.Substring(trimLength)); DirectoryInfo[] dirInfos = currentDir.GetDirectories(); foreach (DirectoryInfo dirInfo in dirInfos) { if (!includingUsedRecipe && dirInfo.Name == "HistoryRecipe") continue; folderEle.AppendChild(GenerateRecipeList(chamberId, dirInfo, doc, includingUsedRecipe)); } FileInfo[] fileInfos = currentDir.GetFiles("*.rcp"); foreach (FileInfo fileInfo in fileInfos) { XmlElement fileNd = doc.CreateElement("File"); string fileStr = fileInfo.FullName.Substring(trimLength).TrimStart(new char[] { '\\' }); ; fileStr = fileStr.Substring(0, fileStr.LastIndexOf(".")); fileNd.SetAttribute("Name", fileStr); folderEle.AppendChild(fileNd); } return folderEle; } /// /// Delete a recipe by recipe name /// /// /// /// public bool DeleteRecipe(string chamberId, string recipeName) { try { var path = GenerateRecipeFilePath(chamberId, recipeName); if (!_rcpContext.EnableEdit(path)) return false; File.Delete(path); InfoDialog(string.Format(Resources.RecipeFileManager_DeleteRecipe_RecipeFile0DeleteSucceeded, recipeName)); } catch (Exception ex) { LOG.WriteExeption("删除recipe file 出错", ex); WarningDialog(string.Format(Resources.RecipeFileManager_DeleteRecipe_RecipeFile0DeleteFailed, recipeName)); return false; } return true; } /// /// Rename recipe /// /// /// /// /// public bool RenameRecipe(string chamId, string oldName, string newName) { try { var path = GenerateRecipeFilePath(chamId, newName); if (!_rcpContext.EnableEdit(path)) return false; if (File.Exists(path)) { WarningDialog(string.Format(Resources.RecipeFileManager_RenameRecipe_RecipeFile0FileExisted, oldName)); return false; } else { File.Move(GenerateRecipeFilePath(chamId, oldName), GenerateRecipeFilePath(chamId, newName)); InfoDialog(string.Format(Resources.RecipeFileManager_RenameRecipe_RecipeFile0Renamed, oldName, newName)); } } catch (Exception ex) { LOG.WriteExeption("重命名recipe file 出错", ex); WarningDialog(string.Format(Resources.RecipeFileManager_RenameRecipe_RecipeFile0RenameFailed, oldName, newName)); return false; } return true; } private void InfoDialog(string message) { _rcpContext.PostInfoDialogMessage(message); } private void WarningDialog(string message) { _rcpContext.PostWarningDialogMessage(message); } /// /// get recipe's file path /// /// /// private string GenerateRecipeFilePath(string chamId, string recipeName) { return getRecipeDirPath(chamId) + recipeName + ".rcp"; } private string GenerateRecipeFilePath2(string chamId, string type,string recipeName) { return getRecipeDirPath(chamId) +type+"\\"+ recipeName + ".rcp"; } private string GenerateSequenceFilePath(string chamId, string recipeName) { return getRecipeDirPath(chamId) + recipeName + ".seq"; } /// /// get recipe's dir path /// /// /// private string getRecipeDirPath(string chamId) { var dir = string.Format("{0}{1}\\", PathManager.GetRecipeDir(), chamId); DirectoryInfo di = new DirectoryInfo(dir); if (!di.Exists) di.Create(); return dir; } /// /// 保存Recipe /// /// /// /// /// public void SaveGenericityRecipe(string root, string recipeName, string recipeType, object recipe) { try { string recipeDir = PathManager.GetRecipeDir(); string fullName = $"{recipeDir}{root}\\{recipeName}.{recipeType}.rcp"; CustomXmlSerializer.Serialize(recipe, fullName); } catch { } } /// /// delete a recipe folder /// /// /// /// public bool DeleteFolder(string chamId, string folderName) { try { Directory.Delete(getRecipeDirPath(chamId) + folderName, true); InfoDialog(string.Format(Resources.RecipeFileManager_DeleteFolder_RecipeFolder0DeleteSucceeded, folderName)); } catch (Exception ex) { LOG.WriteExeption("删除recipe folder 出错", ex); WarningDialog(string.Format("recipe folder {0} delete failed", folderName)); return false; } return true; } /// /// save as recipe content /// /// /// /// /// public bool SaveAsRecipe(string chamId, string recipeName, string recipeContent) { var path = GenerateRecipeFilePath(chamId, recipeName); //if (File.Exists(path)) //{ // WarningDialog(string.Format(Resources.RecipeFileManager_SaveAsRecipe_RecipeFile0savefailed, recipeName)); // return false; //} return SaveRecipe(chamId, recipeName, recipeContent, true, true); } public bool SaveAsRecipe2(string chamId,string type, string recipeName, string recipeContent) { var path = GenerateRecipeFilePath(chamId, recipeName); //if (File.Exists(path)) //{ // WarningDialog(string.Format(Resources.RecipeFileManager_SaveAsRecipe_RecipeFile0savefailed, recipeName)); // return false; //} return SaveRecipe2(chamId,type, recipeName, recipeContent, true, true); } /// /// save recipe content /// /// /// /// /// public bool SaveRecipe(string chamId, string recipeName, string recipeContent, bool clearBarcode, bool notifyUI) { bool ret = true; try { var path = GenerateRecipeFilePath(chamId, recipeName); if (!_rcpContext.EnableEdit(path)) return false; FileInfo fi = new FileInfo(path); if (!fi.Directory.Exists) fi.Directory.Create(); File.WriteAllText(path, RecipeUnity.ConvertJsonString(recipeContent), Encoding.UTF8); } catch (Exception ex) { LOG.WriteExeption("保存recipe file 出错", ex); if (notifyUI) { WarningDialog(string.Format(Resources.RecipeFileManager_SaveRecipe_RecipeFile0SaveFailed, recipeName)); } ret = false; } return ret; } /// /// save recipe content /// /// /// /// /// public bool SaveRecipe2(string chamId,string type, string recipeName, string recipeContent, bool clearBarcode, bool notifyUI) { bool ret = true; try { var path = GenerateRecipeFilePath2(chamId, type, recipeName); if (!_rcpContext.EnableEdit(path)) return false; FileInfo fi = new FileInfo(path); if (!fi.Directory.Exists) fi.Directory.Create(); File.WriteAllText(path, RecipeUnity.ConvertJsonString(recipeContent), Encoding.UTF8); } catch (Exception ex) { LOG.WriteExeption("保存recipe file 出错", ex); if (notifyUI) { WarningDialog(string.Format(Resources.RecipeFileManager_SaveRecipe_RecipeFile0SaveFailed, recipeName)); } ret = false; } return ret; } /// /// move recipe file /// /// /// /// public bool MoveRecipeFile(string chamId, string recipeName, string tragetFolderName, bool clearBarcode, bool notifyUI) { bool ret = true; try { var path = getRecipeDirPath(chamId); string fullFileName = path + recipeName + ".rcp"; string tragetFullFilePath = path + tragetFolderName; File.Move(fullFileName, tragetFullFilePath + "\\" + recipeName.Split('\\')[recipeName.Split('\\').Length - 1] + ".rcp"); if (notifyUI) { InfoDialog(string.Format(Resources.RecipeFileManager_MoveRecipe_RecipeFile0MoveCompleted, recipeName)); } else { LOG.Write(eEvent.EV_SEQUENCE, ModuleName.System, string.Format(Resources.RecipeFileManager_MoveRecipe_RecipeFile0MoveCompleted, recipeName)); } } catch (Exception ex) { LOG.WriteExeption("移动 recipe file 出错", ex); if (notifyUI) { WarningDialog(string.Format(Resources.RecipeFileManager_MoveRecipe_RecipeFile0MoveFailed, recipeName)); } ret = false; } return ret; } /// /// create a new recipe folder /// /// /// /// public bool CreateFolder(string chamId, string folderName) { try { Directory.CreateDirectory(getRecipeDirPath(chamId) + folderName); InfoDialog(string.Format(Resources.RecipeFileManager_CreateFolder_RecipeFolder0Created, folderName)); } catch (Exception ex) { LOG.WriteExeption("创建recipe folder 出错", ex); WarningDialog(string.Format(Resources.RecipeFileManager_CreateFolder_RecipeFolder0CreateFailed, folderName)); return false; } return true; } /// /// Rename recipe folder name /// /// /// /// /// public bool RenameFolder(string chamId, string oldName, string newName) { try { string oldPath = getRecipeDirPath(chamId) + oldName; string newPath = getRecipeDirPath(chamId) + newName; Directory.Move(oldPath, newPath); InfoDialog(string.Format(Resources.RecipeFileManager_RenameFolder_RecipeFolder0renamed, oldName, newName)); } catch (Exception ex) { LOG.WriteExeption("重命名recipe folder 出错", ex); WarningDialog(string.Format(Resources.RecipeFileManager_RenameFolder_RecipeFolder0RenameFailed, oldName, newName)); return false; } return true; } private string GetRecipeBody(string chamberId, string nodePath) { if (_rcpContext == null) return string.Empty; string schema = _rcpContext.GetRecipeDefiniton(chamberId); XmlDocument dom = new XmlDocument(); dom.LoadXml(schema); XmlNode node = dom.SelectSingleNode(nodePath); return node.OuterXml; } /// /// get reactor's recipe format define file /// /// /// public string GetRecipeFormatXml(string chamberId) { return GetRecipeBody(chamberId, "/Aitex/TableRecipeFormat"); } /// /// get reactor's template recipe file /// /// /// public string GetRecipeTemplate(string chamberId) { if (_rcpContext != null) return _rcpContext.GetRecipeTemplate(chamberId); return GetRecipeBody(chamberId, "/Aitex/TableRecipeData"); } /// /// get reactor's template recipe file /// /// /// public string GetRecipeSchema(string chamberId) { if (_rcpContext == null) return string.Empty; string schema = _rcpContext.GetRecipeDefiniton(chamberId); XmlDocument dom = new XmlDocument(); dom.LoadXml(schema); XmlNode node = dom.SelectSingleNode("/Aitex/TableRecipeSchema"); return node.InnerXml; } #region Sequence private string GetSequenceConfig(string nodePath) { if (_seqContext == null) return string.Empty; string schema = _seqContext.GetConfigXml(); XmlDocument dom = new XmlDocument(); dom.LoadXml(schema); XmlNode node = dom.SelectSingleNode(nodePath); return node.OuterXml; } public string GetSequence(string sequenceName, bool needValidation) { string seq = string.Empty; try { using (StreamReader fs = new StreamReader(GenerateSequenceFilePath(SequenceFolder, sequenceName))) { seq = fs.ReadToEnd(); fs.Close(); } if (needValidation && !_seqContext.Validation(seq)) { LOG.Write(eEvent.WARN_SEQUENCE, ModuleName.System, $"Read {sequenceName} failed, validation failed"); seq = string.Empty; } } catch (Exception ex) { LOG.WriteExeption(ex); seq = string.Empty; } return seq; } private void TryAppendNode(XmlElement preOrNextNode, XmlElement curPM,XmlDocument dom, bool isLeft) { if (preOrNextNode != null && preOrNextNode.GetAttribute("Position") != "LL" && preOrNextNode.GetAttribute("Position") != "PM") { XmlElement newNode = dom.CreateElement("Step"); newNode.SetAttribute("Position", "LL"); newNode.SetAttribute("LLSelection", "LLA,LLB"); if (isLeft) curPM.ParentNode.InsertBefore(newNode, curPM); else curPM.ParentNode.InsertAfter(newNode, curPM); } } public string GetSequenceAndTryAppendLL(string sequenceName, bool needValidation) { string seq = string.Empty; try { seq = GetSequence(sequenceName, needValidation); if(!string.IsNullOrWhiteSpace(seq)) { XmlDocument dom = new XmlDocument(); dom.LoadXml(seq); XmlNodeList lstStepNode = dom.SelectNodes("Aitex/TableSequenceData/Step"); if (lstStepNode != null) { List pmList = new List(); foreach (XmlElement nodeStep in lstStepNode) { var positionValue = nodeStep.GetAttribute("Position"); if (positionValue == "PM") { pmList.Add(nodeStep); } } foreach (XmlElement pmNode in pmList) { TryAppendNode((XmlElement)pmNode.PreviousSibling, pmNode, dom, true); TryAppendNode((XmlElement)pmNode.NextSibling, pmNode, dom, false); } using (var ms = new MemoryStream()) using (var writer = new XmlTextWriter(ms, null)) { writer.Formatting = Formatting.Indented; dom.Save(writer); return Encoding.UTF8.GetString(ms.ToArray()); } } } } catch(Exception ex) { LOG.WriteExeption(ex); seq = string.Empty; } return seq; } public List GetSequenceNameList() { var result = new List(); try { string recipePath = PathManager.GetRecipeDir() + SequenceFolder + "\\"; var di = new DirectoryInfo(recipePath); var fis = di.GetFiles("*.seq.*", SearchOption.AllDirectories); foreach (var fi in fis) { string str = fi.FullName.Substring(recipePath.Length); str = str.Substring(0, str.LastIndexOf('.')); result.Add(str); } } catch (Exception ex) { LOG.WriteExeption(ex); } return result; } public bool DeleteSequence(string sequenceName) { try { var path = GenerateSequenceFilePath(SequenceFolder, sequenceName); if (!_seqContext.EnableEdit(path)) return false; File.Delete(path); LOG.Write(eEvent.EV_SEQUENCE, ModuleName.System, $"sequence {sequenceName} deleted"); } catch (Exception ex) { LOG.WriteExeption(ex); return false; } return true; } public bool SaveSequence(string sequenceName, string sequenceContent, bool notifyUI) { bool ret = true; try { var path = GenerateSequenceFilePath(SequenceFolder, sequenceName); if (!_seqContext.EnableEdit(path)) return false; FileInfo fi = new FileInfo(path); if (!fi.Directory.Exists) { fi.Directory.Create(); } XmlDocument xml = new XmlDocument(); xml.LoadXml(sequenceContent); XmlTextWriter writer = new XmlTextWriter(path, null); writer.Formatting = Formatting.Indented; xml.Save(writer); writer.Close(); if (notifyUI) { EV.PostPopDialogMessage(EventLevel.Information, "Save Complete", $"Sequence {sequenceName} saved "); } else { LOG.Write(eEvent.EV_SEQUENCE, ModuleName.System, $"Sequence {sequenceName} saved "); } } catch (Exception ex) { LOG.WriteExeption(ex); if (notifyUI) { EV.PostPopDialogMessage(EventLevel.Alarm, "Save Error", $"save sequence {sequenceName} failed, " + ex.Message); } ret = false; } return ret; } public bool SaveAsSequence(string sequenceName, string sequenceContent) { var path = GenerateSequenceFilePath(SequenceFolder, sequenceName); if (File.Exists(path)) { LOG.Write(eEvent.WARN_SEQUENCE, ModuleName.System, $"save sequence {sequenceName} failed, already exist"); return false; } return SaveSequence(sequenceName, sequenceContent, false); } public bool RenameSequence(string oldName, string newName) { try { var path = GenerateSequenceFilePath(SequenceFolder, oldName); if (!_seqContext.EnableEdit(path)) return false; if (File.Exists(GenerateSequenceFilePath(SequenceFolder, newName))) { LOG.Write(eEvent.WARN_SEQUENCE, ModuleName.System, $"{newName} already exist, rename failed"); return false; } else { File.Move(path, GenerateSequenceFilePath(SequenceFolder, newName)); LOG.Write(eEvent.EV_SEQUENCE, ModuleName.System, $"sequence {oldName} renamed to {newName}"); } } catch (Exception ex) { LOG.WriteExeption(ex); return false; } return true; } public string GetSequenceFormatXml() { return GetSequenceConfig("/Aitex/TableSequenceFormat"); } internal bool DeleteSequenceFolder(string folderName) { try { Directory.Delete(PathManager.GetRecipeDir() + SequenceFolder + "\\" + folderName, true); LOG.Write(eEvent.EV_SEQUENCE,ModuleName.System, "Folder " + folderName + "deleted"); } catch (Exception ex) { //LOG.Write(ex, "delete sequence folder exception"); LOG.Write(eEvent.WARN_SEQUENCE, ModuleName.System, $"can not delete folder {folderName}, {ex.Message}"); return false; } return true; } internal bool CreateSequenceFolder(string folderName) { try { Directory.CreateDirectory(PathManager.GetRecipeDir() + SequenceFolder + "\\" + folderName); LOG.Write(eEvent.EV_SEQUENCE, ModuleName.System, "Folder " + folderName + "created"); } catch (Exception ex) { //LOG.Write(ex, "sequence folder create exception"); LOG.Write(eEvent.WARN_SEQUENCE, ModuleName.System, $"can not create folder {folderName}, {ex.Message}"); return false; } return true; } internal bool RenameSequenceFolder(string oldName, string newName) { try { string oldPath = PathManager.GetRecipeDir() + SequenceFolder + "\\" + oldName; string newPath = PathManager.GetRecipeDir() + SequenceFolder + "\\" + newName; Directory.Move(oldPath, newPath); LOG.Write(eEvent.EV_SEQUENCE, ModuleName.System, $"rename folder from {oldName} to {newName}"); } catch (Exception ex) { //LOG.Write(ex, "rename sequence folder failed"); LOG.Write(eEvent.WARN_SEQUENCE, ModuleName.System, $"can not rename folder {oldName}, {ex.Message}"); return false; } return true; } public string GetXmlSequenceList(string chamberId) { XmlDocument doc = new XmlDocument(); DirectoryInfo curFolderInfo = new DirectoryInfo(PathManager.GetRecipeDir() + SequenceFolder + "\\"); doc.AppendChild(GenerateSequenceList(chamberId, curFolderInfo, doc)); return doc.OuterXml; } XmlElement GenerateSequenceList(string chamberId, DirectoryInfo currentDir, XmlDocument doc) { int trimLength = (PathManager.GetRecipeDir() + SequenceFolder + "\\").Length; XmlElement folderEle = doc.CreateElement("Folder"); folderEle.SetAttribute("Name", currentDir.FullName.Substring(trimLength)); DirectoryInfo[] dirInfos = currentDir.GetDirectories(); foreach (DirectoryInfo dirInfo in dirInfos) { folderEle.AppendChild(GenerateSequenceList(chamberId, dirInfo, doc)); } FileInfo[] fileInfos = currentDir.GetFiles("*.seq"); foreach (FileInfo fileInfo in fileInfos) { XmlElement fileNd = doc.CreateElement("File"); string fileStr = fileInfo.FullName.Substring(trimLength).TrimStart(new char[] { '\\' }); ; fileStr = fileStr.Substring(0, fileStr.LastIndexOf(".")); fileNd.SetAttribute("Name", fileStr); folderEle.AppendChild(fileNd); } return folderEle; } /// /// 获取Sequence(Recipes)文件路径的子目录 /// /// public List GetSequenceList(string recipeType, string sequenceType) { var result = new List(); try { string recipePath; if (sequenceType == "Engineering") { recipePath = PathManager.GetRecipeDir() + EngineeringFolder + "\\"; } else if(sequenceType == "Production") { recipePath = PathManager.GetRecipeDir() + ProductionFolder + "\\"; } else { return null; } var di = new DirectoryInfo(recipePath); var fis = di.GetFiles($"*.{recipeType}.*", SearchOption.TopDirectoryOnly); foreach (var fi in fis) { string str = fi.FullName.Substring(recipePath.Length); str = str.Substring(0, str.LastIndexOf($".{recipeType}")); result.Add(str); } } catch (Exception ex) { LOG.WriteExeption(ex); } return result; } #endregion #region FA相关 /// /// 获取recipe集合 /// /// public string[] GetProductionRecipeList() { List lst = new List(); try { string path = PathManager.GetRecipeDir() + ProductionFolder + "\\"; DirectoryInfo directoryInfo = new DirectoryInfo(path); FileInfo[] files = directoryInfo.GetFiles($"*.rcp", SearchOption.TopDirectoryOnly); foreach (var fi in files) { lst.Add($"{ProductionFolder}\\{fi.Name}"); } } catch(Exception ex) { LOG.WriteExeption(ex); } return lst.ToArray(); } /// /// 加载recipe内容 /// /// /// public string LoadRecipeContent(string recipeName) { string rcp = string.Empty; try { string path = PathManager.GetRecipeDir() + ProductionFolder + "\\"; using (StreamReader fs = new StreamReader($"{PathManager.GetRecipeDir()}{ProductionFolder}\\{recipeName}")) { rcp = fs.ReadToEnd(); fs.Close(); } } catch (Exception ex) { LOG.WriteExeption($"load recipe file failed, {recipeName}", ex); rcp = string.Empty; } return rcp; } #endregion } }