如何替换存储在MSBuild属性中的文件路径的扩展名?

时间:2009-03-19 16:22:02

标签: msbuild properties

我的MSBuild项目文件中有以下几行:

<PropertyGroup>
    <TestResultsFileName Condition=" '$(TestResultsFileName)' == '' ">
        TestResults.trx
    </TestResultsFileName>
    <TestResultsFilePath>$(OutDir)\$(TestResultsFileName)</TestResultsFilePath>
</PropertyGroup>

我需要创建另一个文件,与TestResultsFilePath同名,只有.xml扩展名。所以我希望有一个属性来保存另一个文件的文件路径。

起初,我认为这样的事情会起作用:

<PropertyGroup>
    <NUnitResultsFilePath>
        $(OutDir)\$(TestResultsFileName->'%(Filename).xml')
    </NUnitResultsFilePath>
</PropertyGroup>

当然,它没有,因为TestResultsFileName不是项集合。不幸的是,它不可能是这样,因为它是某个任务的参数,需要一个简单的值,而不是一个集合。

所以,我的问题是如何用.xml替换TestResultsFileName属性值的扩展名?

感谢。

1 个答案:

答案 0 :(得分:0)

没关系。我写了一个自定义任务来完成这项工作:

    public class ReplaceExtension : Task
    {
        [Required]
        public string FilePath { get; set; }

        public string NewExtension { get; set; }

        [Output]
        public string Result { get; set; }

        public override bool Execute()
        {
            if (string.IsNullOrEmpty(FilePath))
            {
                Log.LogError("FilePath cannot be empty!");
                return false;
            }

            try
            {
                int length = FilePath.Length;
                int startIndex = length;
                int oldExtensionLength = 0;
                while (--startIndex >= 0)
                {
                    char ch = FilePath[startIndex];
                    if (ch == '.')
                    {
                        oldExtensionLength = length - startIndex;
                        break;
                    }
                    if (ch == Path.DirectorySeparatorChar || 
                        ch == Path.AltDirectorySeparatorChar || 
                        ch == Path.VolumeSeparatorChar)
                    {
                        break;
                    }
                }

                bool isNewExtensionEmpty = string.IsNullOrEmpty(NewExtension) ||
                    (NewExtension.Length == 1 && NewExtension[0] == '.');

                if (isNewExtensionEmpty)
                {
                    // The new extension is empty - remove the old extension.
                    if (oldExtensionLength > 0)
                    {
                        Result = FilePath.Remove(startIndex, oldExtensionLength);
                    }
                    else
                    {
                        Result = FilePath;
                    }
                }
                else
                {
                    // Replace the old extension with the new one.
                    StringBuilder sb = new StringBuilder(FilePath.Length - oldExtensionLength +
                        NewExtension.Length + (NewExtension[0] == '.' ? 0 : 1));
                    sb.Append(FilePath, 0, FilePath.Length - oldExtensionLength);
                    if (NewExtension[0] != '.')
                    {
                        sb.Append('.');
                    }
                    sb.Append(NewExtension);
                    Result = sb.ToString();
                }
            }
            catch (Exception ex)
            {
                Log.LogErrorFromException(ex);
            }
            return !Log.HasLoggedErrors;
        }
    }

我正在使用它:

  <Target Name="CreateProperties">
    <ReplaceExtension FilePath="$(TestResultsFilePath)" NewExtension="xml">
      <Output TaskParameter="Result" PropertyName="NUnitResultsFilePath"/>
    </ReplaceExtension>
  </Target>