public int OnItemDeleted(uint itemid) { object itemRemoved; int retValue = m_hierarchy.GetProperty(itemid, (int)__VSHPROPID.VSHPROPID_ExtObject, out itemRemoved); if (retValue != VSConstants.S_OK) { return(retValue); } var item = itemRemoved as ProjectItem; if (item != null) { return(ProjectItemRemoved(item)); } if (itemRemoved is Reference) { // Handled from a different event handler. return(VSConstants.S_OK); } SpecUtilities.ShowMessage(string.Format(CultureInfo.InvariantCulture, "Unknown item type: {0}", itemRemoved.ToString())); return(VSConstants.S_OK); }
/// <summary> /// Gets the name of the reference /// </summary> /// <param name="reference">The reference whose name needs to be returned</param> /// <returns>Returns the name of the reference</returns> private static string GetReferenceName(Reference reference) { string name; // Check whether the reference is made to some of the existing projects if (reference.SourceProject != null) { string otherSpecFile; if (!SpecUtilities.TryGetSpecFileFromProject(reference.SourceProject.FileName, out otherSpecFile, out name)) { // SpecUtilities.ShowMessage(string.Format(CultureInfo.InvariantCulture, "Could not find specification file for the project: {0}", reference.SourceProject.Name)); return(null); } // Get the project kind. If its a CPP project, ".Object" needs to be added to the reference name if (reference.SourceProject.Kind.Equals(Constants.VcxProjGuid, StringComparison.OrdinalIgnoreCase)) { name = name + ".Object"; } } else { if (reference.Path != null) { if (Path.GetExtension(reference.Path).Equals(Constants.Lib, StringComparison.OrdinalIgnoreCase)) { // Full file path is required for libs (TODO: need to confirm) return(reference.Path); } name = Path.GetFileName(reference.Path); } else { name = reference.Name; var prjType = (prjOutputType)reference.SourceProject.Properties.Item("OutputType").Value; switch (prjType) { case prjOutputType.prjOutputTypeExe: name += ".exe"; break; case prjOutputType.prjOutputTypeLibrary: case prjOutputType.prjOutputTypeWinExe: name += ".dll"; break; default: break; } } } return("{" + name + "}"); }
/// <summary> /// Gets invoked when a reference is added /// </summary> /// <param name="reference">Reference that is added</param> internal static void ReferenceAdded(Reference reference) { try { string specFile, value; // If the specification file does not exist, ignore if (!TryGetSpecFile(reference, out specFile, out value)) { return; } // If failed to infer the name of the reference string name = GetReferenceName(reference); if (name == null) { SpecUtilities.ShowMessage(string.Format(CultureInfo.InvariantCulture, "Failed to infer the name of the reference: {0}", reference.Name)); return; } var projectKind = reference.ContainingProject.Kind; if (projectKind.Equals(Constants.CsProjGuid, StringComparison.OrdinalIgnoreCase)) { SpecUtilities.AddCSharpReferenceElement(specFile, value, name); return; } if (projectKind.Equals(Constants.VcxProjGuid, StringComparison.OrdinalIgnoreCase)) { SpecUtilities.AddCppReferenceElement(specFile, value, name); return; } SpecUtilities.ShowMessage(string.Format(CultureInfo.InvariantCulture, "Unknown project type: {0}", reference.ContainingProject.Name)); } catch (BuildXLVsException de) { SpecUtilities.ShowException(de.Message, de.StackTrace); } catch (Exception ex) { // Log exception and rethrow it #pragma warning disable EPC12 // Suspicious exception handling: only Message property is observed in exception block. SpecUtilities.ShowException(ex.Message, ex.StackTrace); #pragma warning restore EPC12 // Suspicious exception handling: only Message property is observed in exception block. throw; } }
/// <summary> /// Returns specification file and relative path of the item /// </summary> /// <param name="item">The project item</param> /// <param name="specFile">The specification file</param> /// <param name="value">The name of the value corresponding to this project</param> /// <param name="relativePath">The relative path of the project item</param> /// <returns>Returns the status</returns> private static bool TryGetSpecFileAndSrcRelativePath(ProjectItem item, out string specFile, out string value, out string relativePath) { if (!SpecUtilities.TryGetSpecFileFromProject(item.ContainingProject.FileName, out specFile, out value)) { Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "BuildXL specification file not found")); relativePath = null; return(false); } // Get the relative path of the item var tempSpecFile = specFile; var specFileDir = HandleRecoverableIOException( () => Path.GetDirectoryName(tempSpecFile), ex => { throw new BuildXLVsException(string.Format(CultureInfo.InvariantCulture, "Directory name cannot be retrieved from {0}: {1}", tempSpecFile, ex.Message)); }); relativePath = RelativePath(item.FileNames[0], specFileDir); return(true); }
/// <summary> /// Handles removal of items /// </summary> /// <param name="item">Item that is removed</param> /// <returns>Status of the update</returns> private int ProjectItemRemoved(ProjectItem item) { if (!SpecUtilities.IsAValidProjectItem(item)) { return(VSConstants.S_OK); } try { string specFile, value, relativePath; if (!TryGetSpecFileAndSrcRelativePath(item, out specFile, out value, out relativePath)) { return(VSConstants.S_OK); } // Check if its a folder if (string.Equals(SpecUtilities.PhysicalFolderKind, item.Kind, StringComparison.OrdinalIgnoreCase)) { RemoveProjectDirectory(item); return(VSConstants.S_OK); } // Removing element to the specification file if its csharp file string extension = Path.GetExtension(relativePath); Contract.Assume(extension != null); // TODO: check about BuildXL spec file if (extension.Equals(Constants.CSharp, StringComparison.OrdinalIgnoreCase) || extension.Equals(Constants.CPP, StringComparison.OrdinalIgnoreCase) || extension.Equals(Constants.DominoSpec, StringComparison.OrdinalIgnoreCase)) { SpecUtilities.RemoveSourceElement(specFile, value, relativePath); } // Removing config file if (extension.Equals(Constants.Config, StringComparison.OrdinalIgnoreCase)) { SpecUtilities.RemoveAppConfig(specFile, value, relativePath); return(VSConstants.S_OK); } // Removing resource file if (extension.Equals(Constants.Resource, StringComparison.OrdinalIgnoreCase)) { SpecUtilities.RemoveEmbeddedResource(specFile, value, relativePath); return(VSConstants.S_OK); } // Removing resource file with linked contents if (extension.Equals(Constants.Png, StringComparison.OrdinalIgnoreCase) || extension.Equals(Constants.Js, StringComparison.OrdinalIgnoreCase) || extension.Equals(Constants.Html, StringComparison.OrdinalIgnoreCase) || extension.Equals(Constants.Htm, StringComparison.OrdinalIgnoreCase) || extension.Equals(Constants.Css, StringComparison.OrdinalIgnoreCase) || extension.Equals(Constants.Ico, StringComparison.OrdinalIgnoreCase)) { SpecUtilities.RemoveEmbeddedResourceLinkedContent(specFile, value, relativePath); return(VSConstants.S_OK); } } catch (BuildXLVsException de) { SpecUtilities.ShowException(de.Message, de.StackTrace); } catch (Exception ex) { // Log exception and rethrow it #pragma warning disable EPC12 // Suspicious exception handling: only Message property is observed in exception block. SpecUtilities.ShowException(ex.Message, ex.StackTrace); #pragma warning restore EPC12 // Suspicious exception handling: only Message property is observed in exception block. throw; } return(VSConstants.S_OK); }
/// <summary> /// Gets specification file from reference /// </summary> /// <param name="reference">The reference object</param> /// <param name="specFile">Full path of the specification file</param> /// <param name="value">The name of the value in the specification file</param> /// <returns>true if successful</returns> private static bool TryGetSpecFile(Reference reference, out string specFile, out string value) { return(SpecUtilities.TryGetSpecFileFromProject(reference.ContainingProject.FileName, out specFile, out value)); }