Пакетная обработка MSBUILD (зацикливание) по файлам и строкам Замена имен файлов

Я пытаюсь «зациклиться» (пакетно) по списку файлов и string.replace имя корневого каталога другим именем каталога.

Этот проект использует 3.5, поэтому не может в полной мере использовать некоторые новые функции 4.0.

Я использую задачу MSBuild.ExtensionPack.Framework.TextString (из http://msbuildextensionpack.codeplex.com/releases/57599/download/229487 )

В принципе, я хочу переписать имя файла

c:\SomeFolder\myfile.txt
to
c:\AnotherFolder\myfile.txt

Я написал макет, чтобы продемонстрировать проблему.

Вот результаты, которые я получаю:

"C:\Windows\twunk_16.exe"        "c:\WindowsFake\write.exe"
"C:\Windows\twunk_32.exe"        "c:\WindowsFake\write.exe"
"C:\Windows\winhlp32.exe"        "c:\WindowsFake\write.exe"
"C:\Windows\write.exe"        "c:\WindowsFake\write.exe"

Вы заметите, что «c:\WindowsFake\write.exe» (справа) повторяется для каждого элемента в пакете. :‹

Что я пытаюсь получить:

"C:\Windows\twunk_16.exe"        "c:\WindowsFake\twunk_16.exe"
"C:\Windows\twunk_32.exe"        "c:\WindowsFake\twunk_32.exe"
"C:\Windows\winhlp32.exe"        "c:\WindowsFake\winhlp32.exe"
"C:\Windows\write.exe"        "c:\WindowsFake\write.exe"

Я (вроде) понимаю, почему я получаю повторяющееся значение. Но (конечно) не могу понять, как решить эту проблему. Не зацикливайтесь на «поддельных окнах» «windows», это всего лишь фиктивные примеры, которые я создал, потому что у большинства людей есть каталог c: \ windows на их компьютере, и мне нужно было «захватить» некоторые файлы.

Опять же, я использую 3.5 MSBuild, а не 4.0.

set msBuildDir=%WINDIR%\Microsoft.NET\Framework\v3.5
call %msBuildDir%\msbuild.exe Master_MSBuild.xml /p:Configuration=Release /l:FileLogger,Microsoft.Build.Engine;logfile=Master_MSBuild_LOG.log
set msBuildDir=

Вот полный код .msbuild. (Который у меня есть в файле с именем «Master_MSBuild.xml».)

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="AllTargetsWrapper">
  <!--  -->
  <!--  -->
  <UsingTask AssemblyFile=".\MSBuild.ExtensionPack.dll" TaskName="MSBuild.ExtensionPack.Framework.TextString" />
  <!--  -->
  <!--  -->
  <PropertyGroup>
    <WindowsForRealDirectory>$(windir)</WindowsForRealDirectory>
    <WindowsFakeDirectory>c:\WindowsFake</WindowsFakeDirectory>
  </PropertyGroup>
  <!--  -->
  <!--  -->
  <Target Name="DetermineAllFilesTarget">
    <!--  -->
    <ItemGroup>
      <MyExcludedFiles Include="$(WindowsForRealDirectory)\**\notepad.exe" />
      <MyExcludedFiles Include="$(WindowsForRealDirectory)\**\b*.exe" />      
      <MyExcludedFiles Include="$(WindowsForRealDirectory)\**\e*.exe" />          
      <MyExcludedFiles Include="$(WindowsForRealDirectory)\**\f*.exe" />    
    </ItemGroup>
    <!--  -->
    <ItemGroup>
      <MyIncludedFiles Include="$(WindowsForRealDirectory)\Microsoft.NET\*.exe" Exclude="@(MyExcludedFiles)" />
      <MyIncludedFiles Include="$(WindowsForRealDirectory)\*.exe" Exclude="@(MyExcludedFiles)" />
    </ItemGroup>
    <!--  -->
    <!-- This create item may be redundant. -->
    <CreateItem Include="@(MyIncludedFiles)">
      <Output TaskParameter="Include" ItemName="FoundFolders" />
    </CreateItem>
    <!--  -->
    <!--  -->
    <Message Text="rootdir: @(FoundFolders-&gt;'%(rootdir)')" />
    <Message Text="fullpath: @(FoundFolders-&gt;'%(fullpath)')" />
    <Message Text="rootdir + directory + filename + extension: @(FoundFolders-&gt;'%(rootdir)%(directory)%(filename)%(extension)')" />
    <Message Text="identity: @(FoundFolders-&gt;'%(identity)')" />
    <Message Text="filename: @(FoundFolders-&gt;'%(filename)')" />
    <Message Text="directory: @(FoundFolders-&gt;'%(directory)')" />
    <Message Text="relativedir: @(FoundFolders-&gt;'%(relativedir)')" />
    <Message Text="extension: @(FoundFolders-&gt;'%(extension)')" />
    <!--  -->
  </Target>
  <!--  -->
  <!--  -->
  <!--  -->
  <Target Name="ReplaceAndShowAllFileNames" Inputs="@(FoundFolders)" Outputs="@(FoundFolders.Identity')">
    <!--  -->
    <Message Text="   " />
    <Message Text="FoundFolders.FileName = %(FoundFolders.FileName)" />
    <Message Text="FoundFolders.FullPath = %(FoundFolders.FullPath)" />
    <Message Text="   rootdir + directory + filename + extension = '%(FoundFolders.rootdir)  ***  %(FoundFolders.directory)  ***  %(FoundFolders.filename)  ***  %(FoundFolders.extension)'  " />
    <Message Text="FoundFolders.rootdir = %(FoundFolders.rootdir)" />
    <Message Text="FoundFolders.directory = %(FoundFolders.directory)" />
    <Message Text="FoundFolders.relativedir = %(FoundFolders.relativedir)" />
    <Message Text="FoundFolders.extension = %(FoundFolders.extension)" />
    <Message Text="FoundFolders.recursivedir = %(FoundFolders.recursivedir)" />
    <Message Text="   " />
    <Message Text="   " />
    <Message Text="   " />
    <!--  -->
    <Message Text="   (WindowsFakeDirectory)= $(WindowsFakeDirectory)" />
    <!--  -->
    <!-- Replace the contents of a string -->
    <MSBuild.ExtensionPack.Framework.TextString TaskAction="Replace" OldString="%(FoundFolders.relativedir)%(FoundFolders.Filename)%(FoundFolders.Extension)" OldValue="$(WindowsForRealDirectory)" NewValue="$(WindowsFakeDirectory)">
      <Output PropertyName="RewrittenFileName" TaskParameter="NewString" />
    </MSBuild.ExtensionPack.Framework.TextString>
    <!--  -->
    <CreateProperty Value="$(CheckedOutFileName)">
      <Output PropertyName="CheckedOutFileNameTwo" TaskParameter="Value" />
    </CreateProperty>
    <!--  -->
    <Message Text="   " />  
    <Message Text="The Result of the String.Replace: $(RewrittenFileName)" />
    <!--  -->
    <Message Text="   " />      
    <Message Text="Command: &quot;The original and the rewritten file name:  &quot; &quot;%(FoundFolders.relativedir)%(FoundFolders.Filename)%(FoundFolders.Extension)&quot;        &quot;$(RewrittenFileName)&quot;" />
    <!--  -->
  </Target>
  <!--  -->
  <!--  -->
  <!--  -->
  <Target Name="AllTargetsWrapper">
    <!--  -->
    <CallTarget Targets="DetermineAllFilesTarget" />
    <!--  -->
    <CallTarget Targets="ReplaceAndShowAllFileNames" />
    <!--  -->
  </Target>
  <!--  -->
</Project>

person granadaCoder    schedule 09.06.2011    source источник


Ответы (1)


Есть ли какая-то причина, по которой вы не просто выполняете простые преобразования предметов? Это было бы намного меньше кода.

<ItemGroup>
  <MyIncludedFiles
    Include="$(WindowsForRealDirectory)\**\Microsoft.NET\*.exe"
    Exclude="@(MyExcludedFiles)"
    />
  <MyIncludedFiles
    Include="$(WindowsForRealDirectory)\*.exe"
    Exclude="@(MyExcludedFiles)"
    />
</ItemGroup>

...then

<ItemGroup>
  <MyTransformedFiles
    Include="@(MyIncludedFiles->'$(WindowsFakeDirectory)\%(RecursiveDir)%(Filename)%(Extension)')
    />
</ItemGroup>

Обратите внимание на дополнительные ** перед Microsoft.NET, так что RecursiveDir имеет значение.

person Brian Kretzler    schedule 09.06.2011
comment
Я не смог получить преобразования, чтобы помочь в моей ситуации. В итоге я поставил условия для каждой задачи внутри моей цели, чтобы получить желаемое поведение. - person granadaCoder; 17.06.2011