Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
BuildLogPipeGenerator.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 using System;
4 using System.Collections.Generic;
5 using System.Linq;
6 using Microsoft.Build.Evaluation;
7 using Microsoft.Build.Execution;
8 using Microsoft.VisualStudio;
9 using Microsoft.VisualStudio.Shell.Interop;
10 
11 namespace SiliconStudio.Paradox.VisualStudio
12 {
13  public class BuildLogPipeGenerator
14  {
15  private string logPipeUrl = "net.pipe://localhost/Paradox.BuildEngine.Monitor." + Guid.NewGuid();
16  private SolutionEventsListener solutionEventsListener;
17 
18  public string LogPipeUrl
19  {
20  get { return logPipeUrl; }
21  }
22 
23  public BuildLogPipeGenerator(IServiceProvider serviceProvider)
24  {
25  // Initialize the solution listener that will set ParadoxVSBuilderMonitorGuid for this instance of VisualStudio.
26  solutionEventsListener = new SolutionEventsListener(serviceProvider);
27  solutionEventsListener.AfterProjectOpened += OnProjectOpened;
28 
29  // Process already opened projects
30  var solution = serviceProvider.GetService(typeof(SVsSolution)) as IVsSolution;
31  if (solution != null)
32  {
33  IEnumHierarchies enumerator;
34  var guid = Guid.Empty;
35  var hierarchy = new IVsHierarchy[1] { null };
36  uint fetched = 0;
37 
38  solution.GetProjectEnum((uint)__VSENUMPROJFLAGS.EPF_LOADEDINSOLUTION, ref guid, out enumerator);
39  for (enumerator.Reset(); enumerator.Next(1, hierarchy, out fetched) == VSConstants.S_OK && fetched == 1; )
40  {
41  OnProjectOpened(hierarchy[0]);
42  }
43  }
44  }
45 
46  private void OnProjectOpened(IVsHierarchy vsHierarchy)
47  {
48  // Register pipe url so that MSBuild can transfer it
49  var vsProject = vsHierarchy as IVsProject;
50  if (vsProject != null)
51  {
52  var dteProject = VsHelper.ToDteProject(vsProject);
53 
54  // We will only deal with .csproj files for now
55  // Should we support C++/CLI .vcxproj as well?
56  if (!dteProject.FileName.EndsWith(".csproj"))
57  return;
58 
59  // Find current project active configuration
60  var configManager = dteProject.ConfigurationManager;
61  if (configManager == null)
62  return;
63 
64  EnvDTE.Configuration activeConfig;
65  try
66  {
67  activeConfig = configManager.ActiveConfiguration;
68  }
69  catch (Exception)
70  {
71  if (configManager.Count == 0)
72  return;
73 
74  activeConfig = configManager.Item(1);
75  }
76 
77  // Get global parameters for Configuration and Platform
78  var globalProperties = new Dictionary<string, string>();
79  globalProperties["Configuration"] = activeConfig.ConfigurationName;
80  globalProperties["Platform"] = activeConfig.PlatformName == "Any CPU" ? "AnyCPU" : activeConfig.PlatformName;
81 
82  // Check if project matches: Condition="'$(SiliconStudioCurrentPackagePath)' != '' and '$(SiliconStudioIsExecutable)' == 'true'"
83  var projectInstance = new ProjectInstance(dteProject.FileName, globalProperties, null);
84  var packagePathProperty = projectInstance.Properties.FirstOrDefault(x => x.Name == "SiliconStudioCurrentPackagePath");
85  var isExecutableProperty = projectInstance.Properties.FirstOrDefault(x => x.Name == "SiliconStudioIsExecutable");
86  if (packagePathProperty == null || isExecutableProperty == null || isExecutableProperty.EvaluatedValue.ToLowerInvariant() != "true")
87  return;
88 
89  var buildProjects = ProjectCollection.GlobalProjectCollection.GetLoadedProjects(dteProject.FileName);
90  foreach (var buildProject in buildProjects)
91  {
92  buildProject.SetGlobalProperty("SiliconStudioBuildEngineLogPipeUrl", logPipeUrl);
93  }
94  }
95  }
96  }
97 }