Beispiel #1
0
        /// <summary>
        /// Notifies all of the listeners that a build operation is in progress.
        /// </summary>
        /// <returns>true if the build should continue; false if one or more of the listeners requested
        /// that the build should be canceled.</returns>
        public bool OnTick()
        {
            bool continueBuilding = true;

            // Let all of our listeners know that the build has started.
            Tracer.WriteLineVerbose(classType, "OnTick", "Notifying all of our listeners that the build is in progress.");

            // 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 (IVsBuildStatusCallback eventItem in clone)
            {
                try
                {
                    int continueFlag = Convert.ToInt32(continueBuilding);
                    eventItem.Tick(ref continueFlag);
                    if (continueFlag == 0)
                    {
                        continueBuilding = false;
                    }
                }
                catch (Exception e)
                {
                    Tracer.WriteLine(classType, "OnTick", Tracer.Level.Warning, "There was an exception in one of the listener's event handling code: {0}", e.ToString());
                }
            }

            return(continueBuilding);
        }
Beispiel #2
0
        /// <summary>
        /// Notifies all of our event listeners that an item in the hierarchy has changed.
        /// </summary>
        /// <param name="node">The <see cref="Node"/> that has changed.</param>
        /// <param name="propertyId">The property that has changed.</param>
        public void OnPropertyChanged(Node node, __VSHPROPID propertyId)
        {
            Tracer.VerifyNonNullArgument(node, "node");

            object newValue;

            node.GetProperty(propertyId, out newValue);

            // 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);

            for (int i = 0; i < clone.Count; i++)
            {
                IVsHierarchyEvents eventItem = (IVsHierarchyEvents)clone[i];
                Tracer.WriteLineVerbose(classType, "OnPropertyChanged", "Notifying event listener {0} that '{1}' has changed its {2} property to '{3}'.", this.CookieOf(i), node.Caption, propertyId, newValue);
                try
                {
                    eventItem.OnPropertyChanged(node.HierarchyId, (int)propertyId, 0);
                }
                catch (Exception e)
                {
                    Tracer.WriteLineWarning(classType, "OnPropertyChanged", "There was an exception in the event listener {0} event handling code: {1}", this.CookieOf(i), e.ToString());
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// Resumes file change notifications to the environment for the wrapped file.
        /// </summary>
        public void Resume()
        {
            if (!this.suspended)
            {
                return;
            }

            // Get the environment's change notifier.
            IVsFileChangeEx changeNotifier = Package.Instance.Context.GetService(typeof(SVsFileChangeEx)) as IVsFileChangeEx;

            Tracer.WriteLineIf(classType, "Resume", Tracer.Level.Warning, changeNotifier == null, "Could not get an instance of the IVsChangeEx interface.");
            if (changeNotifier != null)
            {
                // Tell the environment to resume sending change notifications for the file.
                int hr = changeNotifier.IgnoreFile(0, this.FilePath, ResumeNotification);
                Tracer.WriteLineIf(classType, "Resume", Tracer.Level.Warning, NativeMethods.Failed(hr), "Could not tell the environment to resume file change notifications to '{0}': Hr=0x{1:x}", this.FilePath, hr);
            }

            // Tell the environment to resume sending change notifications to editors.
            if (this.docDataFileChangeControl != null)
            {
                int hr = this.docDataFileChangeControl.IgnoreFileChanges(ResumeNotification);
                Tracer.WriteLineIf(classType, "Resume", Tracer.Level.Warning, NativeMethods.Failed(hr), "Could not tell the environment to resume file change notifications to editors of file '{0}': Hr=0x{1:x}", this.FilePath, hr);
                this.docDataFileChangeControl = null;
            }

            // At this point we can consider ourself resumed.
            this.suspended = false;
            Tracer.WriteLineVerbose(classType, "Resume", "Resumed file change notifications for '{0}'.", this.FilePath);
        }
Beispiel #4
0
        /// <summary>
        /// Gets the service object of the specified type.
        /// </summary>
        /// <param name="serviceType">An object that specifies the type of service object to get.</param>
        /// <returns>
        /// <para>A service object of type <paramref name="serviceType"/>.</para>
        /// <para>-or-</para>
        /// <para><see langword="null"/> if there is no service object of type
        /// <paramref name="serviceType"/>.</para>
        /// </returns>
        public object GetService(Type serviceType)
        {
            Tracer.VerifyNonNullArgument(serviceType, "serviceType");
            Tracer.WriteLineVerbose(classType, "GetService", "ServiceType = {0}", serviceType.FullName);

            // Check for the special services that we provide.
            if (serviceType == typeof(IServiceContainer) || serviceType == Instance.GetType())
            {
                return(this);
            }

            object value = null;

            // Check our proferred services list to see if we can return this service.
            if (this.services != null)
            {
                value = this.services[serviceType];
                if (value is ProfferedService)
                {
                    value = ((ProfferedService)value).Instance;
                }

                // If we have a callback then we have to attempt to create the service
                // by calling the callback method.
                if (value is ServiceCreatorCallback)
                {
                    // In case the callback method tries to recursively call back into
                    // us, we'll just null out the entry for this service now. That
                    // way this method will just fail instead of allowing for a stack
                    // overflow exception.
                    this.services[serviceType] = null;

                    // Let the callback create the service.
                    Tracer.WriteLineVerbose(classType, "GetService", "Creating the {0} service via a callback.", serviceType.FullName);
                    value = ((ServiceCreatorCallback)value)(this, serviceType);

                    // Verify that the callback gave us a valid service.
                    if (value != null && !value.GetType().IsCOMObject&& !serviceType.IsAssignableFrom(value.GetType()))
                    {
                        // Well, the callback was naughty and didn't give us what we wanted, but
                        // let's not punish our caller by raising an exception. We'll just fail
                        // by nulling the value.
                        Tracer.Fail("The service creator callback returned the object '{0}' that doesn't implement the requested type '{1}'", value.GetType().FullName, serviceType.FullName);
                        value = null;
                    }

                    // Set the created service in our proferred service list.
                    this.services[serviceType] = value;
                }
            }

            // Let our parent provider handle the rest of the types.
            if (value == null && this.Context.ServiceProvider != null)
            {
                value = this.Context.ServiceProvider.GetService(serviceType);
            }

            return(value);
        }
Beispiel #5
0
        /// <summary>
        /// Gets the service object of the specified type.
        /// </summary>
        /// <param name="serviceType">An object that specifies the type of service object to get.</param>
        /// <returns>
        /// A service object of type <paramref name="serviceType"/>, or <see langword="null"/>
        /// if there is no service object of type <paramref name="serviceType"/>.
        /// </returns>
        public object GetService(Type serviceType)
        {
            Tracer.VerifyNonNullArgument(serviceType, "serviceType");
            Tracer.WriteLineVerbose(classType, "GetService", "ServiceType = {0}", serviceType.FullName);
            object service = this.GetService(serviceType.GUID);

            return(service);
        }
Beispiel #6
0
        /// <summary>
        /// Acts as the factory method for any services exposed through an implementation of
        /// <see cref="IOleServiceProvider"/>.
        /// </summary>
        /// <param name="sid">Unique identifier of the service (an SID).</param>
        /// <param name="iid">Unique identifier of the interface the caller wishes to receive for the service.</param>
        /// <param name="ppvObj">
        /// Address of the caller-allocated variable to receive the interface pointer of the
        /// service on successful return from this function. The caller becomes responsible
        /// for calling <b>Release</b> through this interface pointer when the service is no
        /// longer needed.
        /// </param>
        /// <returns>
        ///     Returns one of the following values:
        ///     <list type="table">
        ///     <item>
        ///         <term>S_OK</term>
        ///         <description>The service was successfully created or retrieved. The caller is
        ///         responsible for calling ((IUnknown *)*ppv)->Release();.</description>
        ///     </item>
        ///     <item>
        ///         <term>E_OUTOFMEMORY</term>
        ///         <description>There is insufficient memory to create the service.</description>
        ///     </item>
        ///     <item>
        ///         <term>E_UNEXPECTED</term>
        ///         <description>An unknown error occurred.</description>
        ///     </item>
        ///     <item>
        ///         <term>E_NOINTERFACE</term>
        ///         <description>The service exists, but the interface requested does not exist
        ///         on that service.</description>
        ///     </item>
        ///     </list>
        /// </returns>
        int IOleServiceProvider.QueryService(ref Guid sid, ref Guid iid, out IntPtr ppvObj)
        {
            Tracer.WriteLineVerbose(classType, "IOleServiceProvider.QueryService", "Querying for service {0}", sid.ToString("B"));
            ppvObj = IntPtr.Zero;
            int    hr      = NativeMethods.S_OK;
            object service = null;

            // See if we can find the service in our proffered services list.
            if (this.services != null)
            {
                foreach (Type serviceType in this.services.Keys)
                {
                    if (serviceType.GUID == sid)
                    {
                        service = GetService(serviceType);
                        break;
                    }
                }
            }

            if (service == null)
            {
                Tracer.WriteLineVerbose(classType, "IOleServiceProvider.QueryService", "Could not find service {0}", sid.ToString("B"));
                return(NativeMethods.E_NOINTERFACE);
            }

            // If the caller requested an IID other than IUnknown, then we have to
            // query for that interface. Otherwise, we can just return the IUnknown.
            if (iid == NativeMethods.IID_IUnknown)
            {
                ppvObj = Marshal.GetIUnknownForObject(service);
            }
            else
            {
                IntPtr pUnk = Marshal.GetIUnknownForObject(service);
                hr = Marshal.QueryInterface(pUnk, ref iid, out ppvObj);
                Marshal.Release(pUnk);
            }

            return(hr);
        }
Beispiel #7
0
        /// <summary>
        /// Suspends any file change notifications to the environment for the wrapped file in
        /// preparation for a multi-stage file operation such as a rename.
        /// </summary>
        public void Suspend()
        {
            // We only want to suspend once.
            if (this.suspended)
            {
                return;
            }

            // Get the environment's change notifier.
            IVsFileChangeEx changeNotifier = Package.Instance.Context.GetService(typeof(SVsFileChangeEx)) as IVsFileChangeEx;

            if (changeNotifier == null)
            {
                Tracer.WriteLineWarning(classType, "Suspend", "Could not get an instance of the IVsChangeEx interface.");
                return;
            }

            // Tell the environment to stop sending change notifications for the file.
            int hr = changeNotifier.IgnoreFile(0, this.FilePath, IgnoreChanges);

            Tracer.WriteLineIf(classType, "Suspend", Tracer.Level.Warning, NativeMethods.Failed(hr), "Could not tell the environment to ignore file changes to '{0}': Hr=0x{1:x}", this.FilePath, hr);
            NativeMethods.ThrowOnFailure(hr);

            // Get the IVsDocDataFileChangeControl interface from the DocumentData. We need this
            // to suspend file change notifications to all editors.
            DocumentInfo docInfo = Package.Instance.Context.RunningDocumentTable.FindByPath(this.FilePath);

            if (docInfo != null)
            {
                this.docDataFileChangeControl = docInfo.DocumentData as IVsDocDataFileChangeControl;
                if (this.docDataFileChangeControl != null)
                {
                    hr = this.docDataFileChangeControl.IgnoreFileChanges(IgnoreChanges);
                    NativeMethods.ThrowOnFailure(hr);
                }
            }

            // At this point we can consider ourself suspended.
            this.suspended = true;
            Tracer.WriteLineVerbose(classType, "Suspend", "Suspended file change notifications for '{0}'.", this.FilePath);
        }
Beispiel #8
0
        /// <summary>
        /// Starts the specified build operation on the project for the currently selected project configuration.
        /// </summary>
        /// <param name="operation">The operation to perform.</param>
        public void StartBuild(BuildOperation operation)
        {
            Tracer.VerifyEnumArgument((int)operation, "operation", typeof(BuildOperation));

            // We have to verify that the environment is not busy right now
            if (Package.Instance.Context.IsSolutionBuilding)
            {
                Tracer.WriteLineVerbose(classType, "StartBuild", "The build manager is busy right now.");
                return;
            }

            // Get the build manager from VS
            IVsSolutionBuildManager solutionBuildMgr = this.ServiceProvider.GetServiceOrThrow(typeof(SVsSolutionBuildManager), typeof(IVsSolutionBuildManager), classType, "StartBuild") as IVsSolutionBuildManager;

            // Convert the enum to one of the VS flags
            VSSOLNBUILDUPDATEFLAGS flags = VSSOLNBUILDUPDATEFLAGS.SBF_OPERATION_NONE;

            switch (operation)
            {
            case BuildOperation.Clean:
                flags |= VSSOLNBUILDUPDATEFLAGS.SBF_OPERATION_CLEAN;
                break;

            case BuildOperation.Build:
                flags |= VSSOLNBUILDUPDATEFLAGS.SBF_OPERATION_BUILD;
                break;

            case BuildOperation.Rebuild:
                flags |= VSSOLNBUILDUPDATEFLAGS.SBF_OPERATION_CLEAN | VSSOLNBUILDUPDATEFLAGS.SBF_OPERATION_BUILD;
                break;

            default:
                Tracer.Fail("Unknown BuildOperation '{0}'", operation.ToString());
                return;
            }


            NativeMethods.ThrowOnFailure(solutionBuildMgr.StartSimpleUpdateProjectConfiguration((IVsHierarchy)this, null, null, (uint)flags, 0, 0));
        }
		int IVsCfgProvider2.GetCfgProviderProperty(int propid, out object pvar)
		{
			pvar = null;

			__VSCFGPROPID vsPropId = (__VSCFGPROPID)propid;
			switch (vsPropId)
			{
				case __VSCFGPROPID.VSCFGPROPID_SupportsCfgAdd:
				case __VSCFGPROPID.VSCFGPROPID_SupportsCfgDelete:
				case __VSCFGPROPID.VSCFGPROPID_SupportsCfgRename:
					pvar = true;
					break;

				case __VSCFGPROPID.VSCFGPROPID_SupportsPlatformAdd:
				case __VSCFGPROPID.VSCFGPROPID_SupportsPlatformDelete:
					pvar = false;
					break;
			}

			Tracer.WriteLineVerbose(classType, "IVsCfgProvider2.GetCfgProviderProperty", "Requested property '{0}' is {1}.", vsPropId, pvar);
			return NativeMethods.S_OK;
		}
Beispiel #10
0
 /// <summary>
 /// Called right after the value is removed from the collection.
 /// </summary>
 /// <param name="index">The index of the item removed from the collection.</param>
 /// <param name="value">The value just removed from the collection.</param>
 protected virtual void OnRemoveComplete(int index, object value)
 {
     Tracer.WriteLineVerbose(classType, "OnRemoveComplete", "Removed '{0}' from the collection.", value.ToString());
 }