/// <summary>
        /// Adds a target for a project whose type is unknown and we cannot build.  We will emit an error or warning as appropriate.
        /// </summary>
        private void AddMetaprojectTargetForUnknownProjectType(ProjectInstance traversalProject, ProjectInstance metaprojectInstance, ProjectInSolution project, string targetName, string unknownProjectTypeErrorMessage)
        {
            ProjectTargetInstance newTarget = metaprojectInstance.AddTarget(targetName ?? "Build", "'$(CurrentSolutionConfigurationContents)' != ''", null, null, null, null, null, false /* legacy target returns behaviour */);

            foreach (SolutionConfigurationInSolution solutionConfiguration in _solutionFile.SolutionConfigurations)
            {
                ProjectConfigurationInSolution projectConfiguration = null;
                ProjectTaskInstance newTask = null;

                if (project.ProjectConfigurations.TryGetValue(solutionConfiguration.FullName, out projectConfiguration))
                {
                    if (projectConfiguration.IncludeInBuild)
                    {
                        // Only add the task if it would run in this configuration.
                        if (!traversalProject.EvaluateCondition(GetConditionStringForConfiguration(solutionConfiguration)))
                        {
                            continue;
                        }

                        if (unknownProjectTypeErrorMessage == null)
                        {
                            // we haven't encountered any problems accessing the project file in the past, but do not support
                            // building this project type
                            newTask = AddErrorWarningMessageInstance
                                (
                                newTarget,
                                null,
                                XMakeElements.warning,
                                true,
                                "SolutionParseUnknownProjectType",
                                project.RelativePath
                                );
                        }
                        else
                        {
                            // this project file may be of supported type, but we have encountered problems accessing it
                            newTask = AddErrorWarningMessageInstance
                                (
                                newTarget,
                                null,
                                XMakeElements.warning,
                                true,
                                "SolutionParseErrorReadingProject",
                                project.RelativePath,
                                unknownProjectTypeErrorMessage
                                );
                        }
                    }
                    else
                    {
                        newTask = AddErrorWarningMessageInstance
                            (
                            newTarget,
                            null,
                            XMakeElements.message,
                            true,
                            "SolutionProjectSkippedForBuilding",
                            project.ProjectName,
                            solutionConfiguration.FullName
                            );
                    }
                }
                else
                {
                    newTask = AddErrorWarningMessageInstance
                        (
                        newTarget,
                        null,
                        XMakeElements.warning,
                        true,
                        "SolutionProjectConfigurationMissing",
                        project.ProjectName,
                        solutionConfiguration.FullName
                        );
                }
            }
        }
        /// <summary>
        /// Add a PropertyGroup to the project for a particular Asp.Net configuration.  This PropertyGroup
        /// will have the correct values for all the Asp.Net properties for this project and this configuration.
        /// </summary>
        private void AddPropertyGroupForAspNetConfiguration
            (
            ProjectInstance traversalProject,
            ProjectInstance metaprojectInstance,
            ProjectInSolution project,
            string configurationName,
            AspNetCompilerParameters aspNetCompilerParameters,
            string solutionFile
            )
        {
            // If the configuration doesn't match, don't add the properties.
            if (!traversalProject.EvaluateCondition(String.Format(CultureInfo.InvariantCulture, " '$(AspNetConfiguration)' == '{0}' ", EscapingUtilities.Escape(configurationName))))
            {
                return;
            }

            // Add properties into the property group for each of the AspNetCompiler properties.
            // REVIEW: SetProperty takes an evaluated value.  Are we doing the right thing here?
            metaprojectInstance.SetProperty(GenerateSafePropertyName(project, "AspNetVirtualPath"), EscapingUtilities.Escape(aspNetCompilerParameters.aspNetVirtualPath));
            metaprojectInstance.SetProperty(GenerateSafePropertyName(project, "AspNetPhysicalPath"), EscapingUtilities.Escape(aspNetCompilerParameters.aspNetPhysicalPath));
            metaprojectInstance.SetProperty(GenerateSafePropertyName(project, "AspNetTargetPath"), EscapingUtilities.Escape(aspNetCompilerParameters.aspNetTargetPath));
            metaprojectInstance.SetProperty(GenerateSafePropertyName(project, "AspNetForce"), EscapingUtilities.Escape(aspNetCompilerParameters.aspNetForce));
            metaprojectInstance.SetProperty(GenerateSafePropertyName(project, "AspNetUpdateable"), EscapingUtilities.Escape(aspNetCompilerParameters.aspNetUpdateable));
            metaprojectInstance.SetProperty(GenerateSafePropertyName(project, "AspNetDebug"), EscapingUtilities.Escape(aspNetCompilerParameters.aspNetDebug));
            metaprojectInstance.SetProperty(GenerateSafePropertyName(project, "AspNetKeyFile"), EscapingUtilities.Escape(aspNetCompilerParameters.aspNetKeyFile));
            metaprojectInstance.SetProperty(GenerateSafePropertyName(project, "AspNetKeyContainer"), EscapingUtilities.Escape(aspNetCompilerParameters.aspNetKeyContainer));
            metaprojectInstance.SetProperty(GenerateSafePropertyName(project, "AspNetDelaySign"), EscapingUtilities.Escape(aspNetCompilerParameters.aspNetDelaySign));
            metaprojectInstance.SetProperty(GenerateSafePropertyName(project, "AspNetAPTCA"), EscapingUtilities.Escape(aspNetCompilerParameters.aspNetAPTCA));
            metaprojectInstance.SetProperty(GenerateSafePropertyName(project, "AspNetFixedNames"), EscapingUtilities.Escape(aspNetCompilerParameters.aspNetFixedNames));

            string aspNetPhysicalPath = aspNetCompilerParameters.aspNetPhysicalPath;
            if (!String.IsNullOrEmpty(aspNetPhysicalPath))
            {
                // Trim the trailing slash if one exists.
                if (
                        (aspNetPhysicalPath[aspNetPhysicalPath.Length - 1] == Path.AltDirectorySeparatorChar) ||
                        (aspNetPhysicalPath[aspNetPhysicalPath.Length - 1] == Path.DirectorySeparatorChar)
                    )
                {
                    aspNetPhysicalPath = aspNetPhysicalPath.Substring(0, aspNetPhysicalPath.Length - 1);
                }

                // This gets us the last folder in the physical path.
                string lastFolderInPhysicalPath = null;

                try
                {
                    lastFolderInPhysicalPath = Path.GetFileName(aspNetPhysicalPath);
                }
                catch (Exception e)
                {
                    if (ExceptionHandling.NotExpectedException(e))
                    {
                        throw;
                    }

                    ProjectFileErrorUtilities.VerifyThrowInvalidProjectFile
                        (
                        false,
                        "SubCategoryForSolutionParsingErrors",
                        new BuildEventFileInfo(solutionFile),
                        e,
                        "SolutionParseInvalidProjectFileName",
                        project.RelativePath,
                        e.Message
                        );
                }

                if (!String.IsNullOrEmpty(lastFolderInPhysicalPath))
                {
                    // If there is a global property called "OutDir" set, that means the caller is trying to 
                    // override the AspNetTargetPath.  What we want to do in this case is concatenate:
                    // $(OutDir) + "\_PublishedWebsites" + (the last portion of the folder in the AspNetPhysicalPath).
                    if (traversalProject.EvaluateCondition(" '$(OutDir)' != '' "))
                    {
                        string outDirValue = String.Empty;
                        ProjectPropertyInstance outdir = metaprojectInstance.GetProperty("OutDir");

                        if (outdir != null)
                        {
                            outDirValue = ProjectInstance.GetPropertyValueEscaped(outdir);
                        }

                        // Make sure the path we are appending to has no leading slash to prevent double slashes.
                        string publishWebsitePath = EscapingUtilities.Escape(WebProjectOverrideFolder) + Path.DirectorySeparatorChar + EscapingUtilities.Escape(lastFolderInPhysicalPath) + Path.DirectorySeparatorChar;

                        metaprojectInstance.SetProperty
                            (
                            GenerateSafePropertyName(project, "AspNetTargetPath"),
                            outDirValue + publishWebsitePath
                            );
                    }
                }
            }
        }
Exemple #3
0
		// FIXME: my guess is the tasks does not have to be loaded entirely but only requested tasks must be loaded at invocation time.
		void LoadUsingTasks (ProjectInstance projectInstance, IEnumerable<ProjectUsingTaskElement> usingTasks)
		{
			Func<string,bool> cond = s => projectInstance != null ? projectInstance.EvaluateCondition (s) : Convert.ToBoolean (s);
			foreach (var ut in usingTasks) {
				var ta = assemblies.FirstOrDefault (a => a.AssemblyFile.Equals (ut.AssemblyFile, StringComparison.OrdinalIgnoreCase) || a.AssemblyName.Equals (ut.AssemblyName, StringComparison.OrdinalIgnoreCase));
				if (ta == null) {
					var path = Path.GetDirectoryName (string.IsNullOrEmpty (ut.Location.File) ? projectInstance.FullPath : ut.Location.File);
					ta = new TaskAssembly () { AssemblyName = ut.AssemblyName, AssemblyFile = ut.AssemblyFile };
					try {
						ta.LoadedAssembly = !string.IsNullOrEmpty (ta.AssemblyName) ? Assembly.Load (ta.AssemblyName) : Assembly.LoadFile (Path.Combine (path, ta.AssemblyFile));
					} catch {
						var errorNotLoaded = string.Format ("For task '{0}' Specified assembly '{1}' was not found", ut.TaskName, string.IsNullOrEmpty (ta.AssemblyName) ? ta.AssemblyFile : ta.AssemblyName);
						engine.LogWarningEvent (new BuildWarningEventArgs (null, null, projectInstance.FullPath, ut.Location.Line, ut.Location.Column, 0, 0, errorNotLoaded, null, null));
						continue;
					}
					assemblies.Add (ta);
				}
				var pg = ut.ParameterGroup == null ? null : ut.ParameterGroup.Parameters.Select (p => new TaskPropertyInfo (p.Name, Type.GetType (p.ParameterType), cond (p.Output), cond (p.Required)))
					.ToDictionary (p => p.Name);
				

				Type type = null;
				string error = null;
				TaskDescription task = new TaskDescription () {
					TaskAssembly = ta,
					Name = ut.TaskName,
					TaskFactoryParameters = pg,
					TaskBody = ut.TaskBody != null && cond (ut.TaskBody.Condition) ? ut.TaskBody.Evaluate : null,
					};
				if (string.IsNullOrEmpty (ut.TaskFactory)) {
					type = LoadTypeFrom (ta.LoadedAssembly, ut.TaskName, ut.TaskName);
					if (type == null)
						error = string.Format ("For task '{0}' Specified type '{1}' was not found in assembly '{2}'", ut.TaskName, ut.TaskName, ta.LoadedAssembly.FullName);
					else
						task.TaskType = type;
				} else {
					type = LoadTypeFrom (ta.LoadedAssembly, ut.TaskName, ut.TaskFactory);
					if (type == null)
						error = string.Format ("For task '{0}' Specified factory type '{1}' was not found in assembly '{2}'", ut.TaskName, ut.TaskFactory, ta.LoadedAssembly.FullName);
					else
						task.TaskFactoryType = type;
				}
				if (error != null)
					engine.LogWarningEvent (new BuildWarningEventArgs (null, null, projectInstance.FullPath, ut.Location.Line, ut.Location.Column, 0, 0, error, null, null));
				else
					task_descs.Add (task);
			}
		}
        /// <summary>
        /// Adds MSBuild tasks to a project target to pre-resolve its project references
        /// </summary>
        private void AddResolveProjectReferenceTasks
        (
            ProjectInstance traversalProject,
            ProjectTargetInstance target,
            ProjectInSolution project,
            SolutionConfigurationInSolution solutionConfiguration,
            string outputReferenceItemName,
            string outputImportLibraryItemName,
            out string addedReferenceGuids
        )
        {
            StringBuilder referenceGuids = new StringBuilder();

            string message = null;

            // Suffix for the reference item name. Since we need to attach additional (different) metadata to every
            // reference item, we need to have helper item lists each with only one item
            int outputReferenceItemNameSuffix = 0;

            // Pre-resolve the MSBuild project references
            foreach (string projectReferenceGuid in project.ProjectReferences)
            {
                ProjectInSolution referencedProject = (ProjectInSolution)_solutionFile.ProjectsByGuid[projectReferenceGuid];
                ProjectConfigurationInSolution referencedProjectConfiguration = null;

                if ((referencedProject != null) &&
                    (referencedProject.ProjectConfigurations.TryGetValue(solutionConfiguration.FullName, out referencedProjectConfiguration)) &&
                    (referencedProjectConfiguration != null))
                {
                    string outputReferenceItemNameWithSuffix = string.Format(CultureInfo.InvariantCulture, "{0}_{1}", outputReferenceItemName, outputReferenceItemNameSuffix);

                    if ((referencedProject.ProjectType == SolutionProjectType.KnownToBeMSBuildFormat) ||
                        ((referencedProject.ProjectType == SolutionProjectType.Unknown) && (referencedProject.CanBeMSBuildProjectFile(out message))))
                    {
                        string condition = GetConditionStringForConfiguration(solutionConfiguration);
                        if (traversalProject.EvaluateCondition(condition))
                        {
                            bool specifyProjectToolsVersion =
                                String.Equals(traversalProject.ToolsVersion, "2.0", StringComparison.OrdinalIgnoreCase) ? false : true;

                            ProjectTaskInstance msbuildTask = AddMSBuildTaskInstance
                                (
                                target,
                                referencedProject.RelativePath,
                                "GetTargetPath",
                                referencedProjectConfiguration.ConfigurationName,
                                referencedProjectConfiguration.PlatformName,
                                specifyProjectToolsVersion
                                );
                            msbuildTask.AddOutputItem("TargetOutputs", outputReferenceItemNameWithSuffix, null);
                        }

                        if (referenceGuids.Length > 0)
                        {
                            referenceGuids.Append(';');
                        }

                        referenceGuids.Append(projectReferenceGuid);

                        // This merges the one-item item list into the main list, adding the appropriate guid metadata
                        ProjectTaskInstance createItemTask = target.AddTask("CreateItem", null, null);
                        createItemTask.SetParameter("Include", "@(" + outputReferenceItemNameWithSuffix + ")");
                        createItemTask.SetParameter("AdditionalMetadata", "Guid=" + projectReferenceGuid);
                        createItemTask.AddOutputItem("Include", outputReferenceItemName, null);
                    }

                    outputReferenceItemNameSuffix++;
                }
            }

            addedReferenceGuids = referenceGuids.ToString();
        }
Exemple #5
0
		void LoadUsingTasks (ProjectInstance projectInstance, ProjectRootElement project)
		{
			Func<string,bool> cond = s => projectInstance != null ? projectInstance.EvaluateCondition (s) : Convert.ToBoolean (s);
			foreach (var ut in project.UsingTasks) {
				var ta = assemblies.FirstOrDefault (a => a.AssemblyFile.Equals (ut.AssemblyFile, StringComparison.OrdinalIgnoreCase) || a.AssemblyName.Equals (ut.AssemblyName, StringComparison.OrdinalIgnoreCase));
				if (ta == null) {
					ta = new TaskAssembly () { AssemblyName = ut.AssemblyName, AssemblyFile = ut.AssemblyFile };
					ta.LoadedAssembly = ta.AssemblyName != null ? Assembly.Load (ta.AssemblyName) : Assembly.LoadFile (ta.AssemblyFile);
					assemblies.Add (ta);
				}
				var pg = ut.ParameterGroup == null ? null : ut.ParameterGroup.Parameters.Select (p => new TaskPropertyInfo (p.Name, Type.GetType (p.ParameterType), cond (p.Output), cond (p.Required)))
					.ToDictionary (p => p.Name);
				var task = new TaskDescription () {
					TaskAssembly = ta,
					Name = ut.TaskName,
					TaskFactoryType = string.IsNullOrEmpty (ut.TaskFactory) ? null : LoadTypeFrom (ta.LoadedAssembly, ut.TaskName, ut.TaskFactory),
					TaskType = string.IsNullOrEmpty (ut.TaskFactory) ? LoadTypeFrom (ta.LoadedAssembly, ut.TaskName, ut.TaskName) : null,
					TaskFactoryParameters = pg,
					TaskBody = ut.TaskBody != null && cond (ut.TaskBody.Condition) ? ut.TaskBody.Evaluate : null,
					};
				task_descs.Add (task);
			}
		}