Пример #1
0
        /// <summary>
        /// Checks whether the proposed caption already exists, meaning that there is not an existing file
        /// or folder at the root path or that there is not already a sibling hierarchy item with the same name.
        /// </summary>
        /// <param name="newCaption">The proposed caption.</param>
        /// <param name="newPath">The proposed new absolute file path.</param>
        /// <remarks>The method throws an exception if the caption already exists.</remarks>
        private void VerifyCaptionDoesNotExist(string newCaption, string newPath)
        {
            bool valid = true;

            // Make sure there isn't already a sibling with the same caption. The root node has no siblings.
            if (this.Parent != null)
            {
                foreach (Node sibling in this.Parent.Children)
                {
                    bool thisIsSibling = Object.ReferenceEquals(sibling, this);
                    bool captionsEqual = (PackageUtility.FileStringEquals(newCaption, sibling.Caption));
                    // We can have a file system node that is the same name as a virtual node.
                    // For example, we can name a file/folder "Library References" if we want,
                    // even though that is already in the hierarchy.
                    bool isExactlyOneVirtual = ((this.IsVirtual && !sibling.IsVirtual) || (!this.IsVirtual && sibling.IsVirtual));
                    if (!thisIsSibling && captionsEqual && !isExactlyOneVirtual)
                    {
                        valid = false;
                        break;
                    }
                }
            }

            if (valid)
            {
                // Now check to see if the file system already contains a file/folder by the same name.
                valid = ((this.IsFile && !File.Exists(newPath)) || (this.IsFolder && !Directory.Exists(newPath)));
            }

            if (!valid)
            {
                Tracer.WriteLineInformation(classType, "VerifyCaption", "An existing file or folder named '{0}' already exists on the disk.", newCaption);
                throw new InvalidOperationException(SconceStrings.ErrorItemAlreadyExistsOnDisk(newCaption));
            }
        }
Пример #2
0
        /// <summary>
        /// Throws an <see cref="InvalidOperationException"/> informing the user that a critical service is missing and to
        /// try to repair the Visual Studio installation.
        /// </summary>
        /// <param name="classType">The type of the class containing the method.</param>
        /// <param name="methodName">The name of the method that is being entered.</param>
        /// <param name="serviceType">An object that specifies the type of service object that was requested but failed.</param>
        /// <remarks>Also logs a failure message in the trace log and asserts in debug mode.</remarks>
        public void ThrowFailedServiceException(Type classType, string methodName, Type serviceType)
        {
            string serviceTypeName = serviceType.Name;

            Tracer.Fail("Cannot get an instance of {0}", serviceTypeName);
            throw new InvalidOperationException(SconceStrings.ErrorMissingService(serviceTypeName));
        }
Пример #3
0
        /// <summary>
        /// Gets a string from the resource file and formats it using the specified arguments.
        /// </summary>
        /// <param name="name">The resource identifier of the string to retrieve.</param>
        /// <param name="args">An array of objects to use in the formatting. Can be null or empty.</param>
        /// <returns>A formatted string from the resource file.</returns>
        public string GetString(string name, params object[] args)
        {
            string returnString = this.missingManifestString;

            // If we previously tried to get a string from the resource file and we had a
            // MissingManifestResourceException, then we don't want to try again. Exceptions
            // are expensive especially when we could be getting lots of strings.
            if (!this.isMissingManifest)
            {
                try
                {
                    // First give the subclass a chance to retrieve the string
                    if (this.IsStringDefined(name))
                    {
                        returnString = this.manager.GetString(name, CultureInfo.CurrentUICulture);
                    }
                    //\ Try getting the string from our assembly if the subclass can't handle it
                    else if (SconceStrings.IsValidStringName(name))
                    {
                        returnString = thisAssemblyManager.GetString(name, CultureInfo.CurrentUICulture);
                    }
                    else
                    {
                        Tracer.WriteLineWarning(classType, "GetString", "The string id '{0}' is not defined.", name);
                        returnString = name;
                    }

                    // Format the message if there are arguments specified. Note that we format
                    // using the CurrentCulture and not the CurrentUICulture (although in almost all
                    // cases it will be the same).
                    if (returnString != null && args != null && args.Length > 0)
                    {
                        returnString = String.Format(CultureInfo.CurrentCulture, returnString, args);
                    }
                }
                catch (MissingManifestResourceException e)
                {
                    this.isMissingManifest = true;
                    Tracer.Fail("The resource cannot be found in the assembly: {0}", e);
                }
            }

            return(returnString);
        }
Пример #4
0
        //==========================================================================================
        // Properties
        //==========================================================================================

        #endregion

        #region Methods
        //==========================================================================================
        // Methods
        //==========================================================================================

        /// <summary>
        /// Returns a value indicating whether the specified name is a defined string resource name.
        /// </summary>
        /// <param name="name">The resource identifier to check.</param>
        /// <returns>true if the string identifier is defined in our assembly; otherwise, false.</returns>
        public virtual bool IsStringDefined(string name)
        {
            return(SconceStrings.IsValidStringName(name));
        }
Пример #5
0
 public static void AppendConsultTraceMessage(ref string message)
 {
     message += SconceStrings.ConsultTraceLog(Tracer.LogPath);
 }
Пример #6
0
        /// <summary>
        /// Opens the standard editor for this file type in Visual Studio.
        /// </summary>
        /// <param name="logicalView">The type of view in which to open the document.</param>
        /// <param name="existingDocumentData">
        /// Passed through to the IVsUIShellOpenDocument.OpenStandardEditor or OpenSpecificEditor, which
        /// will then determine if the document is already opened and reused the open window.
        /// </param>
        /// <param name="physicalView">
        /// Name of the physical view if we're opening with a specific editor. Not used if opening with a standard editor.
        /// </param>
        /// <param name="specificEditor">The GUID of the specific registered editor to use to open this node.</param>
        /// <returns>The <see cref="IVsWindowFrame"/> object that contains the opened document.</returns>
        private IVsWindowFrame Open(VsLogicalView logicalView, IntPtr existingDocumentData, Guid specificEditor, string physicalView)
        {
            Tracer.VerifyNonNullArgument(logicalView, "logicalView");

            // Check to see if the file exists before we try to open it.
            if (!File.Exists(this.AbsolutePath))
            {
                Context.ShowErrorMessageBox(SconceStrings.FileDoesNotExist(this.AbsolutePath));
                return(null);
            }

            IVsWindowFrame windowFrame;
            Guid           logicalViewGuid   = logicalView.Value;
            Guid           editorTypeGuid    = specificEditor;
            bool           useSpecificEditor = (specificEditor != Guid.Empty);
            int            hr;

            // Get a IVsUIShellOpenDocument object so that we can use it to open the document.
            IVsUIShellOpenDocument vsUIShellOpenDocument = (IVsUIShellOpenDocument)this.ServiceProvider.GetServiceOrThrow(typeof(SVsUIShellOpenDocument), typeof(IVsUIShellOpenDocument), classType, "Open");

            // Open the document.
            if (useSpecificEditor)
            {
                hr = vsUIShellOpenDocument.OpenSpecificEditor(
                    0,
                    this.CanonicalName,
                    ref editorTypeGuid,
                    physicalView,
                    ref logicalViewGuid,
                    this.Caption,
                    (IVsUIHierarchy)this.Hierarchy,
                    this.HierarchyId,
                    existingDocumentData,
                    (Microsoft.VisualStudio.OLE.Interop.IServiceProvider)Package.Instance,
                    out windowFrame);
            }
            else
            {
                hr = vsUIShellOpenDocument.OpenStandardEditor(
                    unchecked ((uint)__VSOSEFLAGS.OSE_ChooseBestStdEditor),
                    this.CanonicalName,
                    ref logicalViewGuid,
                    this.Caption,
                    (IVsUIHierarchy)this.Hierarchy,
                    this.HierarchyId,
                    existingDocumentData,
                    (Microsoft.VisualStudio.OLE.Interop.IServiceProvider)Package.Instance,
                    out windowFrame);
            }

            string editorTypeName = useSpecificEditor ? "specific" : "standard";

            if (NativeMethods.Succeeded(hr))
            {
                Tracer.WriteLineInformation(classType, "Open", "Succeeded in opening '{0}' with a {1} editor.", this.AbsolutePath, editorTypeName);
                if (windowFrame != null)
                {
                    // Get the document cookie and cache it.
                    object pvar;
                    hr = windowFrame.GetProperty((int)__VSFPROPID.VSFPROPID_DocCookie, out pvar);
                    NativeMethods.ThrowOnFailure(hr);
                    // pvar is an int, but we need a uint. We get an error if we try to immediately cast to uint
                    // without first casting to an int.
                    uint cookie = unchecked ((uint)(int)pvar);
                    this.SetDocumentCookie(cookie);
                    Tracer.WriteLineInformation(classType, "Open", "Document '{0}' has a cookie value of {1}", this.AbsolutePath, cookie);

                    // Show the window frame of the open document. The documentation says we don't need to do this, but the reality is different.
                    hr = windowFrame.Show();
                    Tracer.Assert(NativeMethods.Succeeded(hr), "Error in IVsWindowFrame.Show(): 0x{0:x}", hr);

                    // Trace the running documents.
                    VsHelperMethods.TraceRunningDocuments();
                }
                else
                {
                    Tracer.Fail("Open succeeded but we were returned a null IVsWindowFrame so we can't show the document.");
                }
            }
            else if (hr == NativeMethods.OLE_E_PROMPTSAVECANCELLED)
            {
                Tracer.WriteLineInformation(classType, "Open", "The user canceled out of the open dialog box.");
            }
            else
            {
                Tracer.Fail("Failed to open '{0}' with a {1} editor. Hr=0x{2:x}", this.AbsolutePath, editorTypeName, hr);
                NativeMethods.ThrowOnFailure(hr);
            }

            return(windowFrame);
        }
Пример #7
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);
        }