Exemplo n.º 1
0
        // Retrieves a property from an MSBuild project file by executing MSBuild and getting MSBuild to print the property.
        // We do this by creating a custom MSBuild file which:
        // * Will import the project file we're inspecting
        // * Has a target that will print a given property
        // and then executing MSBuild on this custom MSBuild file.
        public static async Task <string> GetPropertyByMSBuildEvaluationAsync(this XmlDocument csproj, ILog log, IProcessManager processManager, string projectPath, string evaluateProperty, string dependsOnTargets = "", Dictionary <string, string> properties = null)
        {
            var xml =
                @"<Project DefaultTargets='WriteProperty' xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
	<!-- Import the project we want to inspect -->
	<Import Project='$(ProjectFile)' Condition=""'$(ProjectFile)' != ''"" />
	<!-- Target to write out the property we want -->
	<Target Name='WriteProperty' DependsOnTargets='%DEPENDSONTARGETS%'>
		<PropertyGroup>
			<_Properties>$(%PROPERTY%)</_Properties>
		</PropertyGroup>
		<Error Text='The ProjectFile variable must be set.' Condition=""'$(ProjectFile)' == ''"" />
		<Error Text='The OutputFile variable must be set.' Condition=""'$(OutputFile)' == ''"" />
		<WriteLinesToFile File='$(OutputFile)' Lines='$(_Properties)' Overwrite='true' />
	</Target>
</Project>
";

            var dir       = Path.GetDirectoryName(projectPath);
            var inspector = Path.Combine(dir, "PropertyInspector.csproj");
            var output    = Path.Combine(dir, "PropertyInspector.txt");

            try {
                File.WriteAllText(inspector, xml.Replace("%PROPERTY%", evaluateProperty).Replace("%DEPENDSONTARGETS%", dependsOnTargets));
                using (var proc = new Process()) {
                    var isDotNetProject = csproj.IsDotNetProject();
                    proc.StartInfo.FileName = isDotNetProject ? processManager.GetDotNetExecutable(projectPath) : processManager.MSBuildPath;
                    var args = new List <string> ();
                    if (isDotNetProject)
                    {
                        args.Add("build");
                    }
                    args.Add("/p:ProjectFile=" + projectPath);
                    args.Add("/p:OutputFile=" + output);
                    foreach (var prop in properties)
                    {
                        args.Add($"/p:{prop.Key}={prop.Value}");
                    }
                    args.Add(inspector);
                    proc.StartInfo.Arguments        = StringUtils.FormatArguments(args);
                    proc.StartInfo.WorkingDirectory = dir;
                    var rv = await processManager.RunAsync(proc, log, timeout : TimeSpan.FromSeconds(15));

                    if (!rv.Succeeded)
                    {
                        throw new Exception($"Unable to evaluate the property {evaluateProperty}.");
                    }
                    return(File.ReadAllText(output).Trim());
                }
            } finally {
                File.Delete(inspector);
                File.Delete(output);
            }
        }