コード例 #1
0
        /// <summary>
        /// Attempts to find the document information for the specified file.
        /// </summary>
        /// <param name="absolutePath">The absolute path of the file to search for.</param>
        /// <returns>A <see cref="DocumentInfo"/> object if the file was found; otherwise, null.</returns>
        public DocumentInfo FindByPath(string absolutePath)
        {
            Tracer.VerifyStringArgument(absolutePath, "absolutePath");

            DocumentInfo documentInfo = null;

            // Make the call to IVsRunningDocumentTable.FindAndLockDocument to try to find the document.
            uint         lockType = unchecked ((uint)_VSRDTFLAGS.RDT_NoLock);
            IVsHierarchy vsHierarchy;
            uint         hierarchyId;
            IntPtr       punkDocData;
            uint         cookie;
            int          hr = this.Rdt.FindAndLockDocument(lockType, absolutePath, out vsHierarchy, out hierarchyId, out punkDocData, out cookie);

            NativeMethods.ThrowOnFailure(hr);

            if (punkDocData != IntPtr.Zero)
            {
                try
                {
                    object docData = Marshal.GetObjectForIUnknown(punkDocData);
                    Tracer.Assert(docData != null, "We should be getting something for punkDocData instead of null.");
                    if (docData != null)
                    {
                        documentInfo = new DocumentInfo(absolutePath, vsHierarchy, hierarchyId, docData, cookie);
                    }
                }
                finally
                {
                    Marshal.Release(punkDocData);
                }
            }

            return(documentInfo);
        }
コード例 #2
0
        /// <summary>
        /// Notifies all of the listeners that a configuration name has been changed.
        /// </summary>
        /// <param name="oldName">The old name of the configuration that was changed.</param>
        /// <param name="newName">The new name of the configuration that was changed.</param>
        public void OnCfgNameRenamed(string oldName, string newName)
        {
            Tracer.VerifyStringArgument(oldName, "oldName");
            Tracer.VerifyStringArgument(newName, "newName");

            // Let all of our listeners know that the hierarchy needs to be refreshed.
            Tracer.WriteLine(classType, "OnCfgNameRenamed", Tracer.Level.Information, "Notifying all of our listeners that the configuration '{0}' has been renamed to '{1}'.", oldName, newName);

            // There are some cases where the collection is changed while we're iterating it.
            // To be safe, we'll create a copy of the collection and iterate over that.
            // We just want a shallow copy, though, and not a deep (Clone) copy.
            ArrayList clone = new ArrayList(this.Values);

            foreach (IVsCfgProviderEvents eventItem in clone)
            {
                try
                {
                    eventItem.OnCfgNameRenamed(oldName, newName);
                }
                catch (Exception e)
                {
                    Tracer.WriteLine(classType, "OnCfgNameRenamed", Tracer.Level.Warning, "There was an exception in one of the listener's event handling code: {0}", e.ToString());
                }
            }
        }
コード例 #3
0
        //==========================================================================================
        // Methods
        //==========================================================================================

        /// <summary>
        /// Combines two registry paths.
        /// </summary>
        /// <param name="path1">The first path to combine.</param>
        /// <param name="path2">The second path to combine.</param>
        /// <returns>The concatenation of the first path with the second, delimeted with a '\'.</returns>
        protected string RegistryPathCombine(string path1, string path2)
        {
            Tracer.VerifyStringArgument(path1, "path1");
            Tracer.VerifyStringArgument(path2, "path2");

            return(PackageUtility.EnsureTrailingChar(path1, '\\') + path2);
        }
コード例 #4
0
        /// <summary>
        /// Generates a unique document name for a new node under the parent node.
        /// </summary>
        /// <param name="suggestedRoot">The suggested root to use for the unique name.</param>
        /// <param name="extension">The extension to use for the new file or folder (with or without the leading '.'). Can be null or empty.</param>
        /// <param name="isFolder">Indicates whether the new name is intended to be a file or a folder.</param>
        /// <returns>A unique document name for a new node under the this node.</returns>
        public string GenerateUniqueName(string suggestedRoot, string extension, bool isFolder)
        {
            Tracer.VerifyStringArgument(suggestedRoot, "suggestedRoot");

            int    suffixNumber = 0;
            bool   foundUnique  = false;
            string uniqueName   = String.Empty;

            // Canonicalize the extension by setting it either to "" or prepend it with a '.'
            extension = ((extension == null || extension.Length == 0) ? String.Empty : PackageUtility.EnsureLeadingChar(extension, '.'));

            // We have to make sure that this item doesn't already exist in the hierarchy and the file system.
            while (!foundUnique)
            {
                if (suffixNumber == 0)
                {
                    uniqueName = suggestedRoot + extension;
                }
                else
                {
                    uniqueName = suggestedRoot + suffixNumber + extension;
                }

                // Look in the hierarchy to see if there is an existing item with the proposed name.
                foundUnique = true;
                foreach (Node node in this.Children)
                {
                    if (PackageUtility.FileStringEquals(uniqueName, node.Caption))
                    {
                        foundUnique = false;
                        break;
                    }
                }

                // If the name is unique within the hierarchy, we still need to check the file system.
                if (foundUnique)
                {
                    string pathToCheck = Path.Combine(this.AbsoluteDirectory, uniqueName);
                    if (isFolder && Directory.Exists(pathToCheck))
                    {
                        foundUnique = false;
                    }
                    else if (!isFolder && File.Exists(pathToCheck))
                    {
                        foundUnique = false;
                    }
                    else
                    {
                        // Ok, we found a unique name.
                        break;
                    }
                }

                // Increment the number to append to the root part of the path.
                suffixNumber++;
            }

            Tracer.WriteLineInformation(classType, "GenerateUniqueName", "Found a unique name for a new node. New name = '{0}'.", uniqueName);
            return(uniqueName);
        }
コード例 #5
0
        //==========================================================================================
        // Constructors
        //==========================================================================================

        public ProjectConfiguration(Project project, string name)
        {
            Tracer.VerifyNonNullArgument(project, "project");
            Tracer.VerifyStringArgument(name, "name");
            this.project = project;
            this.name    = name;
        }
コード例 #6
0
 /// <summary>
 /// Adds the specified character to the end of the string if it doesn't already exist at the end.
 /// </summary>
 /// <param name="value">The string to add the trailing character to.</param>
 /// <param name="charToEnsure">The character that will be at the end of the string upon return.</param>
 /// <returns>The original string with the specified character at the end.</returns>
 public static string EnsureTrailingChar(string value, char charToEnsure)
 {
     Tracer.VerifyStringArgument(value, "value");
     if (value[value.Length - 1] != charToEnsure)
     {
         value += charToEnsure;
     }
     return(value);
 }
コード例 #7
0
		int IVsCfgProvider2.DeleteCfgsOfCfgName(string pszCfgName)
		{
			Tracer.VerifyStringArgument(pszCfgName, "pszCfgName");
			if (this.ProjectConfigurations.Contains(pszCfgName))
			{
				this.ProjectConfigurations.Remove(pszCfgName);
			}
			return NativeMethods.S_OK;
		}
コード例 #8
0
        public void Remove(string name)
        {
            Tracer.VerifyStringArgument(name, "name");
            int index = this.IndexOf(name);

            if (index >= 0)
            {
                this.RemoveAt(index);
            }
        }
コード例 #9
0
        //==========================================================================================
        // Methods
        //==========================================================================================

        /// <summary>
        /// Copies the attached project and all of its referenced files to the destination directory.
        /// </summary>
        /// <param name="destinationPath">The destination path where the project file will be copied to.</param>
        /// <returns>A copy of the attached project rooted at <paramref name="destinationDirectory"/> or null if there were errors.</returns>
        public Project CopyTo(string destinationPath)
        {
            Tracer.VerifyStringArgument(destinationPath, "destinationPath");

            bool successful;

            // Reference the attached project.
            Project sourceProject = this.Project;

            // Create the destination project and a new project serializer for it.
            ProjectSerializer destSerializer = (ProjectSerializer)this.MemberwiseClone();
            Project           destProject    = this.CreateProject(destSerializer);

            // We have to have a back pointer from the serializer to the project otherwise when we go to
            // save the destination project, we'll have a null project pointer.
            destSerializer.project = destProject;

            // Set the destination project's properties.
            destProject.ProjectGuid = sourceProject.ProjectGuid;
            destProject.FilePath    = destinationPath;
            string destDirectory = Path.GetDirectoryName(destProject.FilePath);

            // Create the destination directory if it doesn't already exist.
            if (!Directory.Exists(destDirectory))
            {
                Directory.CreateDirectory(destDirectory);
            }

            // Copy the build settings.
            destProject.BuildSettings = (BuildSettings)sourceProject.BuildSettings.Clone();

            // Copy all of the configurations.
            destProject.ConfigurationProvider = sourceProject.ConfigurationProvider.Clone(destProject);

            // Loop through the files, copying each file to the destination directory.
            // TODO: Change the relative path of linked files.
            successful = this.CopyNodeFiles(sourceProject.RootNode, destProject, destProject.RootNode);

            // Loop through the references, adding them to the project.
            if (successful)
            {
                foreach (ReferenceFileNode referenceFile in sourceProject.ReferencesNode.Children)
                {
                    destProject.AddReference(referenceFile.AbsolutePath, false);
                }
            }

            // Now save the destination project.
            if (successful)
            {
                successful = destProject.Serializer.Save();
            }

            return(successful ? destProject : null);
        }
コード例 #10
0
 public ProjectConfiguration this[string name]
 {
     get
     {
         Tracer.VerifyStringArgument(name, "name");
         int index = this.IndexOf(name);
         if (index >= 0)
         {
             return(this[index]);
         }
         return(null);
     }
 }
コード例 #11
0
        //==========================================================================================
        // Constructors
        //==========================================================================================

        /// <summary>
        /// Initializes a new instance of the <see cref="DocumentInfo"/> class.
        /// </summary>
        public DocumentInfo(string absolutePath, IVsHierarchy vsHierarchy, uint hierarchyId, object documentData, uint cookie)
        {
            Tracer.VerifyStringArgument(absolutePath, "absolutePath");
            Tracer.VerifyNonNullArgument(documentData, "documentData");

            this.absolutePath          = absolutePath;
            this.visualStudioHierarchy = vsHierarchy;
            this.hierarchyId           = hierarchyId;
            this.documentData          = documentData;
            this.cookie = cookie;

            // The document is open if it has a hierarchy and a cookie.
            this.isOpen = (vsHierarchy != null && cookie != NullCookie);
        }
コード例 #12
0
        /// <summary>
        /// Renames and/or changes the ownership of a document.
        /// </summary>
        /// <param name="oldFilePath">Absolute path to the previous document.</param>
        /// <param name="newFilePath">Absolute path to the current document.</param>
        /// <param name="newHierarchyId">The hierarchy identifier of the current document or 0 if no change.</param>
        public void RenameDocument(string oldFilePath, string newFilePath, uint newHierarchyId)
        {
            int hr;

            Tracer.VerifyStringArgument(oldFilePath, "oldFilePath");
            Tracer.VerifyStringArgument(newFilePath, "newFilePath");
            if (newHierarchyId == NativeMethods.VSITEMID_NIL)
            {
                throw new ArgumentException("Cannot specify VSITEMID_NIL for the new hierarchy id.", "newHierarchyId");
            }

            // See if the document needs to be renamed (if it's in the RDT).
            DocumentInfo docInfo = this.FindByPath(oldFilePath);

            if (docInfo == null)
            {
                return;
            }

            // Get an IUnknown pointer for the new hierarchy.
            IntPtr punkHierarchy = Marshal.GetIUnknownForObject(docInfo.VisualStudioHierarhcy);

            if (punkHierarchy != IntPtr.Zero)
            {
                try
                {
                    // Get an IVsHierarchy pointer. We have to do this two-step process of getting an IUnknown
                    // and then querying for an IVsHierarchy because in the nested hierarchy case we could get
                    // different pointers.
                    IntPtr pvsHierarchy    = IntPtr.Zero;
                    Guid   vsHierarchyGuid = typeof(IVsHierarchy).GUID;
                    NativeMethods.ThrowOnFailure(Marshal.QueryInterface(punkHierarchy, ref vsHierarchyGuid, out pvsHierarchy));

                    try
                    {
                        hr = this.Rdt.RenameDocument(oldFilePath, newFilePath, pvsHierarchy, newHierarchyId);
                        NativeMethods.ThrowOnFailure(hr);
                    }
                    finally
                    {
                        Marshal.Release(pvsHierarchy);
                    }
                }
                finally
                {
                    Marshal.Release(punkHierarchy);
                }
            }
        }
コード例 #13
0
        /// <summary>
        /// Loads a project template file, serializing it into the specified project at the specified destination.
        /// </summary>
        /// <param name="templatePath">The absolute path of the template project file to load.</param>
        /// <param name="destinationPath">The absolute path to the new project file.</param>
        /// <returns>true if the project file was loaded correctly; otherwise, false.</returns>
        public bool LoadFromTemplate(string templatePath, string destinationPath)
        {
            Tracer.VerifyStringArgument(templatePath, "templatePath");
            Tracer.VerifyStringArgument(destinationPath, "destinationPath");

            bool successful = false;

            // Load the template project.
            if (this.Load(templatePath))
            {
                // Copy the loaded template to the real location of the new project.
                this.project = this.CopyTo(destinationPath);
                successful   = (this.project != null);
            }

            return(successful);
        }
コード例 #14
0
		int IVsCfgProvider2.AddCfgsOfCfgName(string pszCfgName, string pszCloneCfgName, int fPrivate)
		{
			Tracer.VerifyStringArgument(pszCfgName, "pszCfgName");

			// If we need to clone, then get the configurtaions to clone.
			if (pszCloneCfgName != null && pszCloneCfgName.Length > 0 && this.ProjectConfigurations.Contains(pszCloneCfgName))
			{
				ProjectConfiguration source = this.ProjectConfigurations[pszCloneCfgName];
				ProjectConfiguration clonedConfig = source.Clone(pszCfgName);
				this.ProjectConfigurations.Add(clonedConfig);
			}
			else
			{
				// Create a new configuration, since there was nothing to clone.
				ProjectConfiguration newConfig = new ProjectConfiguration(this.Project, pszCfgName);
				this.ProjectConfigurations.Add(newConfig);
			}

			return NativeMethods.S_OK;
		}
コード例 #15
0
 /// <summary>
 /// Gets a localized string like "The package requires that service '{0}' be installed.  Ensure that this service is available by repairing your Visual Studio installation."
 /// </summary>
 /// <param name="serviceName"></param>
 /// <returns></returns>
 public static string ErrorMissingService(string serviceName)
 {
     Tracer.VerifyStringArgument(serviceName, "serviceName");
     return(GetString(StringId.ErrorMissingService, serviceName));
 }
コード例 #16
0
        //==========================================================================================
        // Constructors
        //==========================================================================================

        /// <summary>
        /// Initializes a new instance of the <see cref="PropertyPage"/> class.
        /// </summary>
        /// <param name="name">The localized name of the property page.</param>
        protected PropertyPage(string name)
        {
            Tracer.VerifyStringArgument(name, "name");
            this.name = name;
        }
コード例 #17
0
        //==========================================================================================
        // Constructors / Finalizer
        //==========================================================================================

        /// <summary>
        /// Initializes a new instance of the <see cref="FileChangeNotificationSuspender"/> class.
        /// </summary>
        /// <param name="filePath">The absolute path of the file to suspend notifications about.</param>
        public FileChangeNotificationSuspender(string filePath)
        {
            Tracer.VerifyStringArgument(filePath, "filePath");
            this.filePath = filePath;
            this.Suspend();
        }
コード例 #18
0
        int IVsProjectFactory.CreateProject(string pszFilename, string pszLocation, string pszName, uint grfCreateFlags, ref Guid iidProject, out IntPtr ppvProject, out int pfCanceled)
        {
            IntPtr pUnk = IntPtr.Zero;

            pfCanceled = 0;
            ppvProject = IntPtr.Zero;

            bool loadedSuccessfully = false;

            try
            {
                Tracer.VerifyStringArgument(pszFilename, "pszFilename");

                __VSCREATEPROJFLAGS createFlags = (__VSCREATEPROJFLAGS)grfCreateFlags;

                // Get the right version of the project serializer.
                ProjectSerializer serializer = this.CreateSerializer(pszFilename);

                // Do we need to suppress any load failures from being reported to the end user.
                serializer.SilentFailures = ((createFlags & __VSCREATEPROJFLAGS.CPF_SILENT) == __VSCREATEPROJFLAGS.CPF_SILENT);

                // Now we need to load the project, either from a template file or from an existing file.
                bool openExisting     = ((createFlags & __VSCREATEPROJFLAGS.CPF_OPENFILE) == __VSCREATEPROJFLAGS.CPF_OPENFILE);
                bool openFromTemplate = ((createFlags & __VSCREATEPROJFLAGS.CPF_CLONEFILE) == __VSCREATEPROJFLAGS.CPF_CLONEFILE);
                Tracer.Assert((openExisting && !openFromTemplate) || (!openExisting && openFromTemplate), "The grfCreateFlags are incorrect. You can't have both opening existing and opening from template. Flags={0}", createFlags);

                if (openExisting)
                {
                    Tracer.WriteLineInformation(classType, "IVsProjectFactory.CreateProject", "Attempting to load project: File name={0} Location={1} Name={2} GUID={3}.", pszFilename, pszLocation, pszName, iidProject.ToString("B").ToUpper(CultureInfo.InvariantCulture));
                    loadedSuccessfully = serializer.Load(pszFilename);

                    if (loadedSuccessfully)
                    {
                        Tracer.WriteLineInformation(classType, "IVsProjectFactory.CreateProject", "Successfully loaded project '{0}'.", pszFilename);
                    }
                    else
                    {
                        Tracer.WriteLineInformation(classType, "IVsProjectFactory.CreateProject", "There were errors in loading project '{0}'.", pszFilename);
                    }
                }
                else
                {
                    Tracer.WriteLineInformation(classType, "IVsProjectFactory.CreateProject", "Attempting to create a new project from a template: File name={0} Location={1} Name={2} GUID={3}.", pszFilename, pszLocation, pszName, iidProject.ToString("B").ToUpper(CultureInfo.InvariantCulture));
                    Tracer.VerifyStringArgument(pszLocation, "pszLocation");
                    Tracer.VerifyStringArgument(pszName, "pszName");

                    string destinationFile = Path.Combine(pszLocation, pszName);
                    loadedSuccessfully = serializer.LoadFromTemplate(pszFilename, destinationFile);

                    if (loadedSuccessfully)
                    {
                        Tracer.WriteLineInformation(classType, "IVsProjectFactory.CreateProject", "Successfully loaded project '{0}'.", pszFilename);
                    }
                    else
                    {
                        Tracer.WriteLineInformation(classType, "IVsProjectFactory.CreateProject", "There were errors in loading project '{0}'.", pszFilename);
                    }
                }

                if (loadedSuccessfully)
                {
                    // Once we've loaded the project, we need to return the COM object that the environment is requesting.
                    pUnk = Marshal.GetIUnknownForObject(serializer.Project);
                    int hr = Marshal.QueryInterface(pUnk, ref iidProject, out ppvProject);
                    Tracer.Assert(NativeMethods.Succeeded(hr), "Cannot get the requested project interface ({0}): returned {1}", iidProject.ToString("B").ToUpper(CultureInfo.InvariantCulture), hr);
                    NativeMethods.ThrowOnFailure(hr);
                }
            }
            catch (Exception e)
            {
                Package.Instance.Context.NotifyInternalError(e.ToString());
            }
            finally
            {
                if (pUnk != IntPtr.Zero)
                {
                    Marshal.Release(pUnk);
                }
            }

            return(loadedSuccessfully ? NativeMethods.S_OK : NativeMethods.E_FAIL);
        }
コード例 #19
0
 /// <summary>
 /// Gets a localized string like "{0} (unavailable)".
 /// </summary>
 /// <param name="caption">The caption of the unavailable node.</param>
 /// <returns>A localized string like "{0} (unavailable)".</returns>
 public static string UnavailableCaption(string caption)
 {
     Tracer.VerifyStringArgument(caption, "caption");
     return(GetString(StringId.UnavailableCaption, caption));
 }
コード例 #20
0
 /// <summary>
 /// Gets a localized string like "The file '{0}' does not exist."
 /// </summary>
 /// <param name="fileName">The file name that doesn't exist.</param>
 /// <returns>A localized string like "The file '{0}' does not exist."</returns>
 public static string FileDoesNotExist(string fileName)
 {
     Tracer.VerifyStringArgument(fileName, "fileName");
     return(GetString(StringId.FileDoesNotExist, fileName));
 }
コード例 #21
0
        /// <summary>
        /// Loads a project file from disk.
        /// </summary>
        /// <param name="filePath">The absolute path of the project file to load.</param>
        /// <returns>true if the project file was loaded correctly; otherwise, false.</returns>
        public bool Load(string filePath)
        {
            Tracer.VerifyStringArgument(filePath, "filePath");

            // Create a new project.
            this.project = this.CreateProject(this);

            // Set the project's file path to the one being loaded in. Do this first in case we have
            // to make the project unavailable it can still display the correct caption in Solution Explorer.
            this.Project.FilePath = filePath;

            // Make sure the file exists.
            if (!File.Exists(filePath))
            {
                if (!this.SilentFailures)
                {
                    string message = SconceStrings.FileDoesNotExist(filePath);
                    Package.Instance.Context.ShowErrorMessageBox(message);
                }
                this.Project.Unavailable = true;
                Tracer.WriteLine(classType, "Load", Tracer.Level.Warning, "The project file '{0}' does not exist.", filePath);
                return(false);
            }

            try
            {
                using (StreamReader stream = new StreamReader(filePath))
                {
                    XmlTextReader reader = new XmlTextReader(stream);
                    reader.WhitespaceHandling = WhitespaceHandling.None;
                    XmlDocument xmlDoc = new XmlDocument();
                    xmlDoc.Load(reader);
                    XmlNode node = xmlDoc.DocumentElement;

                    // <VisualStudioProject>
                    if (!this.VerifyNode(node, ElementNames.VisualStudioProject))
                    {
                        this.Project.Unavailable = true;
                        return(false);
                    }
                    node = node.FirstChild;

                    if (!this.ReadProjectNode(node))
                    {
                        this.Project.Unavailable = true;
                        return(false);
                    }
                }
            }
            catch (XmlException e)
            {
                if (!this.SilentFailures)
                {
                    string projectFileName = Path.GetFileName(filePath);
                    string title           = Package.Instance.Context.NativeResources.GetString(ResId.IDS_E_INVALIDPROJECTFILE_TITLE);
                    string message         = Package.Instance.Context.NativeResources.GetString(ResId.IDS_E_INVALIDPROJECTFILE, projectFileName);
                    Package.Instance.Context.ShowErrorMessageBox(title, message);
                }
                this.Project.Unavailable = true;
                Tracer.Fail("There was an error parsing '{0}': {1}", filePath, e.ToString());
                return(false);
            }

            // Once the project has been loaded, it's not dirty anymore.
            this.Project.ClearDirty();

            return(true);
        }
コード例 #22
0
 /// <summary>
 /// Gets a localized string like "A file or folder with the name '{0}' already exists on disk at this location. Please choose another name."
 /// </summary>
 /// <param name="fileOrFolderName">The file or folder name that already exists.</param>
 /// <returns>A localized string like "A file or folder with the name '{0}' already exists on disk at this location. Please choose another name."</returns>
 public static string ErrorItemAlreadyExistsOnDisk(string fileOrFolderName)
 {
     Tracer.VerifyStringArgument(fileOrFolderName, "fileOrFolderName");
     return(GetString(StringId.ErrorItemAlreadyExistsOnDisk, fileOrFolderName));
 }
コード例 #23
0
        //==========================================================================================
        // Methods
        //==========================================================================================

        /// <summary>
        /// Gets a localized string like "Please consult the trace log at '{0}' for more information."
        /// </summary>
        /// <param name="traceLogPath">The path to the trace log file.</param>
        /// <returns>A localized string like "Please consult the trace log at '{0}' for more information."</returns>
        public static string ConsultTraceLog(string traceLogPath)
        {
            Tracer.VerifyStringArgument(traceLogPath, "traceLogPath");
            return(GetString(StringId.ConsultTraceLog, traceLogPath));
        }