OutputGroup.cs :  » Development » StyleCop » Microsoft » VisualStudio » Package » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Development » StyleCop 
StyleCop » Microsoft » VisualStudio » Package » OutputGroup.cs
/***************************************************************************

Copyright (c) Microsoft Corporation. All rights reserved.
This code is licensed under the Visual Studio SDK license terms.
THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.

***************************************************************************/

using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Globalization;
using System.Runtime.InteropServices;

using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.OLE.Interop;
using Microsoft.VisualStudio.Shell;

using MSBuildMicrosoft.Build.BuildEngine;
using System.Diagnostics.CodeAnalysis;

namespace Microsoft.VisualStudio.Package{
  /// <summary>
  /// Allows projects to group outputs according to usage.
  /// </summary>
  [CLSCompliant(false), ComVisible(true)]
  public class OutputGroup : IVsOutputGroup2
  {
    #region fields
    private ProjectConfig projectCfg;
    private ProjectNode project;

    private List<Output> outputs = new List<Output>();
    private Output keyOutput = null;
    private string name;
    private string targetName;
    #endregion

    #region properties
    /// <summary>
    /// Get the project configuration object associated with this output group
    /// </summary>
    [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Cfg")]
    protected ProjectConfig ProjectCfg
    {
      get { return projectCfg; }
    }

    /// <summary>
    /// Get the project object that produces this output group.
    /// </summary>
    protected ProjectNode Project
    {
      get { return project; }
    }

    /// <summary>
    /// Gets the msbuild target name which is assciated to the outputgroup.
    /// ProjectNode defines a static collection of output group names and their associated MsBuild target
    /// </summary>
    protected string TargetName
    {
      get { return targetName; }
    }
    #endregion

    #region ctors

    /// <summary>
    /// Constructor for IVSOutputGroup2 implementation
    /// </summary>
    /// <param name="outputName">Name of the output group. See VS_OUTPUTGROUP_CNAME_Build in vsshell.idl for the list of standard values</param>
    /// <param name="msBuildTargetName">MSBuild target name</param>
    /// <param name="projectManager">Project that produce this output</param>
    /// <param name="configuration">Configuration that produce this output</param>
    public OutputGroup(string outputName, string msBuildTargetName, ProjectNode projectManager, ProjectConfig configuration)
    {
      if (outputName == null)
        throw new ArgumentNullException("outputName");
      if (msBuildTargetName == null)
        throw new ArgumentNullException("outputName");
      if (projectManager == null)
        throw new ArgumentNullException("projectManager");
      if (configuration == null)
        throw new ArgumentNullException("configuration");

      name = outputName;
      targetName = msBuildTargetName;
      project = projectManager;
      projectCfg = configuration;
    }
    #endregion

    #region virtual methods
    protected virtual void Refresh()
    {
      // Let MSBuild know which configuration we are working with
      project.SetConfiguration(projectCfg.ConfigName);

      // Generate dependencies if such a task exist
      const string generateDependencyList = "AllProjectOutputGroups";
      if (project.BuildProject.Targets.Exists(generateDependencyList))
      {
        bool succeeded = false;
        project.BuildTarget(generateDependencyList, out succeeded);
        Debug.Assert(succeeded, "Failed to build target: " + generateDependencyList);
      }

      // Rebuild the content of our list of output
      string outputType = this.targetName + "KeyOutput";
      this.outputs.Clear();
      foreach (MSBuild.BuildItem assembly in project.BuildProject.GetEvaluatedItemsByName(outputType))
      {
        Output output = new Output(project, projectCfg, project.GetProjectElement(assembly));
        this.outputs.Add(output);

        // See if it is our key output
        if (String.Compare(assembly.GetEvaluatedMetadata("IsKeyOutput"), true.ToString(), StringComparison.OrdinalIgnoreCase) == 0)
          keyOutput = output;
      }

      project.SetCurrentConfiguration();

      // Now that the group is built we have to check if it is invalidated by a property
      // change on the project.
      project.OnProjectPropertyChanged += new EventHandler<ProjectPropertyChangedArgs>(OnProjectPropertyChanged);
    }

    public virtual void InvalidateGroup()
    {
      // Set keyOutput to null so that a refresh will be performed the next time
      // a property getter is called.
      if (null != keyOutput)
      {
        // Once the group is invalidated there is no more reason to listen for events.
        project.OnProjectPropertyChanged -= new EventHandler<ProjectPropertyChangedArgs>(OnProjectPropertyChanged);
      }
      keyOutput = null;
    }
    #endregion

    #region event handlers
    private void OnProjectPropertyChanged(object sender, ProjectPropertyChangedArgs args)
    {
      // In theory here we should decide if we have to invalidate the group according with the kind of property
      // that is changed.
      InvalidateGroup();
    }
    #endregion

    #region IVsOutputGroup2 Members

    public virtual int get_CanonicalName(out string pbstrCanonicalName)
    {
      pbstrCanonicalName = this.name;
      return VSConstants.S_OK;
    }

    public virtual int get_DeployDependencies(uint celt, IVsDeployDependency[] rgpdpd, uint[] pcActual)
    {
      return VSConstants.E_NOTIMPL;
    }

    public virtual int get_Description(out string pbstrDescription)
    {
      pbstrDescription = null;

      string description;
      int hr = this.get_CanonicalName(out description);
      if (ErrorHandler.Succeeded(hr))
        pbstrDescription = this.Project.GetOutputGroupDescription(description);
      return hr;
    }

    public virtual int get_DisplayName(out string pbstrDisplayName)
    {
      pbstrDisplayName = null;

      string displayName;
      int hr = this.get_CanonicalName(out displayName);
      if (ErrorHandler.Succeeded(hr))
        pbstrDisplayName = this.Project.GetOutputGroupDisplayName(displayName);
      return hr;
    }

    public virtual int get_KeyOutput(out string pbstrCanonicalName)
    {
      pbstrCanonicalName = null;
      if (keyOutput == null)
        Refresh();
      if (keyOutput == null)
      {
        pbstrCanonicalName = String.Empty;
        return VSConstants.S_FALSE;
      }
      return keyOutput.get_CanonicalName(out pbstrCanonicalName);
    }

    public virtual int get_KeyOutputObject(out IVsOutput2 ppKeyOutput)
    {
      if (keyOutput == null)
        Refresh();
      ppKeyOutput = keyOutput;
      if (ppKeyOutput == null)
        return VSConstants.S_FALSE;
      return VSConstants.S_OK;
    }

    public virtual int get_Outputs(uint celt, IVsOutput2[] rgpcfg, uint[] pcActual)
    {
      // Ensure that we are refreshed.  This is somewhat of a hack that enables project to
      // project reference scenarios to work.  Normally, output groups are populated as part
      // of build.  However, in the project to project reference case, what ends up happening
      // is that the referencing projects requests the referenced project's output group
      // before a build is done on the referenced project.
      //
      // Furthermore, the project auto toolbox manager requires output groups to be populated
      // on project reopen as well...
      //
      // In the end, this is probably the right thing to do, though -- as it keeps the output
      // groups always up to date.
      Refresh();

      // See if only the caller only wants to know the count
      if (celt == 0 || rgpcfg == null)
      {
        if (pcActual != null && pcActual.Length > 0)
          pcActual[0] = (uint)outputs.Count;
        return VSConstants.S_OK;
      }

      // Fill the array with our outputs
      uint count = 0;
      foreach (Output output in outputs)
      {
        if (rgpcfg.Length > count && celt > count && output != null)
        {
          rgpcfg[count] = output;
          ++count;
        }
      }

      if (pcActual != null && pcActual.Length > 0)
        pcActual[0] = count;

      // If the number asked for does not match the number returned, return S_FALSE
      return (count == celt) ? VSConstants.S_OK : VSConstants.S_FALSE;
    }

    public virtual int get_ProjectCfg(out IVsProjectCfg2 ppIVsProjectCfg2)
    {
      ppIVsProjectCfg2 = (IVsProjectCfg2)this.projectCfg;
      return VSConstants.S_OK;
    }

    public virtual int get_Property(string pszProperty, out object pvar)
    {
      pvar = project.GetProjectProperty(pszProperty);
      return VSConstants.S_OK;
    }

    #endregion
  }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.