/// <summary> /// Gets the Projects of a a Solution Folder. /// </summary> /// <param name="solutionFolder">Solution Folder to get projects from.</param> /// <returns></returns> private static IEnumerable <Project> GetSolutionFolderProjects(Project solutionFolder) { var result = new List <Project>(); IEnumerator item = solutionFolder.ProjectItems.GetEnumerator(); while (item.MoveNext()) { var subProject = (item.Current as ProjectItem).SubProject; if (subProject == null) { continue; } if (subProject.Kind == ProjectKinds.vsProjectKindSolutionFolder) { result.AddRange(VisualStudioHelper.GetSolutionFolderProjects(subProject)); } else if (VisualStudioHelper.NotSupportedProjectTypes.Contains(subProject.Kind) == false) { result.Add(subProject); } } return(result); }
/// <summary> /// Gets the Projects of the provided Solution. /// </summary> /// <param name="solution">Solution to get the Projects from.</param> /// <returns></returns> public static List <Project> GetProjectsFromSolution(Solution solution) { var result = new List <Project>(); IEnumerator item = solution.Projects.GetEnumerator(); while (item.MoveNext()) { var project = (item.Current as Project); if (project == null) { continue; } if (project.Kind == ProjectKinds.vsProjectKindSolutionFolder) { result.AddRange(VisualStudioHelper.GetSolutionFolderProjects(project)); } else if (VisualStudioHelper.NotSupportedProjectTypes.Contains(project.Kind) == false) { result.Add(project); } } return(result.OrderBy(i => i.Name).ToList()); }
/// <summary> /// Gets the code classes form a CodeElements collection. /// </summary> /// <param name="codeElements">CodeElements collection from where to get the code classes.</param> /// <returns></returns> private static List <CodeClass> GetCodeClasses(CodeElements codeElements) { var result = new List <CodeClass>(); CodeClass codeClass; // Loop through code elements foreach (CodeElement code in codeElements) { if (code.Kind == vsCMElement.vsCMElementNamespace) { // Get classes from namespace result.AddRange(VisualStudioHelper.GetCodeClasses((code as CodeNamespace).Members)); } else if (code.Kind == vsCMElement.vsCMElementClass) { // Case code to CodeClass codeClass = (code as CodeClass); // Add class to the result result.Add(codeClass); // Add nested classes result.AddRange(VisualStudioHelper.GetCodeClasses(codeClass.Members)); } } return(result); }
/// <summary> /// Gets the code classes from a project. /// </summary> /// <param name="project">Project from where to obtain the code classes.</param> /// <returns></returns> public static IEnumerable <CodeClass> GetProjectCodeClasses(Project project) { var result = new List <CodeClass>(); foreach (ProjectItem codeFile in VisualStudioHelper.GetProjectCodeFiles(project)) { // Add classes from code file result.AddRange(VisualStudioHelper.GetCodeClasses(codeFile.FileCodeModel.CodeElements)); } return(result.OrderBy(c => c.Name)); }
/// <summary> /// Gets all items of the projects of a provided Solution. /// </summary> /// <param name="solution"></param> /// <returns></returns> public static List <ProjectItem> GetSolutionProjectItems(Solution solution) { var result = new List <ProjectItem>(); foreach (Project item in solution.Projects) { if (item.ProjectItems != null) { result.AddRange(VisualStudioHelper.GetProjectItems(item.ProjectItems)); } } return(result); }
/// <summary> /// Gets the full names of the types involved with the received type reference. /// </summary> /// <param name="typeRef">TypeRef from where to obtained the type full names involved with it.</param> /// <returns></returns> public static List <string> GetTypesFullNamesFromTypeRef(CodeTypeRef typeRef) { var result = new List <string>(); if (typeRef.TypeKind == vsCMTypeRef.vsCMTypeRefArray) { result.AddRange(VisualStudioHelper.GetTypesFullNamesFromTypeRef(typeRef.ElementType)); } else { result.AddRange(VisualStudioHelper.GetFullNamesFromFullName(typeRef.AsFullName)); } return(result); }
/// <summary> /// Gets the Entities namspace from an EDMX ProjectItem. /// </summary> /// <param name="edmxProjectItem">EDMX ProjectItem from where to find the Entities namespace.</param> /// <returns></returns> public static string GetEntitiesNamespace(ProjectItem edmxProjectItem) { // Use dynamic to get the container of the EDMX // It can be a Project or ProjectItem but both have "Properties" defined dynamic edmxContainer = (dynamic)edmxProjectItem.Collection.Parent; // Get project namespace string entitiesNamespace = VisualStudioHelper.GetDefaultNamespaceFromProperties(edmxContainer.Properties); if (string.IsNullOrWhiteSpace(entitiesNamespace) == true) { throw new ApplicationException(Resources.Error_EntitiesNamespaceNotFound); } return(entitiesNamespace); }
/// <summary> /// Gets the items of the provided ProjectItems collection. /// </summary> /// <param name="itemsCollection"></param> /// <returns></returns> public static List <ProjectItem> GetProjectItems(ProjectItems itemsCollection) { var result = new List <ProjectItem>(); foreach (ProjectItem item in itemsCollection) { result.Add(item); if (item.SubProject != null && item.SubProject.ProjectItems != null) { result.AddRange(VisualStudioHelper.GetProjectItems(item.SubProject.ProjectItems)); } if (item.ProjectItems != null) { result.AddRange(VisualStudioHelper.GetProjectItems(item.ProjectItems)); } } return(result); }
/// <summary> /// Executed when a Project is removed from the Solution. /// </summary> /// <param name="projectRemoved">Project removed.</param> private static void SolutionEvents_ProjectRemoved(Project projectRemoved) { try { if (VisualStudioHelper.ErrorTaskCollection != null) { // Loop through ErrorTask collection for (int i = (VisualStudioHelper.ErrorTaskCollection.Count - 1); i >= 0; i--) { // Get the ErrorTask ErrorTask objErrorTask = VisualStudioHelper.ErrorTaskCollection.ElementAt(i); if (objErrorTask.HierarchyItem != null) { // Try to get the Project of the ErrorTask object errorTaskProject; ErrorHandler.ThrowOnFailure(objErrorTask.HierarchyItem.GetProperty( VSConstants.VSITEMID_ROOT, Convert.ToInt32(__VSHPROPID.VSHPROPID_ExtObject), out errorTaskProject)); if (errorTaskProject != null && errorTaskProject is Project) { // Cast the Project of the ErrorTask var objErrorTaskProject = (errorTaskProject as Project); if (objErrorTaskProject.UniqueName == projectRemoved.UniqueName) { // If it is the same Project then remove the ErrorTask from the Error List pane and our collection VisualStudioHelper.RemoveTask(objErrorTask); } } } } } } catch (Exception ex) { // Show error message MessageBox.Show(ex.Message, Resources.Error_Caption, MessageBoxButtons.OK, MessageBoxIcon.Error); } }
/// <summary> /// Removes all the ErrorTasks from the ErrorList pane and our collection. /// </summary> public static void ClearErrorList() { try { if (VisualStudioHelper.ErrorTaskCollection.Count > 0) { for (int i = (VisualStudioHelper.ErrorTaskCollection.Count - 1); i >= 0; i--) { // Get the ErrorTask ErrorTask objErrorTask = VisualStudioHelper.ErrorTaskCollection.ElementAt(i); // Remove the ErrorTask from the ErorList pane and our collection VisualStudioHelper.RemoveTask(objErrorTask); } } } catch (Exception ex) { // Show error message MessageBox.Show(ex.Message, Resources.Error_Caption, MessageBoxButtons.OK, MessageBoxIcon.Error); } }
/// <summary> /// Gets a valid Property name /// </summary> /// <param name="propertyNameDesired">Property name desired</param> /// <param name="entityOwnerName">Entity owner name</param> /// <returns></returns> public static string GetPropertyName(string propertyNameDesired, string entityOwnerName) { if (string.IsNullOrWhiteSpace(propertyNameDesired)) { throw new ApplicationException(string.Format(Resources.Error_PropertyNameCannotBeEmpty, entityOwnerName)); } if (PropertyHelper.ReservedNames.Contains(propertyNameDesired.ToLower())) { string newPropertyName = (propertyNameDesired + Resources.NameSeparator); // TODO: ffernandez, indicate Project-ProjectItem-Line-Column VisualStudioHelper.AddToErrorList(TaskErrorCategory.Warning, string.Format(Resources.Warning_InvalidPropertyName, entityOwnerName, propertyNameDesired, newPropertyName), null, null, null, null); return(newPropertyName); } else { return(propertyNameDesired); } }
/// <summary> /// Executed when the BackgroundWorker decides to execute the provided Logic (i.e., the Log process). /// </summary> /// <param name="sender"></param> /// <param name="args"></param> private static void Log_DoWork(object sender, DoWorkEventArgs args) { try { // Synchronize threads lock (LogManager.Lock) { // First log in this Visual Studio session? if (LogManager.isFirstLog == true) { LogManager.isFirstLog = false; // Delete log file, we are going to create a new log file // for this Visual Studio session File.Delete(LogManager.LogFilePath); } // Compose log entry string logMessage = LogManager.GetLogEntryTimeStamp() + (string)args.Argument + Environment.NewLine + Resources.LogSeparator + Environment.NewLine; // Append log entry to log file File.AppendAllText(LogManager.LogFilePath, logMessage); } } catch (Exception ex) { // Create a Warning if Log is not possible string message = (args.Argument != null ? args.Argument.ToString() : string.Empty); message = string.Format(Resources.Warning_CouldNotLogMessage, message) + Environment.NewLine + string.Format(Resources.Warning_ExceptionWhenLog, ex.Message); // Add warning to ErrorList pane VisualStudioHelper.AddToErrorList(TaskErrorCategory.Warning, message, null, null, null, null); } }
/// <summary> /// Executed before closing the Solution. /// </summary> private static void SolutionEvents_BeforeClosing() { // Remove Error Tasks from the Error List pane and our collection VisualStudioHelper.ClearErrorList(); }
/// <summary> /// Gets the CSharp Type from a EDMX Property. /// </summary> /// <param name="propertyNode">Type attribute.</param> /// <param name="entityOwnerName">Entity owner name.</param> /// <returns></returns> public static string GetTypeFromEDMXProperty(XElement propertyNode, string entityOwnerName) { // Get the Type attribute XAttribute typeAttribute = propertyNode.Attribute(EdmxNodeAttributes.Property_Type); // Check Type attribute exists if (typeAttribute == null) { string propertyName = propertyNode.Attribute(EdmxNodeAttributes.Property_Name).Value; throw new ApplicationException(string.Format(Resources.Error_PropertyTypeAttributeMissing, entityOwnerName, propertyName)); } // Get the Type value string edmxTypeValue = propertyNode.Attribute(EdmxNodeAttributes.Property_Type).Value; // Check Type value is not empty if (string.IsNullOrWhiteSpace(edmxTypeValue)) { string propertyName = propertyNode.Attribute(EdmxNodeAttributes.Property_Name).Value; throw new ApplicationException(string.Format(Resources.Error_PropertyTypeAttributeMissing, entityOwnerName, propertyName)); } // Check if it is Nullable bool isNullable = true; XAttribute nullableAttribute = propertyNode.Attribute(EdmxNodeAttributes.Property_Nullable); if (nullableAttribute != null) { isNullable = (nullableAttribute.Value == Resources.XmlBoolTrue); } // Variables string outputType = null; bool outputTypeAdmitsNullable = false; // Check if it is a supported type and we got the mapping for it if (PropertyHelper.EdmxCSharpMapping.ContainsKey(edmxTypeValue)) { // Do the mapping between the EDMX type and the C# type outputType = PropertyHelper.EdmxCSharpMapping[edmxTypeValue].Name; outputTypeAdmitsNullable = PropertyHelper.EdmxCSharpMapping[edmxTypeValue].AllowsNullable; } else { // Get type name without namespce to check if it is a type defined in the EDMX (ComplexType, EnumType) string edmxTypeName = EdmxHelper.GetNameWithoutNamespace(edmxTypeValue); // Check if it is a complex type DTOEntity complexTypeDTO = PropertyHelper.ComplexTypes.FirstOrDefault(ct => ct.Name == edmxTypeName); if (complexTypeDTO != null) { // It is a ComplexType outputType = complexTypeDTO.NameDTO; outputTypeAdmitsNullable = true; } else if (PropertyHelper.EnumTypes.Exists(e => e.Name == edmxTypeName)) { // It is an EnumType outputType = edmxTypeName; outputTypeAdmitsNullable = true; } else { // Not a supported Type neither a Type defined in the EDMX // Use object type and notify the user outputType = Resources.CSharpTypeObject; outputTypeAdmitsNullable = true; string propertyName = propertyNode.Attribute(EdmxNodeAttributes.Property_Name).Value; // TODO: ffernandez, indicate Project-ProjectItem-Line-Column VisualStudioHelper.AddToErrorList(TaskErrorCategory.Warning, string.Format(Resources.Warning_NotSupportedEDMXPropertyType, entityOwnerName, propertyName, edmxTypeValue), null, null, null, null); } } // Check if it is Nullable and the Type admits Nullable Types if (isNullable && outputTypeAdmitsNullable) { outputType = string.Format(Resources.CSharpTypeNullableT, outputType); } return(outputType); }
/// <summary> /// Generates the specified Source File in the received Project with the options /// provided and gets the Namespace ready to add code in it. /// </summary> /// <param name="targetProject">Project where the Source File is going to be placed.</param> /// <param name="targetProjectFolder">Project folder where the source file is going to be placed. /// Null indicates to place the source file as child of targetProject.</param> /// <param name="sourceFileName">Source File name to use.</param> /// <param name="sourceFileHeaderComment">Source File Header Comment (optional).</param> /// <param name="sourceNamespace">Namespace used in the Source File.</param> /// <param name="isServiceReady">Specifies if it is Service-Ready (serialization is going to be used).</param> /// <param name="sourceFileItem">(out parameter) Source File ProjectItem.</param> /// <returns></returns> public static CodeNamespace GenerateSourceAndGetNamespace(Project targetProject, ProjectItem targetProjectFolder, string sourceFileName, string sourceFileHeaderComment, string sourceNamespace, bool isServiceReady, out ProjectItem sourceFileItem) { // Validate source file name if (sourceFileName.EndsWith(Resources.CSharpFileExtension) == false) { sourceFileName += Resources.CSharpFileExtension; } // Validate source file header comment if (string.IsNullOrWhiteSpace(sourceFileHeaderComment) == false) { if (sourceFileHeaderComment.IndexOf("*/") >= 0) { throw new ApplicationException(Resources.Error_HeaderCommentInvalidChars); } } // ProjectItems collection where to place the source file ProjectItems projectItems = targetProject.ProjectItems; if (targetProjectFolder != null) { // Place inside received project folder projectItems = targetProjectFolder.ProjectItems; } // Properties collection of the target EnvDTE.Properties targetProperties = targetProject.Properties; if (targetProjectFolder != null) { targetProperties = targetProjectFolder.Properties; } // Source file sourceFileItem = null; #region If source file exists in the target, clear it and get the reference foreach (ProjectItem projItem in projectItems) { string projItemFileName = projItem.Properties.Item(Resources.ProjectItem_FileName).Value.ToString(); if (sourceFileName.ToLower() == projItemFileName.ToLower()) { // Source file already exists sourceFileItem = projItem; if (sourceFileItem.FileCodeModel.CodeElements != null && sourceFileItem.FileCodeModel.CodeElements.Count > 0) { // Clear source file CodeElement firstElement = sourceFileItem.FileCodeModel.CodeElements.Item(1); CodeElement lastElement = sourceFileItem.FileCodeModel.CodeElements.Item( sourceFileItem.FileCodeModel.CodeElements.Count); EditPoint startPoint = firstElement.StartPoint.CreateEditPoint(); EditPoint endPoint = lastElement.EndPoint.CreateEditPoint(); while (startPoint.AtStartOfDocument != true) { startPoint.LineUp(); } while (endPoint.AtEndOfDocument != true) { endPoint.LineDown(); } startPoint.Delete(endPoint); } break; } } #endregion #region If source file NOT exists in the target, create it and get the reference if (sourceFileItem == null) { // New source file, get target path string targetPath = targetProperties.Item(Resources.Properties_LocalPath).Value.ToString(); // Check if the new source file already exists in the file system (and it is not added to the solution) if (File.Exists(targetPath + sourceFileName)) { // Rename the existent source file string backupSourceFileName = (sourceFileName + Resources.BackupFileExtension); File.Move((targetPath + sourceFileName), (targetPath + backupSourceFileName)); // Add warning VisualStudioHelper.AddToErrorList(TaskErrorCategory.Warning, string.Format(Resources.Warning_SourceFileAlreadyExists, sourceFileName, backupSourceFileName), targetProject, sourceFileName, null, null); } // Add source file to target sourceFileItem = projectItems.AddFromTemplate(TemplateClass.FilePath, sourceFileName); } #endregion #region Generate imports var importList = new List <SourceCodeImport>(); importList.Add(new SourceCodeImport(Resources.NamespaceSystem)); importList.Add(new SourceCodeImport(Resources.NamespaceSystemCollectionsGeneric)); importList.Add(new SourceCodeImport(Resources.NamespaceSystemText)); if (isServiceReady) { importList.Add(new SourceCodeImport(Resources.NamespaceSystemRuntimeSerialization)); } importList = importList.OrderBy(d => d.ImportNamespace).ToList(); #endregion Generate imports // Add imports to the source code VisualStudioHelper.AddImportsToSourceCode(ref sourceFileItem, importList); // Get Source file code start EditPoint objEditPoint = sourceFileItem.FileCodeModel.CodeElements.Item(1).StartPoint.CreateEditPoint(); objEditPoint.StartOfDocument(); // Add header comment if (string.IsNullOrWhiteSpace(sourceFileHeaderComment) == false) { sourceFileHeaderComment = (Environment.NewLine + sourceFileHeaderComment + Environment.NewLine); objEditPoint.Insert( string.Format(Resources.CSharpCommentMultiline, sourceFileHeaderComment) + Environment.NewLine); } // Add EntitiesToDTOs signature string timestamp = DateTime.Now.ToString("yyyy/MM/dd - HH:mm:ss"); objEditPoint.Insert(string.Format(Resources.EntitiesToDTOsSignature, AssemblyHelper.Version, timestamp)); objEditPoint.Insert(Environment.NewLine); // Add blank line before source file namespace objEditPoint.EndOfDocument(); objEditPoint.Insert(Environment.NewLine); // Add namespace CodeNamespace objNamespace = sourceFileItem.FileCodeModel .AddNamespace(sourceNamespace, AppConstants.PLACE_AT_THE_END); return(objNamespace); }
/// <summary> /// Adds the provided Reference to the received Project. /// </summary> /// <param name="targetProject">Project to add the Reference.</param> /// <param name="referencedProject">Project to be referenced.</param> public static void AddReferenceToProject(Project targetProject, Project referencedProject) { if (targetProject.FullName == referencedProject.FullName) { return; } if (targetProject.Object is VSLangProj.VSProject) { VSLangProj.VSProject vsproject = (VSLangProj.VSProject)targetProject.Object; VSLangProj.Reference reference = null; try { reference = vsproject.References.Find(referencedProject.Name); } catch (Exception) { // It failed to find one, so it must not exist. } if (reference == null) { try { vsproject.References.AddProject(referencedProject); } catch (Exception) { // Add warning to ErrorList pane VisualStudioHelper.AddToErrorList(TaskErrorCategory.Warning, string.Format(Resources.Warning_ManuallyAddReference, referencedProject.Name, targetProject.Name), targetProject, null, null, null); } } else { // Reference already exists. } } else if (targetProject.Object is VsWebSite.VSWebSite) { VsWebSite.VSWebSite vswebsite = (VsWebSite.VSWebSite)targetProject.Object; VsWebSite.AssemblyReference reference = null; try { foreach (VsWebSite.AssemblyReference r in vswebsite.References) { if (r.Name == referencedProject.Name) { reference = r; break; } } } catch (Exception) { // It failed to find one, so it must not exist. } if (reference == null) { try { vswebsite.References.AddFromProject(referencedProject); } catch (Exception) { // Add warning to ErrorList pane VisualStudioHelper.AddToErrorList(TaskErrorCategory.Warning, string.Format(Resources.Warning_ManuallyAddReference, referencedProject.Name, targetProject.Name), targetProject, null, null, null); } } else { // Reference already exists. } } else { // Add warning to ErrorList pane VisualStudioHelper.AddToErrorList(TaskErrorCategory.Warning, string.Format(Resources.Warning_ManuallyAddReference, referencedProject.Name, targetProject.Name), targetProject, null, null, null); } }
/// <summary> /// Adds the provided Reference to the received Project. /// </summary> /// <param name="targetProject">Project to add the Reference.</param> /// <param name="referenceIdentity">Reference Identity (Name).</param> /// <param name="browseUrl">URL of the Reference (same as the Identity if it is in the GAC).</param> public static void AddReferenceToProject(Project targetProject, string referenceIdentity, string browseUrl) { string path = string.Empty; if (browseUrl.StartsWith(referenceIdentity) == false) { // It is a path path = browseUrl; } if (targetProject.Object is VSLangProj.VSProject) { VSLangProj.VSProject vsproject = (VSLangProj.VSProject)targetProject.Object; VSLangProj.Reference reference = null; try { reference = vsproject.References.Find(referenceIdentity); } catch (Exception) { // It failed to find one, so it must not exist. } if (reference == null) { try { if (string.IsNullOrWhiteSpace(path)) { vsproject.References.Add(browseUrl); } else { vsproject.References.Add(path); } } catch (Exception) { // Add warning to ErrorList pane VisualStudioHelper.AddToErrorList(TaskErrorCategory.Warning, string.Format(Resources.Warning_ManuallyAddReference, referenceIdentity, targetProject.Name), targetProject, null, null, null); } } else { // Reference already exists. } } else if (targetProject.Object is VsWebSite.VSWebSite) { VsWebSite.VSWebSite vswebsite = (VsWebSite.VSWebSite)targetProject.Object; VsWebSite.AssemblyReference reference = null; try { foreach (VsWebSite.AssemblyReference r in vswebsite.References) { if (r.Name == referenceIdentity) { reference = r; break; } } } catch (Exception) { // It failed to find one, so it must not exist. } if (reference == null) { if (string.IsNullOrWhiteSpace(path)) { vswebsite.References.AddFromGAC(browseUrl); } else { vswebsite.References.AddFromFile(path); } } else { // Reference already exists. } } else { // Add warning to ErrorList pane VisualStudioHelper.AddToErrorList(TaskErrorCategory.Warning, string.Format(Resources.Warning_ManuallyAddReference, referenceIdentity, targetProject.Name), targetProject, null, null, null); } }
/// <summary> /// Gets the project code files. /// </summary> /// <param name="project">Project from where to obtain the code files.</param> /// <returns></returns> public static IEnumerable <ProjectItem> GetProjectCodeFiles(Project project) { return(VisualStudioHelper.GetProjectItems(project.ProjectItems) .Where(i => i.Name.EndsWith(Resources.CSharpFileExtension)) .OrderBy(i => i.Name)); }