IsSamePath() публичный статический Метод

public static IsSamePath ( string file1, string file2 ) : bool
file1 string
file2 string
Результат bool
Пример #1
0
        /// <summary>
        /// Checks if a reference is already added. The method parses all references and compares the Url.
        /// </summary>
        /// <param name="existingEquivalentNode">The existing reference, if one is found.</param>
        /// <returns>true if the assembly has already been added.</returns>
        protected internal virtual bool IsAlreadyAdded(out ReferenceNode existingEquivalentNode)
        {
            ReferenceContainerNode referencesFolder = this.ProjectMgr.FindChild(ReferenceContainerNode.ReferencesNodeVirtualName) as ReferenceContainerNode;

            Debug.Assert(referencesFolder != null, "Could not find the References node");

            for (HierarchyNode n = referencesFolder.FirstChild; n != null; n = n.NextSibling)
            {
                ReferenceNode referenceNode = n as ReferenceNode;
                if (null != referenceNode)
                {
                    // We check if the Url of the assemblies is the same.
                    if (NativeMethods.IsSamePath(referenceNode.Url, this.Url))
                    {
                        existingEquivalentNode = referenceNode;
                        return(true);
                    }
                }
            }

            existingEquivalentNode = null;
            return(false);
        }
Пример #2
0
        /// <summary>
        /// Checks if an assembly is already added. The method parses all references and compares the full assemblynames, or the location of the assemblies to decide whether two assemblies are the same.
        /// </summary>
        /// <returns>true if the assembly has already been added.</returns>
        protected override bool IsAlreadyAdded()
        {
            ReferenceContainerNode referencesFolder = this.ProjectMgr.FindChild(ReferenceContainerNode.ReferencesNodeVirtualName) as ReferenceContainerNode;

            Debug.Assert(referencesFolder != null, "Could not find the References node");
            bool shouldCheckPath = !string.IsNullOrEmpty(this.Url);

            for (HierarchyNode n = referencesFolder.FirstChild; n != null; n = n.NextSibling)
            {
                AssemblyReferenceNode assemblyRefererenceNode = n as AssemblyReferenceNode;
                if (null != assemblyRefererenceNode)
                {
                    // We will check if the full assemblynames are the same or if the Url of the assemblies is the same.
                    if (String.Compare(assemblyRefererenceNode.AssemblyName.FullName, this.assemblyName.FullName, StringComparison.OrdinalIgnoreCase) == 0 ||
                        (shouldCheckPath && NativeMethods.IsSamePath(assemblyRefererenceNode.Url, this.Url)))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Пример #3
0
        /// <summary>
        /// Event callback. Called when one of the nested project files is changed.
        /// </summary>
        /// <param name="sender">The FileChangeManager object.</param>
        /// <param name="e">Event args containing the file name that was updated.</param>
        private void OnNestedProjectFileChangedOnDisk(object sender, FileChangedOnDiskEventArgs e)
        {
            #region Pre-condition validation
            Debug.Assert(e != null, "No event args specified for the FileChangedOnDisk event");

            // We care only about time change for reload.
            if ((e.FileChangeFlag & _VSFILECHANGEFLAGS.VSFILECHG_Time) == 0)
            {
                return;
            }

            // test if we actually have a document for this id.
            string moniker;
            this.GetMkDocument(e.ItemID, out moniker);
            Debug.Assert(NativeMethods.IsSamePath(moniker, e.FileName), " The file + " + e.FileName + " has changed but we could not retrieve the path for the item id associated to the path.");
            #endregion

            bool reload = true;
            if (!Utilities.IsInAutomationFunction(this.Site))
            {
                // Prompt to reload the nested project file. We use the moniker here since the filename from the event arg is canonicalized.
                string          message       = String.Format(CultureInfo.CurrentCulture, SR.GetString(SR.QueryReloadNestedProject, CultureInfo.CurrentUICulture), moniker);
                string          title         = string.Empty;
                OLEMSGICON      icon          = OLEMSGICON.OLEMSGICON_INFO;
                OLEMSGBUTTON    buttons       = OLEMSGBUTTON.OLEMSGBUTTON_YESNO;
                OLEMSGDEFBUTTON defaultButton = OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST;
                reload = (VsShellUtilities.ShowMessageBox(this.Site, message, title, icon, buttons, defaultButton) == NativeMethods.IDYES);
            }

            if (reload)
            {
                // We have to use here the interface method call, since it might be that specialized project nodes like the project container item
                // is owerwriting the default functionality.
                this.ReloadItem(e.ItemID, 0);
            }
        }
        private static ProjectReferenceNode GetProjectReferenceOnNodeForHierarchy(IList <ReferenceNode> references, IVsHierarchy inputHierarchy)
        {
            if (references == null)
            {
                return(null);
            }
            ThreadHelper.ThrowIfNotOnUIThread();

            Guid projectGuid;

            inputHierarchy.GetGuidProperty(VSConstants.VSITEMID_ROOT, (int)__VSHPROPID.VSHPROPID_ProjectIDGuid, out projectGuid);

            string canonicalName;

            ThreadHelper.ThrowIfNotOnUIThread();
            inputHierarchy.GetCanonicalName(VSConstants.VSITEMID_ROOT, out canonicalName);
            foreach (ReferenceNode refNode in references)
            {
                ProjectReferenceNode projRefNode = refNode as ProjectReferenceNode;
                if (projRefNode != null)
                {
                    if (projRefNode.ReferencedProjectGuid == projectGuid)
                    {
                        return(projRefNode);
                    }

                    // Try with canonical names, if the project that is removed is an unloaded project than the above criteria will not pass.
                    if (!String.IsNullOrEmpty(projRefNode.Url) && NativeMethods.IsSamePath(projRefNode.Url, canonicalName))
                    {
                        return(projRefNode);
                    }
                }
            }

            return(null);
        }
Пример #5
0
        /// <summary>
        /// Loads a project file for the file. If the build project exists and it was loaded with a different file then it is unloaded first.
        /// </summary>
        /// <param name="engine">The build engine to use to create a build project.</param>
        /// <param name="fullProjectPath">The full path of the project.</param>
        /// <param name="exitingBuildProject">An Existing build project that will be reloaded.</param>
        /// <returns>A loaded msbuild project.</returns>
        internal static MSBuild.Project ReinitializeMsBuildProject(MSBuild.ProjectCollection buildEngine, string fullProjectPath, MSBuild.Project exitingBuildProject)
        {
            // If we have a build project that has been loaded with another file unload it.
            try
            {
                if (exitingBuildProject != null && exitingBuildProject.ProjectCollection != null && !NativeMethods.IsSamePath(exitingBuildProject.FullPath, fullProjectPath))
                {
                    buildEngine.UnloadProject(exitingBuildProject);
                }
            }
            // We  catch Invalid operation exception because if the project was unloaded while we touch the ParentEngine the msbuild API throws.
            // Is there a way to figure out that a project was unloaded?
            catch (InvalidOperationException)
            {
            }

            return(Utilities.InitializeMsBuildProject(buildEngine, fullProjectPath));
        }
Пример #6
0
        private EnvDTE.Project FindProjectByPath(IEnumerable <EnvDTE.Project> projects)
        {
            foreach (EnvDTE.Project prj in projects)
            {
                //Skip this project if it is an umodeled project (unloaded)
                if (string.Compare(EnvDTE.Constants.vsProjectKindUnmodeled, prj.Kind, StringComparison.OrdinalIgnoreCase) == 0)
                {
                    continue;
                }

                //SolutionFolder

                if (string.Compare(EnvDTE.Constants.vsProjectKindSolutionItems, prj.Kind, StringComparison.OrdinalIgnoreCase) == 0)
                {
                    var subProjects = new List <EnvDTE.Project>();

                    foreach (EnvDTE.ProjectItem item in prj.ProjectItems)
                    {
                        try
                        {
                            EnvDTE.Project subProject = item.SubProject as EnvDTE.Project;

                            if (subProject != null)
                            {
                                subProjects.Add(subProject);
                            }
                        }
                        catch { }
                    }

                    if (subProjects.Count > 0)
                    {
                        var result = FindProjectByPath(subProjects);

                        if (result != null)
                        {
                            return(result);
                        }
                    }
                }

                // Get the full path of the current project.
                EnvDTE.Property pathProperty = GetProperty(prj, "FullPath");

                if (pathProperty == null)
                {
                    var fullName = prj.FullName;

                    if (NativeMethods.IsSamePath(fullName, referencedProjectFullPath))
                    {
                        return(prj);
                    }

                    // The full path should alway be availabe, but if this is not the
                    // case then we have to skip it.
                    continue;
                }

                string prjPath = pathProperty.Value.ToString();


                // Get the name of the project file.
                EnvDTE.Property fileNameProperty = GetProperty(prj, "FileName");

                if (fileNameProperty == null)
                {
                    // Again, this should never be the case, but we handle it anyway.
                    continue;
                }

                prjPath = System.IO.Path.Combine(prjPath, fileNameProperty.Value.ToString());

                // If the full path of this project is the same as the one of this
                // reference, then we have found the right project.
                if (NativeMethods.IsSamePath(prjPath, referencedProjectFullPath))
                {
                    return(prj);
                }
            }

            return(null);
        }
Пример #7
0
        /// <summary>
        /// Get's called to rename the eventually running document this hierarchyitem points to
        /// </summary>
        /// returns FALSE if the doc can not be renamed
        internal bool RenameDocument(string oldName, string newName)
        {
            IVsRunningDocumentTable pRDT = this.GetService(typeof(IVsRunningDocumentTable)) as IVsRunningDocumentTable;

            if (pRDT == null)
            {
                return(false);
            }
            IntPtr       docData = IntPtr.Zero;
            IVsHierarchy pIVsHierarchy;
            uint         itemId;
            uint         uiVsDocCookie;

            SuspendFileChanges sfc = new SuspendFileChanges(this.ProjectMgr.Site, oldName);

            sfc.Suspend();

            try
            {
                // Suspend ms build since during a rename operation no msbuild re-evaluation should be performed until we have finished.
                // Scenario that could fail if we do not suspend.
                // We have a project system relying on MPF that triggers a Compile target build (re-evaluates itself) whenever the project changes. (example: a file is added, property changed.)
                // 1. User renames a file in  the above project sytem relying on MPF
                // 2. Our rename funstionality implemented in this method removes and readds the file and as a post step copies all msbuild entries from the removed file to the added file.
                // 3. The project system mentioned will trigger an msbuild re-evaluate with the new item, because it was listening to OnItemAdded.
                //    The problem is that the item at the "add" time is only partly added to the project, since the msbuild part has not yet been copied over as mentioned in part 2 of the last step of the rename process.
                //    The result is that the project re-evaluates itself wrongly.
                VSRENAMEFILEFLAGS renameflag = VSRENAMEFILEFLAGS.VSRENAMEFILEFLAGS_NoFlags;
                try
                {
                    this.ProjectMgr.SuspendMSBuild();
                    ErrorHandler.ThrowOnFailure(pRDT.FindAndLockDocument((uint)_VSRDTFLAGS.RDT_NoLock, oldName, out pIVsHierarchy, out itemId, out docData, out uiVsDocCookie));

                    if (pIVsHierarchy != null && !Utilities.IsSameComObject(pIVsHierarchy, this.ProjectMgr))
                    {
                        // Don't rename it if it wasn't opened by us.
                        return(false);
                    }

                    // ask other potentially running packages
                    if (!this.ProjectMgr.Tracker.CanRenameItem(oldName, newName, renameflag))
                    {
                        return(false);
                    }
                    // Allow the user to "fix" the project by renaming the item in the hierarchy
                    // to the real name of the file on disk.
                    if (IsFileOnDisk(oldName) || !IsFileOnDisk(newName))
                    {
                        RenameInStorage(oldName, newName);
                    }

                    string newFileName = Path.GetFileName(newName);
                    DocumentManager.UpdateCaption(this.ProjectMgr.Site, newFileName, docData);
                    bool caseOnlyChange = NativeMethods.IsSamePath(oldName, newName);
                    if (!caseOnlyChange)
                    {
                        // Check out the project file if necessary.
                        if (!this.ProjectMgr.QueryEditProjectFile(false))
                        {
                            throw Marshal.GetExceptionForHR(VSConstants.OLE_E_PROMPTSAVECANCELLED);
                        }

                        this.RenameFileNode(oldName, newName);
                    }
                    else
                    {
                        this.RenameCaseOnlyChange(newFileName);
                    }
                }
                finally
                {
                    this.ProjectMgr.ResumeMSBuild(this.ProjectMgr.ReEvaluateProjectFileTargetName);
                }

                this.ProjectMgr.Tracker.OnItemRenamed(oldName, newName, renameflag);
            }
            finally
            {
                sfc.Resume();
                if (docData != IntPtr.Zero)
                {
                    Marshal.Release(docData);
                }
            }

            return(true);
        }
Пример #8
0
        /// <summary>
        /// Performs a SaveAs operation of an open document. Called from SaveItem after the running document table has been updated with the new doc data.
        /// </summary>
        /// <param name="docData">A pointer to the document in the rdt</param>
        /// <param name="newFilePath">The new file path to the document</param>
        /// <returns></returns>
        protected override int AfterSaveItemAs(IntPtr docData, string newFilePath)
        {
            if (String.IsNullOrEmpty(newFilePath))
            {
                throw new ArgumentException(SR.GetString(SR.ParameterCannotBeNullOrEmpty, CultureInfo.CurrentUICulture), "newFilePath");
            }

            int returnCode = VSConstants.S_OK;

            newFilePath = newFilePath.Trim();

            //Identify if Path or FileName are the same for old and new file
            string newDirectoryName          = Path.GetDirectoryName(newFilePath);
            Uri    newDirectoryUri           = new Uri(newDirectoryName);
            string newCanonicalDirectoryName = newDirectoryUri.LocalPath;

            newCanonicalDirectoryName = newCanonicalDirectoryName.TrimEnd(Path.DirectorySeparatorChar);
            string oldCanonicalDirectoryName = new Uri(Path.GetDirectoryName(this.GetMkDocument())).LocalPath;

            oldCanonicalDirectoryName = oldCanonicalDirectoryName.TrimEnd(Path.DirectorySeparatorChar);
            string errorMessage = String.Empty;
            bool   isSamePath   = NativeMethods.IsSamePath(newCanonicalDirectoryName, oldCanonicalDirectoryName);
            bool   isSameFile   = NativeMethods.IsSamePath(newFilePath, this.Url);

            // Currently we do not support if the new directory is located outside the project cone
            string projectCannonicalDirecoryName = new Uri(this.ProjectMgr.ProjectFolder).LocalPath;

            projectCannonicalDirecoryName = projectCannonicalDirecoryName.TrimEnd(Path.DirectorySeparatorChar);
            if (!isSamePath && newCanonicalDirectoryName.IndexOf(projectCannonicalDirecoryName, StringComparison.OrdinalIgnoreCase) == -1)
            {
                errorMessage = String.Format(CultureInfo.CurrentCulture, SR.GetString(SR.LinkedItemsAreNotSupported, CultureInfo.CurrentUICulture), Path.GetFileNameWithoutExtension(newFilePath));
                throw new InvalidOperationException(errorMessage);
            }

            //Get target container
            HierarchyNode targetContainer = null;

            if (isSamePath)
            {
                targetContainer = this.Parent;
            }
            else if (NativeMethods.IsSamePath(newCanonicalDirectoryName, projectCannonicalDirecoryName))
            {
                //the projectnode is the target container
                targetContainer = this.ProjectMgr;
            }
            else
            {
                //search for the target container among existing child nodes
                targetContainer = this.ProjectMgr.FindChild(newDirectoryName);
                if (targetContainer != null && (targetContainer is FileNode))
                {
                    // We already have a file node with this name in the hierarchy.
                    errorMessage = String.Format(CultureInfo.CurrentCulture, SR.GetString(SR.FileAlreadyExistsAndCannotBeRenamed, CultureInfo.CurrentUICulture), Path.GetFileNameWithoutExtension(newFilePath));
                    throw new InvalidOperationException(errorMessage);
                }
            }

            if (targetContainer == null)
            {
                // Add a chain of subdirectories to the project.
                string relativeUri = PackageUtilities.GetPathDistance(this.ProjectMgr.BaseURI.Uri, newDirectoryUri);
                Debug.Assert(!String.IsNullOrEmpty(relativeUri) && relativeUri != newDirectoryUri.LocalPath, "Could not make pat distance of " + this.ProjectMgr.BaseURI.Uri.LocalPath + " and " + newDirectoryUri);
                targetContainer = this.ProjectMgr.CreateFolderNodes(relativeUri);
            }
            Debug.Assert(targetContainer != null, "We should have found a target node by now");

            //Suspend file changes while we rename the document
            string             oldrelPath = this.ItemNode.GetMetadata(ProjectFileConstants.Include);
            string             oldName    = Path.Combine(this.ProjectMgr.ProjectFolder, oldrelPath);
            SuspendFileChanges sfc        = new SuspendFileChanges(this.ProjectMgr.Site, oldName);

            sfc.Suspend();

            try
            {
                // Rename the node.
                DocumentManager.UpdateCaption(this.ProjectMgr.Site, Path.GetFileName(newFilePath), docData);
                // Check if the file name was actually changed.
                // In same cases (e.g. if the item is a file and the user has changed its encoding) this function
                // is called even if there is no real rename.
                if (!isSameFile || (this.Parent.ID != targetContainer.ID))
                {
                    // The path of the file is changed or its parent is changed; in both cases we have
                    // to rename the item.
                    this.RenameFileNode(oldName, newFilePath, targetContainer.ID);
                    OnInvalidateItems(this.Parent);
                }
            }
            catch (Exception e)
            {
                Trace.WriteLine("Exception : " + e.Message);
                this.RecoverFromRenameFailure(newFilePath, oldrelPath);
                throw;
            }
            finally
            {
                sfc.Resume();
            }

            return(returnCode);
        }
Пример #9
0
        /// <summary>
        /// Rename the underlying document based on the change the user just made to the edit label.
        /// </summary>
        protected internal override int SetEditLabel(string label, string relativePath)
        {
            int    returnValue = VSConstants.S_OK;
            uint   oldId       = this.ID;
            string strSavePath = Path.GetDirectoryName(relativePath);

            if (!Path.IsPathRooted(relativePath))
            {
                strSavePath = Path.Combine(Path.GetDirectoryName(this.ProjectMgr.BaseURI.Uri.LocalPath), strSavePath);
            }

            string newName = Path.Combine(strSavePath, label);

            if (NativeMethods.IsSamePath(newName, this.Url))
            {
                // If this is really a no-op, then nothing to do
                if (String.Compare(newName, this.Url, StringComparison.Ordinal) == 0)
                {
                    return(VSConstants.S_FALSE);
                }
            }
            else
            {
                // If the renamed file already exists then quit (unless it is the result of the parent having done the move).
                if (IsFileOnDisk(newName) &&
                    (IsFileOnDisk(this.Url) ||
                     String.Compare(Path.GetFileName(newName), Path.GetFileName(this.Url), StringComparison.Ordinal) != 0))
                {
                    throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, SR.GetString(SR.FileCannotBeRenamedToAnExistingFile, CultureInfo.CurrentUICulture), label));
                }
                else if (newName.Length > NativeMethods.MAX_PATH)
                {
                    throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, SR.GetString(SR.PathTooLong, CultureInfo.CurrentUICulture), label));
                }
            }

            string oldName = this.Url;
            // must update the caption prior to calling RenameDocument, since it may
            // cause queries of that property (such as from open editors).
            string oldrelPath = this.ItemNode.GetMetadata(ProjectFileConstants.Include);

            try
            {
                if (!RenameDocument(oldName, newName))
                {
                    this.ItemNode.Rename(oldrelPath);
                    this.ItemNode.RefreshProperties();
                }

                if (this is DependentFileNode)
                {
                    OnInvalidateItems(this.Parent);
                }
            }
            catch (Exception e)
            {
                // Just re-throw the exception so we don't get duplicate message boxes.
                Trace.WriteLine("Exception : " + e.Message);
                this.RecoverFromRenameFailure(newName, oldrelPath);
                returnValue = Marshal.GetHRForException(e);
                throw;
            }
            // Return S_FALSE if the hierarchy item id has changed.  This forces VS to flush the stale
            // hierarchy item id.
            if (returnValue == (int)VSConstants.S_OK || returnValue == (int)VSConstants.S_FALSE || returnValue == VSConstants.OLE_E_PROMPTSAVECANCELLED)
            {
                return((oldId == this.ID) ? VSConstants.S_OK : (int)VSConstants.S_FALSE);
            }

            return(returnValue);
        }
Пример #10
0
        private EnvDTE.Project FindReferencedProject(System.Collections.IEnumerable projects)
        {
            EnvDTE.Project refProject = null;

            // Search for the project in the collection of the projects in the current solution.
            foreach (EnvDTE.Project prj in projects)
            {
                //Skip this project if it is an umodeled project (unloaded)
                if (string.Compare(EnvDTE.Constants.vsProjectKindUnmodeled, prj.Kind, StringComparison.OrdinalIgnoreCase) == 0)
                {
                    continue;
                }

                // Recursively iterate solution folder for the project.
                if (string.Compare(EnvDTE.Constants.vsProjectKindSolutionItems, prj.Kind, StringComparison.OrdinalIgnoreCase) == 0)
                {
                    var containedProjects = GetContainerProjects(prj);

                    refProject = FindReferencedProject(containedProjects);
                    if (refProject != null)
                    {
                        return(refProject);
                    }
                }

                // Get the full path of the current project.
                EnvDTE.Property pathProperty = null;
                try
                {
                    if (prj.Properties == null)
                    {
                        continue;
                    }

                    pathProperty = prj.Properties.Item("FullPath");
                    if (null == pathProperty)
                    {
                        // The full path should alway be availabe, but if this is not the
                        // case then we have to skip it.
                        continue;
                    }
                }
                catch (ArgumentException)
                {
                    continue;
                }
                string          prjPath          = pathProperty.Value.ToString();
                EnvDTE.Property fileNameProperty = null;
                // Get the name of the project file.
                try
                {
                    fileNameProperty = prj.Properties.Item("FileName");
                    if (null == fileNameProperty)
                    {
                        // Again, this should never be the case, but we handle it anyway.
                        continue;
                    }
                }
                catch (ArgumentException)
                {
                    continue;
                }
                prjPath = System.IO.Path.Combine(prjPath, fileNameProperty.Value.ToString());

                // If the full path of this project is the same as the one of this
                // reference, then we have found the right project.
                if (NativeMethods.IsSamePath(prjPath, referencedProjectFullPath))
                {
                    refProject = prj;
                    break;
                }
            }
            return(refProject);
        }