Advertisement
Guest User

Fixed VCProject.cs for NSight Tegra debugging in UE4

a guest
Apr 14th, 2016
159
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 57.92 KB | None | 0 0
  1. // Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
  2.  
  3. using System;
  4. using System.Collections.Generic;
  5. using System.IO;
  6. using System.Xml;
  7. using System.Xml.XPath;
  8. using System.Xml.Linq;
  9. using System.Linq;
  10. using System.Text;
  11. using System.Diagnostics;
  12.  
  13. namespace UnrealBuildTool
  14. {
  15.     public abstract class MSBuildProjectFile : ProjectFile
  16.     {
  17.         /// The project file version string
  18.         static public readonly string VCProjectFileVersionString = "10.0.30319.1";
  19.  
  20.         /// The build configuration name to use for stub project configurations.  These are projects whose purpose
  21.         /// is to make it easier for developers to find source files and to provide IntelliSense data for the module
  22.         /// to Visual Studio
  23.         static public readonly string StubProjectConfigurationName = "BuiltWithUnrealBuildTool";
  24.  
  25.         /// The name of the Visual C++ platform to use for stub project configurations
  26.         /// NOTE: We always use Win32 for the stub project's platform, since that is guaranteed to be supported by Visual Studio
  27.         static public readonly string StubProjectPlatformName = "Win32";
  28.  
  29.         /// override project configuration name for platforms visual studio doesn't natively support
  30.         public string ProjectConfigurationNameOverride = "";
  31.  
  32.         /// override project platform for platforms visual studio doesn't natively support
  33.         public string ProjectPlatformNameOverride = "";
  34.  
  35.         /// <summary>
  36.         /// The Guid representing the project type e.g. C# or C++
  37.         /// </summary>
  38.         public virtual string ProjectTypeGUID
  39.         {
  40.             get { throw new BuildException( "Unrecognized type of project file for Visual Studio solution" ); }
  41.         }
  42.  
  43.         /// <summary>
  44.         /// Constructs a new project file object
  45.         /// </summary>
  46.         /// <param name="InitFilePath">The path to the project file on disk</param>
  47.         public MSBuildProjectFile(string InitFilePath)
  48.             : base(InitFilePath)
  49.         {
  50.             // Each project gets its own GUID.  This is stored in the project file and referenced in the solution file.
  51.  
  52.             // First, check to see if we have an existing file on disk.  If we do, then we'll try to preserve the
  53.             // GUID by loading it from the existing file.
  54.             if (File.Exists(ProjectFilePath))
  55.             {
  56.                 try
  57.                 {
  58.                     LoadGUIDFromExistingProject();
  59.                 }
  60.                 catch (Exception)
  61.                 {
  62.                     // Failed to find GUID, so just create a new one
  63.                     ProjectGUID = Guid.NewGuid();
  64.                 }
  65.             }
  66.  
  67.             if (ProjectGUID == Guid.Empty)
  68.             {
  69.                 // Generate a brand new GUID
  70.                 ProjectGUID = Guid.NewGuid();
  71.             }
  72.         }
  73.  
  74.  
  75.         /// <summary>
  76.         /// Attempts to load the project's GUID from an existing project file on disk
  77.         /// </summary>
  78.         public override void LoadGUIDFromExistingProject()
  79.         {
  80.             // Only load GUIDs if we're in project generation mode.  Regular builds don't need GUIDs for anything.
  81.             if( ProjectFileGenerator.bGenerateProjectFiles )
  82.             {
  83.                 var Doc = new XmlDocument();
  84.                 Doc.Load( ProjectFilePath );
  85.  
  86.                 // @todo projectfiles: Ideally we could do a better job about preserving GUIDs when only minor changes are made
  87.                 // to the project (such as adding a single new file.) It would make diffing changes much easier!
  88.  
  89.                 // @todo projectfiles: Can we "seed" a GUID based off the project path and generate consistent GUIDs each time?
  90.  
  91.                 var Elements = Doc.GetElementsByTagName( "ProjectGuid" );
  92.                 foreach( XmlElement Element in Elements )
  93.                 {
  94.                     ProjectGUID = Guid.ParseExact( Element.InnerText.Trim( "{}".ToCharArray() ), "D" );
  95.                 }
  96.             }
  97.         }
  98.  
  99.  
  100.         /// <summary>
  101.         /// Given a target platform and configuration, generates a platform and configuration name string to use in Visual Studio projects.
  102.         /// Unlike with solution configurations, Visual Studio project configurations only support certain types of platforms, so we'll
  103.         /// generate a configuration name that has the platform "built in", and use a default platform type
  104.         /// </summary>
  105.         /// <param name="Platform">Actual platform</param>
  106.         /// <param name="Configuration">Actual configuration</param>
  107.         /// <param name="TargetConfigurationName">The configuration name from the target rules, or null if we don't have one</param>
  108.         /// <param name="ProjectPlatformName">Name of platform string to use for Visual Studio project</param>
  109.         /// <param name="ProjectConfigurationName">Name of configuration string to use for Visual Studio project</param>
  110.         public void MakeProjectPlatformAndConfigurationNames(UnrealTargetPlatform Platform, UnrealTargetConfiguration Configuration, string TargetConfigurationName, out string ProjectPlatformName, out string ProjectConfigurationName)
  111.         {
  112.             if (IsStubProject)
  113.             {
  114.                 if (Platform != UnrealTargetPlatform.Unknown || Configuration != UnrealTargetConfiguration.Unknown)
  115.                 {
  116.                     throw new BuildException("Stub project was expecting platform and configuration type to be set to Unknown");
  117.                 }
  118.                 ProjectPlatformName = StubProjectPlatformName;
  119.                 ProjectConfigurationName = StubProjectConfigurationName;
  120.             }
  121.             else
  122.             {
  123.                 // If this is a C# project, then the project platform name must always be "Any CPU"
  124.                 if (this is VCSharpProjectFile)
  125.                 {
  126.                     ProjectConfigurationName = Configuration.ToString();
  127.                     ProjectPlatformName = VCProjectFileGenerator.DotNetPlatformName;
  128.                 }
  129.                 else
  130.                 {
  131.                     var PlatformProjectGenerator = UEPlatformProjectGenerator.GetPlatformProjectGenerator(Platform, bInAllowFailure: true);
  132.  
  133.                     // Check to see if this platform is supported directly by Visual Studio projects.
  134.                     bool HasActualVSPlatform = (PlatformProjectGenerator != null) ? PlatformProjectGenerator.HasVisualStudioSupport(Platform, Configuration) : false;
  135.  
  136.                     if (HasActualVSPlatform)
  137.                     {
  138.                         // Great!  Visual Studio supports this platform natively, so we don't need to make up
  139.                         // a fake project configuration name.
  140.  
  141.                         // Allow the platform to specify the name used in VisualStudio.
  142.                         // Note that the actual name of the platform on the Visual Studio side may be different than what
  143.                         // UnrealBuildTool calls it (e.g. "Win64" -> "x64".) GetVisualStudioPlatformName() will figure this out.
  144.                         ProjectConfigurationName = Configuration.ToString();
  145.                         ProjectPlatformName = PlatformProjectGenerator.GetVisualStudioPlatformName(Platform, Configuration);
  146.                     }
  147.                     else
  148.                     {
  149.                         // Visual Studio doesn't natively support this platform, so we fake it by mapping it to
  150.                         // a project configuration that has the platform name in that configuration as a suffix,
  151.                         // and then using "Win32" as the actual VS platform name
  152.                         ProjectConfigurationName = ProjectConfigurationNameOverride == "" ? Platform.ToString() + "_" + Configuration.ToString() : ProjectConfigurationNameOverride;
  153.                         ProjectPlatformName = ProjectPlatformNameOverride == "" ? VCProjectFileGenerator.DefaultPlatformName : ProjectPlatformNameOverride;
  154.                     }
  155.  
  156.                     if( !String.IsNullOrEmpty( TargetConfigurationName ) )
  157.                     {
  158.                         ProjectConfigurationName += "_" + TargetConfigurationName;
  159.                     }
  160.                 }
  161.             }
  162.         }
  163.  
  164.  
  165.         /// <summary>
  166.         /// Checks to see if the specified solution platform and configuration is able to map to this project
  167.         /// </summary>
  168.         /// <param name="ProjectTarget">The target that we're checking for a valid platform/config combination</param>
  169.         /// <param name="Platform">Platform</param>
  170.         /// <param name="Configuration">Configuration</param>
  171.         /// <returns>True if this is a valid combination for this project, otherwise false</returns>
  172.         public static bool IsValidProjectPlatformAndConfiguration(ProjectTarget ProjectTarget, UnrealTargetPlatform Platform, UnrealTargetConfiguration Configuration)
  173.         {
  174.             var PlatformProjectGenerator = UEPlatformProjectGenerator.GetPlatformProjectGenerator(Platform, true);
  175.             if (PlatformProjectGenerator == null)
  176.             {
  177.                 return false;
  178.             }
  179.  
  180.             var BuildPlatform = UEBuildPlatform.GetBuildPlatform(Platform, true);
  181.             if (BuildPlatform == null)
  182.             {
  183.                 return false;
  184.             }
  185.  
  186.             if (BuildPlatform.HasRequiredSDKsInstalled() != SDKStatus.Valid)
  187.             {
  188.                 return false;
  189.             }
  190.  
  191.  
  192.             var SupportedConfigurations = new List<UnrealTargetConfiguration>();
  193.             var SupportedPlatforms = new List<UnrealTargetPlatform>();
  194.             if (!ProjectFileGenerator.bCreateDummyConfigsForUnsupportedPlatforms)
  195.             {
  196.                 if( ProjectTarget.TargetRules != null )
  197.                 {
  198.                     ProjectTarget.TargetRules.GetSupportedPlatforms(ref SupportedPlatforms);
  199.                 }
  200.             }
  201.             else
  202.             {
  203.                 UnrealBuildTool.GetAllPlatforms(ref SupportedPlatforms);
  204.             }
  205.             bool bIncludeTestAndShippingConfigs = ProjectFileGenerator.bIncludeTestAndShippingConfigs || ProjectFileGenerator.bGeneratingRocketProjectFiles;
  206.             if( ProjectTarget.TargetRules != null )
  207.             {
  208.                 // Rocket projects always get shipping configs
  209.                 ProjectTarget.TargetRules.GetSupportedConfigurations(ref SupportedConfigurations, bIncludeTestAndShippingConfigs:bIncludeTestAndShippingConfigs);
  210.             }
  211.  
  212.             // Add all of the extra platforms/configurations for this target
  213.             {
  214.                 foreach( var ExtraPlatform in ProjectTarget.ExtraSupportedPlatforms )
  215.                 {
  216.                     if( !SupportedPlatforms.Contains( ExtraPlatform ) )
  217.                     {
  218.                         SupportedPlatforms.Add( ExtraPlatform );
  219.                     }
  220.                 }
  221.                 foreach( var ExtraConfig in ProjectTarget.ExtraSupportedConfigurations )
  222.                 {
  223.                     if( bIncludeTestAndShippingConfigs || ( ExtraConfig != UnrealTargetConfiguration.Shipping && ExtraConfig != UnrealTargetConfiguration.Test ) )
  224.                     {
  225.                         if( !SupportedConfigurations.Contains( ExtraConfig ) )
  226.                         {
  227.                             SupportedConfigurations.Add( ExtraConfig );
  228.                         }
  229.                     }
  230.                 }
  231.             }
  232.  
  233.             // Only build for supported platforms
  234.             if (SupportedPlatforms.Contains(Platform) == false)
  235.             {
  236.                 return false;
  237.             }
  238.  
  239.             // Only build for supported configurations
  240.             if (SupportedConfigurations.Contains(Configuration) == false)
  241.             {
  242.                 return false;
  243.             }
  244.  
  245.             return true;
  246.         }
  247.  
  248.         /// <summary>
  249.         /// GUID for this Visual C++ project file
  250.         /// </summary>
  251.         public Guid ProjectGUID
  252.         {
  253.             get;
  254.             protected set;
  255.         }
  256.     }
  257.            
  258.     public class VCProjectFile : MSBuildProjectFile
  259.     {
  260.         // This is the GUID that Visual Studio uses to identify a C++ project file in the solution
  261.         public override string ProjectTypeGUID
  262.         {
  263.             get { return "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}"; }
  264.         }
  265.  
  266.         /// <summary>
  267.         /// Constructs a new project file object
  268.         /// </summary>
  269.         /// <param name="InitFilePath">The path to the project file on disk</param>
  270.         public VCProjectFile(string InitFilePath)
  271.             : base( InitFilePath )
  272.         {
  273.         }
  274.  
  275.  
  276.         class ProjectConfigAndTargetCombination
  277.         {
  278.             public UnrealTargetPlatform Platform;
  279.             public UnrealTargetConfiguration Configuration;
  280.             public string ProjectPlatformName;
  281.             public string ProjectConfigurationName;
  282.             public ProjectTarget ProjectTarget;
  283.  
  284.             public ProjectConfigAndTargetCombination(UnrealTargetPlatform InPlatform, UnrealTargetConfiguration InConfiguration, string InProjectPlatformName, string InProjectConfigurationName, ProjectTarget InProjectTarget)
  285.             {
  286.                 Platform = InPlatform;
  287.                 Configuration = InConfiguration;
  288.                 ProjectPlatformName = InProjectPlatformName;
  289.                 ProjectConfigurationName = InProjectConfigurationName;
  290.                 ProjectTarget = InProjectTarget;
  291.             }
  292.  
  293.             public string ProjectConfigurationAndPlatformName
  294.             {
  295.                 get { return (ProjectPlatformName == null)? null : (ProjectConfigurationName + "|" + ProjectPlatformName); }
  296.             }
  297.  
  298.             public override string ToString()
  299.             {
  300.                 return String.Format("{0} {1} {2}", ProjectTarget, Platform, Configuration);
  301.             }
  302.         }
  303.  
  304.  
  305.         /// Implements Project interface
  306.         public override bool WriteProjectFile(List<UnrealTargetPlatform> InPlatforms, List<UnrealTargetConfiguration> InConfigurations)
  307.         {
  308.             string ProjectName = Path.GetFileNameWithoutExtension(ProjectFilePath);
  309.  
  310.             bool bSuccess = true;
  311.  
  312.             // NOTE: We intentionally do not SORT the source file list, as we want the order they're written to disk to be consistent
  313.             //       with how they are stored in memory.  This makes for more consistent Unity compiles when alternating between
  314.             //       using "auto" projects and on-disk projects for builds.
  315.             var ShouldSortSourceFiles = false;
  316.             if( ShouldSortSourceFiles )
  317.             {
  318.                 // Source our list of source files
  319.                 Comparison<SourceFile> SourceFileComparer = ( FileA, FileB ) => { return FileA.FilePath.CompareTo( FileB.FilePath ); };
  320.                 SourceFiles.Sort( SourceFileComparer );
  321.             }
  322.  
  323.             // Build up the new include search path string
  324.             var VCIncludeSearchPaths = new StringBuilder();
  325.             {
  326.                 foreach (var CurPath in IntelliSenseIncludeSearchPaths)
  327.                 {
  328.                     VCIncludeSearchPaths.Append(CurPath + ";");
  329.                 }
  330.                 foreach (var CurPath in IntelliSenseSystemIncludeSearchPaths)
  331.                 {
  332.                     VCIncludeSearchPaths.Append(CurPath + ";");
  333.                 }
  334.                 if (InPlatforms.Contains(UnrealTargetPlatform.UWP))
  335.                 {
  336.                     VCIncludeSearchPaths.Append(UWPToolChain.GetVCIncludePaths(CPPTargetPlatform.UWP) + ";");
  337.                 }
  338.                 else if (InPlatforms.Contains(UnrealTargetPlatform.Win64))
  339.                 {
  340.                     VCIncludeSearchPaths.Append(VCToolChain.GetVCIncludePaths(CPPTargetPlatform.Win64) + ";");
  341.                 }
  342.                 else if (InPlatforms.Contains(UnrealTargetPlatform.Win32))
  343.                 {
  344.                     VCIncludeSearchPaths.Append(VCToolChain.GetVCIncludePaths(CPPTargetPlatform.Win32) + ";");
  345.                 }
  346.             }
  347.  
  348.             var VCPreprocessorDefinitions = new StringBuilder();
  349.             foreach( var CurDef in IntelliSensePreprocessorDefinitions )
  350.             {
  351.                 if( VCPreprocessorDefinitions.Length > 0 )
  352.                 {
  353.                     VCPreprocessorDefinitions.Append( ';' );
  354.                 }
  355.                 VCPreprocessorDefinitions.Append( CurDef );
  356.             }
  357.  
  358.             // Setup VC project file content
  359.             var VCProjectFileContent = new StringBuilder();
  360.             var VCFiltersFileContent = new StringBuilder();
  361.             var VCUserFileContent = new StringBuilder();
  362.  
  363.             // Visual Studio doesn't require a *.vcxproj.filters file to even exist alongside the project unless
  364.             // it actually has something of substance in it.  We'll avoid saving it out unless we need to.
  365.             var FiltersFileIsNeeded = false;
  366.  
  367.             // Project file header
  368.             VCProjectFileContent.Append(
  369.                 "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + ProjectFileGenerator.NewLine +
  370.                 ProjectFileGenerator.NewLine +
  371.                 "<Project DefaultTargets=\"Build\" ToolsVersion=\"" + VCProjectFileGenerator.ProjectFileToolVersionString + "\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">" + ProjectFileGenerator.NewLine);
  372.  
  373.             bool bGenerateUserFileContent = UEPlatformProjectGenerator.PlatformRequiresVSUserFileGeneration(InPlatforms, InConfigurations);
  374.             if (bGenerateUserFileContent)
  375.             {
  376.                 VCUserFileContent.Append(
  377.                     "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + ProjectFileGenerator.NewLine +
  378.                     ProjectFileGenerator.NewLine +
  379.                     "<Project ToolsVersion=\"" + VCProjectFileGenerator.ProjectFileToolVersionString + "\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">" + ProjectFileGenerator.NewLine
  380.                     );
  381.             }
  382.  
  383.             // Build up a list of platforms and configurations this project will support.  In this list, Unknown simply
  384.             // means that we should use the default "stub" project platform and configuration name.
  385.             var ProjectConfigAndTargetCombinations = new List< ProjectConfigAndTargetCombination >();
  386.  
  387.             // If this is a "stub" project, then only add a single configuration to the project
  388.             if( IsStubProject )
  389.             {
  390.                 ProjectConfigAndTargetCombination StubCombination = new ProjectConfigAndTargetCombination(UnrealTargetPlatform.Unknown, UnrealTargetConfiguration.Unknown, StubProjectPlatformName, StubProjectConfigurationName, null);
  391.                 ProjectConfigAndTargetCombinations.Add(StubCombination);
  392.             }
  393.             else
  394.             {
  395.                 // Figure out all the desired configurations
  396.                 foreach (var Configuration in InConfigurations)
  397.                 {
  398.                     //@todo.Rocket: Put this in a commonly accessible place?
  399.                     if (UnrealBuildTool.IsValidConfiguration(Configuration) == false)
  400.                     {
  401.                         continue;
  402.                     }
  403.                     foreach (var Platform in InPlatforms)
  404.                     {
  405.                         if (UnrealBuildTool.IsValidPlatform(Platform) == false)
  406.                         {
  407.                             continue;
  408.                         }
  409.                         var BuildPlatform = UEBuildPlatform.GetBuildPlatform(Platform, true);
  410.                         if ((BuildPlatform != null) && (BuildPlatform.HasRequiredSDKsInstalled() == SDKStatus.Valid))
  411.                         {
  412.                             // Now go through all of the target types for this project
  413.                             if( ProjectTargets.Count == 0 )
  414.                             {
  415.                                 throw new BuildException( "Expecting at least one ProjectTarget to be associated with project '{0}' in the TargetProjects list ", ProjectFilePath );
  416.                             }
  417.  
  418.                             foreach( var ProjectTarget in ProjectTargets )
  419.                             {
  420.                                 if(IsValidProjectPlatformAndConfiguration( ProjectTarget, Platform, Configuration ))
  421.                                 {
  422.                                     string ProjectPlatformName, ProjectConfigurationName;
  423.                                     MakeProjectPlatformAndConfigurationNames(Platform, Configuration, ProjectTarget.TargetRules.ConfigurationName, out ProjectPlatformName, out ProjectConfigurationName);
  424.  
  425.                                     ProjectConfigAndTargetCombination Combination = new ProjectConfigAndTargetCombination(Platform, Configuration, ProjectPlatformName, ProjectConfigurationName, ProjectTarget);
  426.                                     ProjectConfigAndTargetCombinations.Add( Combination );
  427.                                 }
  428.                             }
  429.                         }
  430.                     }
  431.                 }
  432.             }
  433.  
  434.             VCProjectFileContent.Append(
  435.                 "   <ItemGroup Label=\"ProjectConfigurations\">" + ProjectFileGenerator.NewLine);
  436.  
  437.             // Make a list of the platforms and configs as project-format names
  438.             var ProjectPlatforms = new List<UnrealTargetPlatform>();
  439.             var ProjectPlatformNameAndPlatforms = new List<Tuple<string, UnrealTargetPlatform>>();  // ProjectPlatformName, Platform
  440.             var ProjectConfigurationNameAndConfigurations = new List<Tuple<string, UnrealTargetConfiguration>>();   // ProjectConfigurationName, Configuration
  441.             foreach ( var Combination in ProjectConfigAndTargetCombinations )
  442.             {
  443.                 if( !ProjectPlatforms.Contains( Combination.Platform ) )
  444.                 {
  445.                     ProjectPlatforms.Add( Combination.Platform );
  446.                 }
  447.                 if( !ProjectPlatformNameAndPlatforms.Any( ProjectPlatformNameAndPlatformTuple => ProjectPlatformNameAndPlatformTuple.Item1 == Combination.ProjectPlatformName ) )
  448.                 {
  449.                     ProjectPlatformNameAndPlatforms.Add( Tuple.Create( Combination.ProjectPlatformName, Combination.Platform ) );
  450.                 }
  451.                 if( !ProjectConfigurationNameAndConfigurations.Any( ProjectConfigurationNameAndConfigurationTuple => ProjectConfigurationNameAndConfigurationTuple.Item1 == Combination.ProjectConfigurationName ) )
  452.                 {
  453.                     ProjectConfigurationNameAndConfigurations.Add( Tuple.Create( Combination.ProjectConfigurationName, Combination.Configuration ) );
  454.                 }
  455.             }
  456.  
  457.             // Output ALL the project's config-platform permutations (project files MUST do this)
  458.             foreach( var ConfigurationTuple in ProjectConfigurationNameAndConfigurations )
  459.             {
  460.                 var ProjectConfigurationName = ConfigurationTuple.Item1;
  461.                 foreach( var PlatformTuple in ProjectPlatformNameAndPlatforms )
  462.                 {
  463.                     var ProjectPlatformName = PlatformTuple.Item1;
  464.                     VCProjectFileContent.Append(
  465.                             "       <ProjectConfiguration Include=\"" + ProjectConfigurationName + "|" + ProjectPlatformName + "\">" + ProjectFileGenerator.NewLine +
  466.                             "           <Configuration>" + ProjectConfigurationName + "</Configuration>" + ProjectFileGenerator.NewLine +
  467.                             "           <Platform>" + ProjectPlatformName + "</Platform>" + ProjectFileGenerator.NewLine +
  468.                             "       </ProjectConfiguration>" + ProjectFileGenerator.NewLine);
  469.                 }              
  470.             }
  471.  
  472.             VCProjectFileContent.Append(
  473.                 "   </ItemGroup>" + ProjectFileGenerator.NewLine);
  474.  
  475.             VCFiltersFileContent.Append(
  476.                 "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + ProjectFileGenerator.NewLine +
  477.                 ProjectFileGenerator.NewLine +
  478.                 "<Project ToolsVersion=\"" + VCProjectFileGenerator.ProjectFileToolVersionString + "\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">" + ProjectFileGenerator.NewLine);
  479.  
  480.             // Platform specific PropertyGroups, etc.
  481.             StringBuilder AdditionalPropertyGroups = new StringBuilder();
  482.             if (!IsStubProject)
  483.             {
  484.                 foreach (var Platform in ProjectPlatforms)
  485.                 {
  486.                     UEPlatformProjectGenerator ProjGenerator = UEPlatformProjectGenerator.GetPlatformProjectGenerator(Platform, true);
  487.                     if (ProjGenerator != null && ProjGenerator.HasVisualStudioSupport(Platform, UnrealTargetConfiguration.Development))
  488.                     {
  489.                         AdditionalPropertyGroups.Append(ProjGenerator.GetAdditionalVisualStudioPropertyGroups(Platform));
  490.                     }
  491.                 }
  492.  
  493.                 VCProjectFileContent.Append( AdditionalPropertyGroups );
  494.             }
  495.  
  496.             // Project globals (project GUID, project type, SCC bindings, etc)
  497.             {
  498.                 VCProjectFileContent.Append(
  499.                     "   <PropertyGroup Label=\"Globals\">" + ProjectFileGenerator.NewLine +
  500.                     "       <ProjectGuid>" + ProjectGUID.ToString("B").ToUpperInvariant() + "</ProjectGuid>" + ProjectFileGenerator.NewLine +
  501.                     "       <Keyword>MakeFileProj</Keyword>" + ProjectFileGenerator.NewLine +
  502.                     "       <RootNamespace>" + ProjectName + "</RootNamespace>" + ProjectFileGenerator.NewLine);
  503.  
  504.                 VCProjectFileContent.Append(
  505.                     "   </PropertyGroup>" + ProjectFileGenerator.NewLine);
  506.             }
  507.  
  508.             VCProjectFileContent.Append(
  509.                 "   <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />" + ProjectFileGenerator.NewLine);
  510.  
  511.  
  512.             // Write each project configuration PreDefaultProps section
  513.             foreach (var ConfigurationTuple in ProjectConfigurationNameAndConfigurations)
  514.             {
  515.                 var ProjectConfigurationName = ConfigurationTuple.Item1;
  516.                 var TargetConfiguration = ConfigurationTuple.Item2;
  517.                 foreach (var PlatformTuple in ProjectPlatformNameAndPlatforms)
  518.                 {
  519.                     var ProjectPlatformName = PlatformTuple.Item1;
  520.                     var TargetPlatform = PlatformTuple.Item2;
  521.                     WritePreDefaultPropsConfiguration(TargetPlatform, TargetConfiguration, ProjectPlatformName, ProjectConfigurationName, VCProjectFileContent);
  522.                 }
  523.             }
  524.  
  525.  
  526.             VCProjectFileContent.Append(
  527.                 "   <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />" + ProjectFileGenerator.NewLine +
  528.                 "   <ImportGroup Label=\"ExtensionSettings\" />" + ProjectFileGenerator.NewLine +
  529.                 "   <PropertyGroup Label=\"UserMacros\" />" + ProjectFileGenerator.NewLine
  530.                 );
  531.  
  532.             // Write each project configuration
  533.             foreach( var Combination in ProjectConfigAndTargetCombinations )
  534.             {
  535.                 WriteConfiguration( ProjectName, Combination, VCProjectFileContent, bGenerateUserFileContent? VCUserFileContent : null );
  536.             }
  537.  
  538.             // For Rocket, include engine source in the source search paths. We never build it locally, so the debugger can't find it.
  539.             if(UnrealBuildTool.RunningRocket() && !IsStubProject)
  540.             {
  541.                 VCProjectFileContent.Append("   <PropertyGroup>" + ProjectFileGenerator.NewLine);
  542.                 VCProjectFileContent.Append("       <SourcePath>");
  543.                 foreach(string DirectoryName in Directory.EnumerateDirectories(Path.GetFullPath(Path.Combine(ProjectFileGenerator.EngineRelativePath, "Source")), "*", SearchOption.AllDirectories))
  544.                 {
  545.                     if(Directory.EnumerateFiles(DirectoryName, "*.cpp").Any())
  546.                     {
  547.                         VCProjectFileContent.Append(DirectoryName);
  548.                         VCProjectFileContent.Append(";");
  549.                     }
  550.                 }
  551.                 VCProjectFileContent.Append("</SourcePath>" + ProjectFileGenerator.NewLine);
  552.                 VCProjectFileContent.Append("   </PropertyGroup>" + ProjectFileGenerator.NewLine);
  553.             }
  554.  
  555.             // Write IntelliSense info
  556.             {
  557.                 // @todo projectfiles: Currently we are storing defines/include paths for ALL configurations rather than using ConditionString and storing
  558.                 //      this data uniquely for each target configuration.  IntelliSense may behave better if we did that, but it will result in a LOT more
  559.                 //      data being stored into the project file, and might make the IDE perform worse when switching configurations!
  560.                 VCProjectFileContent.Append(
  561.                     "   <PropertyGroup>" + ProjectFileGenerator.NewLine +
  562.                     "       <NMakePreprocessorDefinitions>$(NMakePreprocessorDefinitions)" + ( VCPreprocessorDefinitions.Length > 0 ? ( ";" + VCPreprocessorDefinitions ) : "" ) + "</NMakePreprocessorDefinitions>" + ProjectFileGenerator.NewLine +
  563.                     "       <NMakeIncludeSearchPath>$(NMakeIncludeSearchPath)" + ( VCIncludeSearchPaths.Length > 0 ? ( ";" + VCIncludeSearchPaths ) : "" ) + "</NMakeIncludeSearchPath>" + ProjectFileGenerator.NewLine +
  564.                     "       <NMakeForcedIncludes>$(NMakeForcedIncludes)</NMakeForcedIncludes>" + ProjectFileGenerator.NewLine +
  565.                     "       <NMakeAssemblySearchPath>$(NMakeAssemblySearchPath)</NMakeAssemblySearchPath>" + ProjectFileGenerator.NewLine +
  566.                     "       <NMakeForcedUsingAssemblies>$(NMakeForcedUsingAssemblies)</NMakeForcedUsingAssemblies>" + ProjectFileGenerator.NewLine +
  567.                     "   </PropertyGroup>" + ProjectFileGenerator.NewLine );
  568.             }
  569.  
  570.             // look for additional import lines for all platforms for non stub projects
  571.             StringBuilder AdditionalImportSettings = new StringBuilder();
  572.             if (!IsStubProject)
  573.             {
  574.                 foreach (var Platform in ProjectPlatforms)
  575.                 {
  576.                     UEPlatformProjectGenerator ProjGenerator = UEPlatformProjectGenerator.GetPlatformProjectGenerator(Platform, true);
  577.                     if (ProjGenerator != null && ProjGenerator.HasVisualStudioSupport(Platform, UnrealTargetConfiguration.Development))
  578.                     {
  579.                         AdditionalImportSettings.Append(ProjGenerator.GetAdditionalVisualStudioImportSettings(Platform));
  580.                     }
  581.                 }
  582.             }
  583.  
  584.             string OutputManifestString = "";
  585.             if (!IsStubProject)
  586.             {
  587.                 foreach (var Platform in ProjectPlatforms)
  588.                 {
  589.                     UEPlatformProjectGenerator ProjGenerator = UEPlatformProjectGenerator.GetPlatformProjectGenerator(Platform, true);
  590.                     if (ProjGenerator != null && ProjGenerator.HasVisualStudioSupport(Platform, UnrealTargetConfiguration.Development))
  591.                     {
  592.                         // @todo projectfiles: Serious hacks here because we are trying to emit one-time platform-specific sections that need information
  593.                         //    about a target type, but the project file may contain many types of targets!  Some of this logic will need to move into
  594.                         //    the per-target configuration writing code.
  595.                         var HackTargetType = TargetRules.TargetType.Game;
  596.                         string HackTargetFilePath = null;
  597.                         foreach( var Combination in ProjectConfigAndTargetCombinations )
  598.                         {
  599.                             if( Combination.Platform == Platform &&
  600.                                 Combination.ProjectTarget.TargetRules != null &&
  601.                                 Combination.ProjectTarget.TargetRules.Type == HackTargetType )
  602.                             {
  603.                                 HackTargetFilePath = Combination.ProjectTarget.TargetFilePath;// ProjectConfigAndTargetCombinations[0].ProjectTarget.TargetFilePath;
  604.                                 break;                                     
  605.                             }
  606.                         }
  607.  
  608.                         if( !String.IsNullOrEmpty( HackTargetFilePath ) )
  609.                         {
  610.                             OutputManifestString += ProjGenerator.GetVisualStudioOutputManifestSection(Platform, HackTargetType, HackTargetFilePath, ProjectFilePath);
  611.                         }
  612.                     }
  613.                 }
  614.             }
  615.  
  616.             VCProjectFileContent.Append(
  617.                     OutputManifestString +  // output manifest must come before the Cpp.targets file.
  618.                     "   <ItemDefinitionGroup>" + ProjectFileGenerator.NewLine +
  619.                     "   </ItemDefinitionGroup>" + ProjectFileGenerator.NewLine);
  620.  
  621.             // Source folders and files
  622.             {
  623.                 var LocalAliasedFiles = new List<AliasedFile>(AliasedFiles);
  624.  
  625.                 foreach (var CurFile in SourceFiles)
  626.                 {
  627.                     // We want all source file and directory paths in the project files to be relative to the project file's
  628.                     // location on the disk.  Convert the path to be relative to the project file directory
  629.                     var ProjectRelativeSourceFile = Utils.MakePathRelativeTo(CurFile.FilePath, Path.GetDirectoryName(ProjectFilePath));
  630.  
  631.                     // By default, files will appear relative to the project file in the solution.  This is kind of the normal Visual
  632.                     // Studio way to do things, but because our generated project files are emitted to intermediate folders, if we always
  633.                     // did this it would yield really ugly paths int he solution explorer
  634.                     string FilterRelativeSourceDirectory = Path.GetDirectoryName(ProjectRelativeSourceFile);
  635.  
  636.                     // Use the specified relative base folder
  637.                     if (CurFile.RelativeBaseFolder != null) // NOTE: We are looking for null strings, not empty strings!
  638.                     {
  639.                         FilterRelativeSourceDirectory = Path.GetDirectoryName(Utils.MakePathRelativeTo(CurFile.FilePath, CurFile.RelativeBaseFolder));
  640.                     }
  641.  
  642.                     LocalAliasedFiles.Add(new AliasedFile(ProjectRelativeSourceFile, FilterRelativeSourceDirectory));
  643.                 }
  644.  
  645.                 VCFiltersFileContent.Append(
  646.                     "   <ItemGroup>" + ProjectFileGenerator.NewLine);
  647.  
  648.                 VCProjectFileContent.Append(
  649.                     "   <ItemGroup>" + ProjectFileGenerator.NewLine);
  650.  
  651.                 // Add all file directories to the filters file as solution filters
  652.                 var FilterDirectories = new HashSet<string>();
  653.                 foreach (var AliasedFile in LocalAliasedFiles)
  654.                 {
  655.                     // No need to add the root directory relative to the project (it would just be an empty string!)
  656.                     if (!String.IsNullOrWhiteSpace(AliasedFile.ProjectPath))
  657.                     {
  658.                         FiltersFileIsNeeded = EnsureFilterPathExists(AliasedFile.ProjectPath, VCFiltersFileContent, FilterDirectories);
  659.                     }
  660.  
  661.                     var VCFileType = GetVCFileType(AliasedFile.FileSystemPath);
  662.  
  663.                     VCProjectFileContent.Append(
  664.                         "       <" + VCFileType + " Include=\"" + AliasedFile.FileSystemPath + "\" />" + ProjectFileGenerator.NewLine);
  665.  
  666.                     if (!String.IsNullOrWhiteSpace(AliasedFile.ProjectPath))
  667.                     {
  668.                         VCFiltersFileContent.Append(
  669.                             "       <" + VCFileType + " Include=\"" + AliasedFile.FileSystemPath + "\">" + ProjectFileGenerator.NewLine +
  670.                             "           <Filter>" + Utils.CleanDirectorySeparators(AliasedFile.ProjectPath) + "</Filter>" + ProjectFileGenerator.NewLine +
  671.                             "       </" + VCFileType + " >" + ProjectFileGenerator.NewLine);
  672.  
  673.                         FiltersFileIsNeeded = true;
  674.                     }
  675.                     else
  676.                     {
  677.                         // No need to specify the root directory relative to the project (it would just be an empty string!)
  678.                         VCFiltersFileContent.Append(
  679.                             "       <" + VCFileType + " Include=\"" + AliasedFile.FileSystemPath + "\" />" + ProjectFileGenerator.NewLine);
  680.                     }
  681.                 }
  682.  
  683.                 VCProjectFileContent.Append(
  684.                     "   </ItemGroup>" + ProjectFileGenerator.NewLine);
  685.  
  686.                 VCFiltersFileContent.Append(
  687.                     "   </ItemGroup>" + ProjectFileGenerator.NewLine);
  688.             }
  689.  
  690.  
  691.             VCProjectFileContent.Append(
  692.                     "   <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />" + ProjectFileGenerator.NewLine +
  693.                     AdditionalImportSettings.ToString() +
  694.                     "   <ImportGroup Label=\"ExtensionTargets\">" + ProjectFileGenerator.NewLine +
  695.                     "   </ImportGroup>" + ProjectFileGenerator.NewLine +
  696.                     "</Project>" + ProjectFileGenerator.NewLine );
  697.  
  698.             VCFiltersFileContent.Append(
  699.                 "</Project>" + ProjectFileGenerator.NewLine );
  700.  
  701.             if (bGenerateUserFileContent)
  702.             {
  703.                 VCUserFileContent.Append(
  704.                     "</Project>" + ProjectFileGenerator.NewLine
  705.                     );
  706.             }
  707.  
  708.             // Save the project file
  709.             if( bSuccess )
  710.             {
  711.                 bSuccess = ProjectFileGenerator.WriteFileIfChanged( ProjectFilePath, VCProjectFileContent.ToString() );
  712.             }
  713.  
  714.  
  715.             // Save the filters file
  716.             if( bSuccess )
  717.             {
  718.                 // Create a path to the project file's filters file
  719.                 var VCFiltersFilePath = ProjectFilePath + ".filters";
  720.                 if( FiltersFileIsNeeded )
  721.                 {
  722.                     bSuccess = ProjectFileGenerator.WriteFileIfChanged( VCFiltersFilePath, VCFiltersFileContent.ToString() );
  723.                 }
  724.                 else
  725.                 {
  726.                     Log.TraceVerbose( "Deleting Visual C++ filters file which is no longer needed: " + VCFiltersFilePath );
  727.  
  728.                     // Delete the filters file, if one exists.  We no longer need it
  729.                     try
  730.                     {
  731.                         File.Delete( VCFiltersFilePath );
  732.                     }
  733.                     catch( Exception )
  734.                     {
  735.                         Log.TraceInformation( "Error deleting filters file (file may not be writable): " + VCFiltersFilePath );
  736.                     }
  737.                 }
  738.             }
  739.  
  740.             // Save the user file, if required
  741.             if (VCUserFileContent.Length > 0)
  742.             {
  743.                 // Create a path to the project file's user file
  744.                 var VCUserFilePath = ProjectFilePath + ".user";
  745.                 // Never overwrite the existing user path as it will cause them to lose their settings
  746.                 if (File.Exists(VCUserFilePath) == false)
  747.                 {
  748.                     bSuccess = ProjectFileGenerator.WriteFileIfChanged(VCUserFilePath, VCUserFileContent.ToString());
  749.                 }
  750.             }
  751.  
  752.             return bSuccess;
  753.         }
  754.  
  755.         private static bool EnsureFilterPathExists(string FilterRelativeSourceDirectory, StringBuilder VCFiltersFileContent, HashSet<string> FilterDirectories)
  756.         {
  757.             // We only want each directory to appear once in the filters file
  758.             var PathRemaining = Utils.CleanDirectorySeparators( FilterRelativeSourceDirectory );
  759.             var FiltersFileIsNeeded = false;
  760.             if( !FilterDirectories.Contains( PathRemaining ) )
  761.             {
  762.                 // Make sure all subdirectories leading up to this directory each have their own filter, too!
  763.                 var AllDirectoriesInPath = new List<string>();
  764.                 var PathSoFar = "";
  765.                 for( ; ; )
  766.                 {
  767.                     if( PathRemaining.Length > 0 )
  768.                     {
  769.                         var SlashIndex = PathRemaining.IndexOf( Path.DirectorySeparatorChar );
  770.                         string SplitDirectory;
  771.                         if( SlashIndex != -1 )
  772.                         {
  773.                             SplitDirectory = PathRemaining.Substring( 0, SlashIndex );
  774.                             PathRemaining = PathRemaining.Substring( SplitDirectory.Length + 1 );
  775.                         }
  776.                         else
  777.                         {
  778.                             SplitDirectory = PathRemaining;
  779.                             PathRemaining = "";
  780.                         }
  781.                         if( !String.IsNullOrEmpty( PathSoFar ) )
  782.                         {
  783.                             PathSoFar += Path.DirectorySeparatorChar;
  784.                         }
  785.                         PathSoFar += SplitDirectory;
  786.  
  787.                         AllDirectoriesInPath.Add( PathSoFar );
  788.                     }
  789.                     else
  790.                     {
  791.                         break;
  792.                     }
  793.                 }
  794.  
  795.                 foreach( var LeadingDirectory in AllDirectoriesInPath )
  796.                 {
  797.                     if( !FilterDirectories.Contains( LeadingDirectory ) )
  798.                     {
  799.                         FilterDirectories.Add( LeadingDirectory );
  800.  
  801.                         // Generate a unique GUID for this folder
  802.                         // NOTE: When saving generated project files, we ignore differences in GUIDs if every other part of the file
  803.                         //       matches identically with the pre-existing file
  804.                         var FilterGUID = Guid.NewGuid().ToString( "B" ).ToUpperInvariant();
  805.  
  806.                         VCFiltersFileContent.Append(
  807.                             "       <Filter Include=\"" + LeadingDirectory + "\">" + ProjectFileGenerator.NewLine +
  808.                             "           <UniqueIdentifier>" + FilterGUID + "</UniqueIdentifier>" + ProjectFileGenerator.NewLine +
  809.                             "       </Filter>" + ProjectFileGenerator.NewLine);
  810.  
  811.                         FiltersFileIsNeeded = true;
  812.                     }
  813.                 }
  814.             }
  815.  
  816.             return FiltersFileIsNeeded;
  817.         }
  818.  
  819.         /// <summary>
  820.         /// Returns the VCFileType element name based on the file path.
  821.         /// </summary>
  822.         /// <param name="Path">The path of the file to return type for.</param>
  823.         /// <returns>Name of the element in MSBuild project file for this file.</returns>
  824.         private string GetVCFileType(string Path)
  825.         {
  826.             // What type of file is this?
  827.             if (Path.EndsWith(".h", StringComparison.InvariantCultureIgnoreCase) ||
  828.                 Path.EndsWith(".inl", StringComparison.InvariantCultureIgnoreCase))
  829.             {
  830.                 return "ClInclude";
  831.             }
  832.             else if (Path.EndsWith(".cpp", StringComparison.InvariantCultureIgnoreCase))
  833.             {
  834.                 return "ClCompile";
  835.             }
  836.             else if (Path.EndsWith(".rc", StringComparison.InvariantCultureIgnoreCase))
  837.             {
  838.                 return "ResourceCompile";
  839.             }
  840.             else if (Path.EndsWith(".manifest", StringComparison.InvariantCultureIgnoreCase))
  841.             {
  842.                 return "Manifest";
  843.             }
  844.             else
  845.             {
  846.                 return "None";
  847.             }
  848.         }
  849.  
  850.         // Anonymous function that writes pre-Default.props configuration data
  851.         private void WritePreDefaultPropsConfiguration(UnrealTargetPlatform TargetPlatform, UnrealTargetConfiguration TargetConfiguration, string ProjectPlatformName, string ProjectConfigurationName, StringBuilder VCProjectFileContent)
  852.         {
  853.             UEPlatformProjectGenerator ProjGenerator = UEPlatformProjectGenerator.GetPlatformProjectGenerator(TargetPlatform, true);
  854.             if (((ProjGenerator == null) && (TargetPlatform != UnrealTargetPlatform.Unknown)))
  855.             {
  856.                 return;
  857.             }
  858.  
  859.             var ProjectConfigurationAndPlatformName = ProjectConfigurationName + "|" + ProjectPlatformName;
  860.             string ConditionString = "Condition=\"'$(Configuration)|$(Platform)'=='" + ProjectConfigurationAndPlatformName + "'\"";
  861.  
  862.             string PlatformToolsetString = (ProjGenerator != null) ? ProjGenerator.GetVisualStudioPlatformToolsetString(TargetPlatform, TargetConfiguration, this) : "";
  863.             if( String.IsNullOrEmpty( PlatformToolsetString ) )
  864.             {
  865.                 PlatformToolsetString = "       <PlatformToolset>" + VCProjectFileGenerator.ProjectFilePlatformToolsetVersionString + "</PlatformToolset>" + ProjectFileGenerator.NewLine;
  866.             }
  867.  
  868.             string PlatformConfigurationType = (ProjGenerator == null)? "Makefile" : ProjGenerator.GetVisualStudioPlatformConfigurationType(TargetPlatform);   
  869.             VCProjectFileContent.Append(
  870.                 "   <PropertyGroup " + ConditionString + " Label=\"Configuration\">" + ProjectFileGenerator.NewLine +
  871.                 "       <ConfigurationType>" + PlatformConfigurationType + "</ConfigurationType>" + ProjectFileGenerator.NewLine +
  872.                         PlatformToolsetString +
  873.                 "   </PropertyGroup>" + ProjectFileGenerator.NewLine
  874.                 );
  875.         }
  876.  
  877.         // Anonymous function that writes project configuration data
  878.         private void WriteConfiguration(string ProjectName, ProjectConfigAndTargetCombination Combination, StringBuilder VCProjectFileContent, StringBuilder VCUserFileContent)
  879.         {
  880.             UnrealTargetPlatform Platform = Combination.Platform;
  881.             UnrealTargetConfiguration Configuration = Combination.Configuration;
  882.  
  883.             UEPlatformProjectGenerator ProjGenerator = UEPlatformProjectGenerator.GetPlatformProjectGenerator(Platform, true);
  884.             if (((ProjGenerator == null) && (Platform != UnrealTargetPlatform.Unknown)))
  885.             {
  886.                 return;
  887.             }
  888.    
  889.             string UProjectPath = "";
  890.             if (IsForeignProject)
  891.             {
  892.                 UProjectPath = "\"$(SolutionDir)$(ProjectName).uproject\"";
  893.             }
  894.  
  895.             string ConditionString = "Condition=\"'$(Configuration)|$(Platform)'=='" + Combination.ProjectConfigurationAndPlatformName + "'\"";
  896.  
  897.             {
  898.                 VCProjectFileContent.Append(
  899.                     "   <ImportGroup " + ConditionString + " Label=\"PropertySheets\">" + ProjectFileGenerator.NewLine +
  900.                     "       <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />" + ProjectFileGenerator.NewLine +
  901.                     "   </ImportGroup>" + ProjectFileGenerator.NewLine);
  902.  
  903.                 if (IsStubProject)
  904.                 {
  905.                     string ProjectRelativeUnusedDirectory = NormalizeProjectPath(Path.Combine(ProjectFileGenerator.EngineRelativePath, BuildConfiguration.BaseIntermediateFolder, "Unused"));
  906.  
  907.                     VCProjectFileContent.Append(
  908.                         "   <PropertyGroup " + ConditionString + ">" + ProjectFileGenerator.NewLine +
  909.                         "       <OutDir>" + ProjectRelativeUnusedDirectory + Path.DirectorySeparatorChar + "</OutDir>" + ProjectFileGenerator.NewLine +
  910.                         "       <IntDir>" + ProjectRelativeUnusedDirectory + Path.DirectorySeparatorChar + "</IntDir>" + ProjectFileGenerator.NewLine +
  911.                         "       <NMakeBuildCommandLine>@rem Nothing to do.</NMakeBuildCommandLine>" + ProjectFileGenerator.NewLine +
  912.                         "       <NMakeReBuildCommandLine>@rem Nothing to do.</NMakeReBuildCommandLine>" + ProjectFileGenerator.NewLine +
  913.                         "       <NMakeCleanCommandLine>@rem Nothing to do.</NMakeCleanCommandLine>" + ProjectFileGenerator.NewLine +
  914.                         "       <NMakeOutput/>" + ProjectFileGenerator.NewLine +
  915.                         "   </PropertyGroup>" + ProjectFileGenerator.NewLine);
  916.                 }
  917.                 else if(ProjectFileGenerator.bGeneratingRocketProjectFiles && Combination.ProjectTarget != null && Combination.ProjectTarget.TargetRules != null && !Combination.ProjectTarget.TargetRules.SupportsPlatform(Combination.Platform))
  918.                 {
  919.                     List<UnrealTargetPlatform> SupportedPlatforms = new List<UnrealTargetPlatform>();
  920.                     Combination.ProjectTarget.TargetRules.GetSupportedPlatforms(ref SupportedPlatforms);
  921.  
  922.                     string ProjectRelativeUnusedDirectory = NormalizeProjectPath(Path.Combine(ProjectFileGenerator.EngineRelativePath, BuildConfiguration.BaseIntermediateFolder, "Unused"));
  923.  
  924.                     VCProjectFileContent.AppendFormat(
  925.                         "   <PropertyGroup " + ConditionString + ">" + ProjectFileGenerator.NewLine +
  926.                         "       <OutDir>" + ProjectRelativeUnusedDirectory + Path.DirectorySeparatorChar + "</OutDir>" + ProjectFileGenerator.NewLine +
  927.                         "       <IntDir>" + ProjectRelativeUnusedDirectory + Path.DirectorySeparatorChar + "</IntDir>" + ProjectFileGenerator.NewLine +
  928.                         "       <NMakeBuildCommandLine>@echo {0} is not a supported platform for {1}. Valid platforms are {2}.</NMakeBuildCommandLine>" + ProjectFileGenerator.NewLine +
  929.                         "       <NMakeReBuildCommandLine>@echo {0} is not a supported platform for {1}. Valid platforms are {2}.</NMakeReBuildCommandLine>" + ProjectFileGenerator.NewLine +
  930.                         "       <NMakeCleanCommandLine>@echo {0} is not a supported platform for {1}. Valid platforms are {2}.</NMakeCleanCommandLine>" + ProjectFileGenerator.NewLine +
  931.                         "       <NMakeOutput/>" + ProjectFileGenerator.NewLine +
  932.                         "   </PropertyGroup>" + ProjectFileGenerator.NewLine, Combination.Platform, Utils.GetFilenameWithoutAnyExtensions(Combination.ProjectTarget.TargetFilePath), String.Join(", ", SupportedPlatforms.Select(x => x.ToString())));
  933.                 }
  934.                 else
  935.                 {
  936.                     TargetRules TargetRulesObject = Combination.ProjectTarget.TargetRules;
  937.                     string TargetFilePath = Combination.ProjectTarget.TargetFilePath;
  938.                     string TargetName = Utils.GetFilenameWithoutAnyExtensions(TargetFilePath);
  939.                     var UBTPlatformName = IsStubProject ? StubProjectPlatformName : Platform.ToString();
  940.                     var UBTConfigurationName = IsStubProject ? StubProjectConfigurationName : Configuration.ToString();
  941.  
  942.                     // Setup output path
  943.                     var BuildPlatform = UEBuildPlatform.GetBuildPlatform(Platform);
  944.  
  945.                     // Figure out if this is a monolithic build
  946.                     bool bShouldCompileMonolithic = BuildPlatform.ShouldCompileMonolithicBinary(Platform);
  947.                     bShouldCompileMonolithic |= TargetRulesObject.ShouldCompileMonolithic(Platform, Configuration);
  948.  
  949.                     // Get the output directory
  950.                     string EngineRootDirectory = Path.GetFullPath(ProjectFileGenerator.EngineRelativePath);
  951.                     string RootDirectory = EngineRootDirectory;
  952.                     if ((TargetRules.IsAGame(TargetRulesObject.Type) || TargetRulesObject.Type == TargetRules.TargetType.Server) && bShouldCompileMonolithic && !TargetRulesObject.bOutputToEngineBinaries)
  953.                     {
  954.                         if (UnrealBuildTool.HasUProjectFile() && Utils.IsFileUnderDirectory(TargetFilePath, UnrealBuildTool.GetUProjectPath()))
  955.                         {
  956.                             RootDirectory = Path.GetFullPath(UnrealBuildTool.GetUProjectPath());
  957.                         }
  958.                         else
  959.                         {
  960.                             string UnrealProjectPath = UProjectInfo.GetProjectFilePath(ProjectName);
  961.                             if (!String.IsNullOrEmpty(UnrealProjectPath))
  962.                             {
  963.                                 RootDirectory = Path.GetDirectoryName(Path.GetFullPath(UnrealProjectPath));
  964.                             }
  965.                         }
  966.                     }
  967.  
  968.                     if(TargetRulesObject.Type == TargetRules.TargetType.Program && !TargetRulesObject.bOutputToEngineBinaries)
  969.                     {
  970.                         string UnrealProjectPath = UProjectInfo.GetProjectForTarget(TargetName);
  971.                         if (!String.IsNullOrEmpty(UnrealProjectPath))
  972.                         {
  973.                             RootDirectory = Path.GetDirectoryName(Path.GetFullPath(UnrealProjectPath));
  974.                         }
  975.                     }
  976.  
  977.                     // Get the output directory
  978.                     string OutputDirectory = Path.Combine(RootDirectory, "Binaries", UBTPlatformName);
  979.  
  980.                     // Get the executable name (minus any platform or config suffixes)
  981.                     string BaseExeName = TargetName;
  982.                     if (!bShouldCompileMonolithic && TargetRulesObject.Type != TargetRules.TargetType.Program)
  983.                     {
  984.                         // Figure out what the compiled binary will be called so that we can point the IDE to the correct file
  985.                         string TargetConfigurationName = TargetRulesObject.ConfigurationName;
  986.                         if (TargetConfigurationName != TargetRules.TargetType.Game.ToString() && TargetConfigurationName != TargetRules.TargetType.Program.ToString())
  987.                         {
  988.                             BaseExeName = "UE4" + TargetConfigurationName;
  989.                         }
  990.                     }
  991.  
  992.                     // Make the output file path
  993.                     string NMakePath = Path.Combine(OutputDirectory, BaseExeName);
  994.                     if (Configuration != UnrealTargetConfiguration.Development && (Configuration != UnrealTargetConfiguration.DebugGame || bShouldCompileMonolithic))
  995.                     {
  996.                         NMakePath += "-" + UBTPlatformName + "-" + UBTConfigurationName;
  997.                     }
  998.                     NMakePath += BuildPlatform.GetActiveArchitecture();
  999.                     NMakePath += BuildPlatform.GetBinaryExtension(UEBuildBinaryType.Executable);
  1000.                     NMakePath = (BuildPlatform as UEBuildPlatform).ModifyNMakeOutput(NMakePath);
  1001.  
  1002.                     VCProjectFileContent.Append(
  1003.                         "   <PropertyGroup " + ConditionString + ">" + ProjectFileGenerator.NewLine);
  1004.  
  1005.                     string PathStrings = (ProjGenerator != null) ? ProjGenerator.GetVisualStudioPathsEntries(Platform, Configuration, TargetRulesObject.Type, TargetFilePath, ProjectFilePath, NMakePath) : "";
  1006.                     if (string.IsNullOrEmpty(PathStrings) || (PathStrings.Contains("<IntDir>") == false))
  1007.                     {
  1008.                         string ProjectRelativeUnusedDirectory = "$(ProjectDir)..\\Build\\Unused";
  1009.                         VCProjectFileContent.Append(
  1010.                             PathStrings +
  1011.                             "       <OutDir>" + ProjectRelativeUnusedDirectory + Path.DirectorySeparatorChar + "</OutDir>" + ProjectFileGenerator.NewLine +
  1012.                             "       <IntDir>" + ProjectRelativeUnusedDirectory + Path.DirectorySeparatorChar + "</IntDir>" + ProjectFileGenerator.NewLine);
  1013.                     }
  1014.                     else
  1015.                     {
  1016.                         VCProjectFileContent.Append(PathStrings);
  1017.                     }
  1018.  
  1019.                     if (TargetRules.IsGameType(TargetRulesObject.Type) &&
  1020.                         (TargetRules.IsEditorType(TargetRulesObject.Type) == false))
  1021.                     {
  1022.                         // Allow platforms to add any special properties they require... like aumid override for Xbox One
  1023.                         UEPlatformProjectGenerator.GenerateGamePlatformSpecificProperties(Platform, Configuration, TargetRulesObject.Type, VCProjectFileContent, RootDirectory, TargetFilePath);
  1024.                     }
  1025.  
  1026.                     // This is the standard UE4 based project NMake build line:
  1027.                     //  ..\..\Build\BatchFiles\Build.bat <TARGETNAME> <PLATFORM> <CONFIGURATION>
  1028.                     //  ie ..\..\Build\BatchFiles\Build.bat BlankProgram Win64 Debug
  1029.  
  1030.                     string BuildArguments = " " + TargetName + " " + UBTPlatformName + " " + UBTConfigurationName;
  1031.                     if(ProjectFileGenerator.bUsePrecompiled)
  1032.                     {
  1033.                         BuildArguments += " -useprecompiled";
  1034.                     }
  1035.                     if (IsForeignProject)
  1036.                     {
  1037.                         BuildArguments += " " + UProjectPath + (UnrealBuildTool.RunningRocket() ? " -rocket" : "");
  1038.                     }
  1039.  
  1040.                     // Always wait for the mutex between UBT invocations, so that building the whole solution doesn't fail.
  1041.                     BuildArguments += " -waitmutex";
  1042.  
  1043.                     string BatchFilesDirectoryName = Path.Combine(ProjectFileGenerator.EngineRelativePath, "Build", "BatchFiles");
  1044.  
  1045.                     // @todo UWP: For the MS toolchains, if an override was set for project generation, push that into the build strings to override the build toolchain as well
  1046.                     string BuildToolOverride = "";
  1047.                     if (UnrealBuildTool.CommandLineContains("-2012"))
  1048.                     {
  1049.                         BuildToolOverride = " -2012";
  1050.                     }
  1051.                     if (UnrealBuildTool.CommandLineContains("-2013"))
  1052.                     {
  1053.                         BuildToolOverride = " -2013";
  1054.                     }
  1055.                     if (UnrealBuildTool.CommandLineContains("-2015"))
  1056.                     {
  1057.                         BuildToolOverride = " -2015";
  1058.                     }
  1059.                     BuildArguments += BuildToolOverride;
  1060.  
  1061.                     // NMake Build command line
  1062.                     VCProjectFileContent.Append("       <NMakeBuildCommandLine>");
  1063.                     VCProjectFileContent.Append(EscapePath(NormalizeProjectPath(Path.Combine(BatchFilesDirectoryName, "Build.bat"))) + BuildArguments.ToString());
  1064.                     VCProjectFileContent.Append("</NMakeBuildCommandLine>" + ProjectFileGenerator.NewLine);
  1065.  
  1066.                     // NMake ReBuild command line
  1067.                     VCProjectFileContent.Append("       <NMakeReBuildCommandLine>");
  1068.                     VCProjectFileContent.Append(EscapePath(NormalizeProjectPath(Path.Combine(BatchFilesDirectoryName, "Rebuild.bat"))) + BuildArguments.ToString());
  1069.                     VCProjectFileContent.Append("</NMakeReBuildCommandLine>" + ProjectFileGenerator.NewLine);
  1070.  
  1071.                     // NMake Clean command line
  1072.                     VCProjectFileContent.Append("       <NMakeCleanCommandLine>");
  1073.                     VCProjectFileContent.Append(EscapePath(NormalizeProjectPath(Path.Combine(BatchFilesDirectoryName, "Clean.bat"))) + BuildArguments.ToString());
  1074.                     VCProjectFileContent.Append("</NMakeCleanCommandLine>" + ProjectFileGenerator.NewLine);
  1075.  
  1076.                     VCProjectFileContent.Append("       <NMakeOutput>");
  1077.                     VCProjectFileContent.Append(NormalizeProjectPath(NMakePath));
  1078.                     VCProjectFileContent.Append("</NMakeOutput>" + ProjectFileGenerator.NewLine);
  1079.                     VCProjectFileContent.Append("   </PropertyGroup>" + ProjectFileGenerator.NewLine);
  1080.  
  1081.                     string LayoutDirString = (ProjGenerator != null) ? ProjGenerator.GetVisualStudioLayoutDirSection(Platform, Configuration, ConditionString, Combination.ProjectTarget.TargetRules.Type, Combination.ProjectTarget.TargetFilePath, ProjectFilePath, NMakePath) : "";
  1082.                     VCProjectFileContent.Append(LayoutDirString);
  1083.                 }
  1084.  
  1085.                 if (VCUserFileContent != null && Combination.ProjectTarget != null)
  1086.                 {
  1087.                     TargetRules TargetRulesObject = Combination.ProjectTarget.TargetRules;
  1088.  
  1089.                     if ((Platform == UnrealTargetPlatform.Win32) || (Platform == UnrealTargetPlatform.Win64) || (Platform == UnrealTargetPlatform.UWP))
  1090.                     {
  1091.                         VCUserFileContent.Append(
  1092.                             "   <PropertyGroup " + ConditionString + ">" + ProjectFileGenerator.NewLine);
  1093.                         if (TargetRulesObject.Type != TargetRules.TargetType.Game)
  1094.                         {
  1095.                             string DebugOptions = "";
  1096.                            
  1097.                             if(IsForeignProject)
  1098.                             {
  1099.                                 DebugOptions += UProjectPath;
  1100.                             }
  1101.                             else if(TargetRulesObject.Type == TargetRules.TargetType.Editor && ProjectName != "UE4")
  1102.                             {
  1103.                                 DebugOptions += ProjectName;
  1104.                             }
  1105.  
  1106.                             if (Configuration == UnrealTargetConfiguration.Debug || Configuration == UnrealTargetConfiguration.DebugGame)
  1107.                             {
  1108.                                 DebugOptions += " -debug";
  1109.                             }
  1110.                             else if (Configuration == UnrealTargetConfiguration.Shipping)
  1111.                             {
  1112.                                 DebugOptions += " -shipping";
  1113.                             }
  1114.  
  1115.                             VCUserFileContent.Append(
  1116.                                 "       <LocalDebuggerCommandArguments>" + DebugOptions + "</LocalDebuggerCommandArguments>" + ProjectFileGenerator.NewLine
  1117.                                 );
  1118.                         }
  1119.                         VCUserFileContent.Append(
  1120.                             "       <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>" + ProjectFileGenerator.NewLine
  1121.                             );
  1122.                         VCUserFileContent.Append(
  1123.                             "   </PropertyGroup>" + ProjectFileGenerator.NewLine
  1124.                             );
  1125.                     }
  1126.  
  1127.                     string PlatformUserFileStrings = (ProjGenerator != null) ? ProjGenerator.GetVisualStudioUserFileStrings(Platform, Configuration, ConditionString, TargetRulesObject, Combination.ProjectTarget.TargetFilePath, ProjectFilePath) : "";
  1128.                     VCUserFileContent.Append(PlatformUserFileStrings);
  1129.                 }
  1130.             }
  1131.         }
  1132.     }
  1133.  
  1134.  
  1135.     /** A Visual C# project. */
  1136.     public class VCSharpProjectFile : MSBuildProjectFile
  1137.     {
  1138.         // This is the GUID that Visual Studio uses to identify a C# project file in the solution
  1139.         public override string ProjectTypeGUID
  1140.         {
  1141.             get { return "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"; }
  1142.         }
  1143.  
  1144.         /// <summary>
  1145.         /// Constructs a new project file object
  1146.         /// </summary>
  1147.         /// <param name="InitFilePath">The path to the project file on disk</param>
  1148.         public VCSharpProjectFile( string InitFilePath )
  1149.             : base( InitFilePath )
  1150.         {
  1151.         }
  1152.  
  1153.  
  1154.         /** Reads the list of dependencies from the specified project file. */
  1155.         public List<string> GetCSharpDependencies()
  1156.         {
  1157.             var RelativeFilePaths = new List<string>();
  1158.             var Doc = new XmlDocument();
  1159.             Doc.Load( ProjectFilePath );
  1160.  
  1161.             var Tags = new string[] { "Compile", "Page", "Resource" };
  1162.             foreach( var Tag in Tags )
  1163.             {
  1164.                 var Elements = Doc.GetElementsByTagName( Tag );
  1165.                 foreach( XmlElement Element in Elements )
  1166.                 {
  1167.                     RelativeFilePaths.Add( Element.GetAttribute( "Include" ) );
  1168.                 }
  1169.             }
  1170.  
  1171.             return RelativeFilePaths;
  1172.         }
  1173.  
  1174.         /**
  1175.          * Adds a C# dot net (system) assembly reference to this project
  1176.          *
  1177.          * @param   AssemblyReference   The full path to the assembly file on disk
  1178.          */
  1179.         public void AddDotNetAssemblyReference(string AssemblyReference)
  1180.         {
  1181.             if (!DotNetAssemblyReferences.Contains(AssemblyReference))
  1182.             {
  1183.                 DotNetAssemblyReferences.Add(AssemblyReference);
  1184.             }
  1185.         }
  1186.  
  1187.         /**
  1188.          * Adds a C# assembly reference to this project, such as a third party assembly needed for this project to compile
  1189.          *
  1190.          * @param   AssemblyReference   The full path to the assembly file on disk
  1191.          */
  1192.         public void AddAssemblyReference( string AssemblyReference )
  1193.         {
  1194.             AssemblyReferences.Add( AssemblyReference );
  1195.         }
  1196.  
  1197.         /// <summary>
  1198.         /// Basic csproj file support. Generates C# library project with one build config.
  1199.         /// </summary>
  1200.         /// <param name="InPlatforms">Not used.</param>
  1201.         /// <param name="InConfigurations">Not Used.</param>
  1202.         /// <returns>true if the opration was successful, false otherwise</returns>
  1203.         public override bool WriteProjectFile(List<UnrealTargetPlatform> InPlatforms, List<UnrealTargetConfiguration> InConfigurations)
  1204.         {
  1205.             bool bSuccess = true;
  1206.  
  1207.             // Setup C# project file content.
  1208.             var ProjectFileContent = new StringBuilder();
  1209.  
  1210.             // Project file header.
  1211.             ProjectFileContent.Append(
  1212.                 "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + ProjectFileGenerator.NewLine +
  1213.                 "<Project DefaultTargets=\"Build\" ToolsVersion=\"" + VCProjectFileGenerator.ProjectFileToolVersionString + "\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">" + ProjectFileGenerator.NewLine);
  1214.  
  1215.             ProjectFileContent.Append(
  1216.                 "<Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />" +
  1217.                     ProjectFileGenerator.NewLine);
  1218.  
  1219.             // Support single configuration only (for now).
  1220.             ProjectFileContent.Append(
  1221.                     "<PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Development|AnyCPU' \">" + ProjectFileGenerator.NewLine +
  1222.                     "\t<DebugType>pdbonly</DebugType>" + ProjectFileGenerator.NewLine +
  1223.                     "\t<Optimize>true</Optimize>" + ProjectFileGenerator.NewLine +
  1224.                     "\t<OutputPath>bin\\Release\\</OutputPath>" + ProjectFileGenerator.NewLine +
  1225.                     "\t<DefineConstants>TRACE</DefineConstants>" + ProjectFileGenerator.NewLine +
  1226.                     "\t<ErrorReport>prompt</ErrorReport>" + ProjectFileGenerator.NewLine +
  1227.                     "\t<WarningLevel>4</WarningLevel>" + ProjectFileGenerator.NewLine +
  1228.                     "\t<TreatWarningsAsErrors>true</TreatWarningsAsErrors>" + ProjectFileGenerator.NewLine +
  1229.                 "</PropertyGroup>" + ProjectFileGenerator.NewLine);
  1230.  
  1231.             ProjectFileContent.Append(
  1232.                 "<PropertyGroup>" + ProjectFileGenerator.NewLine +
  1233.                     "\t<OutputType>Library</OutputType>" + ProjectFileGenerator.NewLine +
  1234.                     "\t<ProjectGuid>" + ProjectGUID.ToString("B").ToUpperInvariant() + "</ProjectGuid>" + ProjectFileGenerator.NewLine +
  1235.                     "\t<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>" + ProjectFileGenerator.NewLine +
  1236.                 "\t</PropertyGroup>" + ProjectFileGenerator.NewLine);
  1237.  
  1238.             // Basic .Net references
  1239.             if (DotNetAssemblyReferences.Count > 0)
  1240.             {
  1241.                 ProjectFileContent.Append("<ItemGroup>" + ProjectFileGenerator.NewLine);
  1242.                 foreach (var CurReference in DotNetAssemblyReferences)
  1243.                 {
  1244.                     ProjectFileContent.Append("\t<Reference Include=\"" + CurReference + "\" />" + ProjectFileGenerator.NewLine);
  1245.                 }
  1246.                 ProjectFileContent.Append("</ItemGroup>" + ProjectFileGenerator.NewLine);
  1247.             }
  1248.             // External or third party assembly references
  1249.             if( AssemblyReferences.Count > 0 )
  1250.             {
  1251.                 ProjectFileContent.Append( "<ItemGroup>" + ProjectFileGenerator.NewLine );
  1252.                 foreach( var CurReference in AssemblyReferences )
  1253.                 {
  1254.                     ProjectFileContent.Append( "\t<Reference Include=\"" + Path.GetFileNameWithoutExtension( CurReference ) + "\" >" + ProjectFileGenerator.NewLine );
  1255.                     ProjectFileContent.Append( "\t\t<HintPath>" + Utils.MakePathRelativeTo( CurReference, Path.GetDirectoryName(ProjectFilePath) ) + "</HintPath>" + ProjectFileGenerator.NewLine );
  1256.                     ProjectFileContent.Append( "\t</Reference>" + ProjectFileGenerator.NewLine );
  1257.                 }
  1258.                 ProjectFileContent.Append( "</ItemGroup>" + ProjectFileGenerator.NewLine );
  1259.             }
  1260.  
  1261.             // Other references (note it's assumed all references here are at least of MSBuildProjectFile type.
  1262.             foreach (var Project in DependsOnProjects)
  1263.             {
  1264.                 var RelativePath = Utils.MakePathRelativeTo(Path.GetDirectoryName(Project.ProjectFilePath), Path.GetDirectoryName(ProjectFilePath));
  1265.                 RelativePath = Path.Combine(RelativePath, Path.GetFileName(Project.ProjectFilePath));
  1266.                 ProjectFileContent.Append(
  1267.                     "<ItemGroup>" + ProjectFileGenerator.NewLine +
  1268.                         "<ProjectReference Include=\"" + RelativePath + "\">" + ProjectFileGenerator.NewLine +
  1269.                             "<Project>" + ((MSBuildProjectFile)Project).ProjectGUID.ToString("B").ToUpperInvariant() + "</Project>" + ProjectFileGenerator.NewLine +
  1270.                             "<Name>" + Path.GetFileNameWithoutExtension(RelativePath) + "</Name>" + ProjectFileGenerator.NewLine +
  1271.                         "</ProjectReference>" + ProjectFileGenerator.NewLine +
  1272.                     "</ItemGroup>" + ProjectFileGenerator.NewLine);
  1273.             }
  1274.  
  1275.             // Source files.
  1276.             ProjectFileContent.Append(
  1277.                 "   <ItemGroup>" + ProjectFileGenerator.NewLine );
  1278.             // Add all files to the project.
  1279.             foreach( var CurFile in SourceFiles )
  1280.             {
  1281.                 var ProjectRelativeSourceFile = Utils.MakePathRelativeTo( CurFile.FilePath, Path.GetDirectoryName( ProjectFilePath ) );
  1282.                 ProjectFileContent.Append(
  1283.                     "       <Compile Include=\"" + ProjectRelativeSourceFile + "\" />" + ProjectFileGenerator.NewLine);
  1284.             }
  1285.             ProjectFileContent.Append(
  1286.                 "   </ItemGroup>" + ProjectFileGenerator.NewLine );
  1287.  
  1288.             ProjectFileContent.Append(
  1289.                 "<Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />" + ProjectFileGenerator.NewLine);
  1290.  
  1291.             ProjectFileContent.Append(
  1292.                 "</Project>" + ProjectFileGenerator.NewLine );
  1293.  
  1294.             // Save the project file
  1295.             if (bSuccess)
  1296.             {
  1297.                 bSuccess = ProjectFileGenerator.WriteFileIfChanged(ProjectFilePath, ProjectFileContent.ToString());
  1298.             }
  1299.  
  1300.             return bSuccess;
  1301.         }
  1302.  
  1303.         /// Assemblies this project is dependent on
  1304.         protected readonly List<string> AssemblyReferences = new List<string>();
  1305.         /// System assemblies this project is dependent on
  1306.         protected readonly List<string> DotNetAssemblyReferences = new List<string>() { "System", "System.Core", "System.Data", "System.Xml" };
  1307.     }
  1308.  
  1309.  
  1310.     /// <summary>
  1311.     /// A Sandcastle Help File Builder project
  1312.     /// </summary>
  1313.     public class VSHFBProjectFile : MSBuildProjectFile
  1314.     {
  1315.         // This is the GUID that Visual Studio uses to identify a Sandcastle Help File project file in the solution - note the lack of {}
  1316.         public override string ProjectTypeGUID
  1317.         {
  1318.             get { return "0074e5b6-dd35-4f2c-9ede-f6259f61e92c"; }
  1319.         }
  1320.  
  1321.         /// <summary>
  1322.         /// Constructs a new project file object
  1323.         /// </summary>
  1324.         /// <param name="InitFilePath">The path to the project file on disk</param>
  1325.         public VSHFBProjectFile( string InitFilePath )
  1326.             : base( InitFilePath )
  1327.         {
  1328.         }
  1329.     }
  1330. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement