Синтаксис завдання MSBuild для видалення файлів


75

Я намагаюся написати завдання MSBuild, яке видаляє каталог Obj та PDB з моєї папки bin у сценаріях моєї виробничої збірки і, здається, не може змусити його працювати належним чином.

Хто-небудь має приклад, коли вони роблять це або подібне, або посилання на простий приклад видалення файлів і каталогу за допомогою MSBuild?

Відповіді:


94

Якщо ви хочете видалити весь каталог, вам потрібно завдання RemoveDir :

<RemoveDir Directories="Path/To/Obj" />

І якщо ви хочете видалити PDB-файли з кошика, вам потрібно буде видалити завдання:

<Delete Files="Path/To/Bin/MyApp.pdb" />

Зверніть увагу, що ви не можете використовувати узагальнюючі символи у завданні "Видалити", тому, якщо у вас є кілька файлів pdb, ви повинні вказати ItemGroup як аргумент.


8
На довідковій сторінці завдання RemoveDir (див. Вище) сказано, що всі файли та підкаталоги будуть видалені.
Yawar

Я хотів би позначити обидві ваші відповіді, оскільки посилання на завдання RemoveDir показало мені, чого насправді не вистачало, так це те, що я не розпізнав своє властивість OutputPath для пошуку правильного каталогу. Відповідь Саїдса із синтаксисом ItemGroup - це те, що мені потрібно було зробити, щоб захопити всі файли pdb, щоб їх видалити. Дякую вам обом!
Кріс Марісіч,

1
Працює у мене, тому дякую, але краще додати ContinueOnError="true"атрибут, для першої перебудови
pylover

1
Sidenote - якщо шлях довший за 260 символів, RemoveDir не зможе; і вам натомість потрібно використовувати Exec з rmdir.
Ondrej Svejdar

Я грав із <Delete Files=...>завданням і помітив, що коли я будую збірку з Visual Studio, файли видаляються, і я бачу цю інформацію у вихідних даних. Але коли я запускаю в ньому командний рядок msbuild, файли не видаляються, і я нічого про це не бачу у вихідних даних, незалежно від багатослівності.
Howiecamp

131

Ви можете спочатку видалити файли в цих каталогах, а потім сам каталог із

<Target Name="SomeTarget">
    <ItemGroup>
        <FilesToDelete Include="Path\To\Obj\**\*"/>
    </ItemGroup>   
    <Delete Files="@(FilesToDelete)" />   
    <RemoveDir Directories="Path\To\Obj\" />
</Target>

1
@pylover, де у мене є Path \ To \ Obj ** \ * шлях повинен бути реальним шляхом до папки; наприклад C: \ temp \ папку для видалення. Чи може це бути причиною того, що у вас це не працює? Чи можете ви дати більше деталей, чому це не працює?
Sayed Ibrahim Hashimi

Використовуючи 2012 рік, я щойно перевірив, що RemoveDir виконує те, що сказано в документах - видаляє файли та папки. Не потребують додаткових кроків.
dudeNumber4

@SayedIbrahimHashimi вибачте за прямий підхід, але у мене є ваша книга, і я все ще не можу зрозуміти, як обійти цю проблему. stackoverflow.com/questions/25525197/… . Ви можете допомогти?
Blowsie

19

Публікації для інших, які могли б зіткнутися з тією ж проблемою, що і у мене.

Завдання "Видалити" не може видалити файли лише для читання, що мені потрібно було зробити, оскільки, коли MSBuild отримує останню версію TFS, файли позначаються як лише для читання. Я використав команду EXEC для видалення файлів лише для читання:

<ItemGroup>
    <FileToDelete Include="c:\temp\fileToDelete.txt"/>
</ItemGroup>
<Exec Command="del /F /Q &quot;@(FileToDelete)&quot;"/>

Це єдине, що могло б працювати у мене, коли файли лише для читання! (наприклад, перевірено з TFS) :) Дякую.
Тод Томсон,

1
У мене була ItemGroup із символами підстановки, яка розширилася до такої кількості файлів (повних шляхів), що delкомандний рядок став занадто довгим. Моє рішення було передати delузагальнюючі символи безпосередньо, а не використовувати ItemGroup.
йойо

9

Опубліковані відповіді будуть працювати, доки вам доведеться мати справу з одним каталогом. Якщо у вас трапляються вкладені папки, помилка RemoveDirне відбудеться Directory not empty.

Трохи загальний підхід також опікується вкладеними папками:

<Target Name="CleanOutDir">
    <ItemGroup>
        <FilesToClean Include="$(OutDir)\**\*.*" />

        <!-- Bit of .Net to get all folders and subfolders -->
        <FoldersToClean Include="$([System.IO.Directory]::GetDirectories(&quot;$(OutDir)&quot;))" />
    </ItemGroup>

    <Delete Files="@(FilesToClean)"/>
    <RemoveDir Directories="@(FoldersToClean)" />
</Target>

5

Цей код настільки потворний, що він має йти в комплекті з мішкою для протиповітряної хвороби. ;-) Але це швидко, тому що він не створює список файлів для видалення тощо.

<Target Name="DeleteBuildFolder">
    <Exec Command="RmDir /S /Q &quot;$(BuildFolder)&quot;" />
    <Exec Command="RmDir /S /Q &quot;$(BuildFolder)&quot;" />
    <Exec Command="RmDir /S /Q &quot;$(BuildFolder)&quot;" />
    <Exec Command="RmDir /S /Q &quot;$(BuildFolder)&quot;" />
    <Exec Command="RmDir /S /Q &quot;$(BuildFolder)&quot;" />
    <Exec Command="RmDir /S /Q &quot;$(BuildFolder)&quot;" />
    <Exec Command="RmDir /S /Q &quot;$(BuildFolder)&quot;" />
</Target>

Скільки команд RmDir потрібно? Досить кілька команд RmDir повертають "Система не може знайти вказаний файл" замість "Каталог не порожній". На моїй машині схоже на інший RmDir, якщо $ (BuildFolder) відкритий у Провіднику Windows. Антивірусна програма може впливати на RmDir, як це іноді робить Subversion, але я волів би загальний захист AV, ніж (не) керувати списком виключень.


4

Також можна спочатку видалити властивість readonly з файлу та виконати завдання видалення msbuild.

Подобається так:

<Target Name="DeleteFiles">
 <Message Text="Delete File" Importance="high"/>
 <Attrib Files="$(FileToDelete)" ReadOnly="false" />
 <Delete Files="$(FileToDelete)" />
</Target>`

2
Схоже, що завдання Attrib, про яке йдеться тут, є частиною проекту MSBuild Community Tasks .
Скотт Манро,

2

У Visual Studio 2013 додав це в кінець мого файлу .csproj безпосередньо перед </Project>закриваючим тегом

<Target Name = "clean_folders" AfterTargets="Clean">
 <Exec Command = "rd /S /Q obj" />
 <Exec Command = "rd /S /Q bin" />
</Target>

Спочатку це не спрацювало, але я помітив, що Visual Studio (або R #, не впевнений) повторно додано DesignTimeResolveAssemblyReferencesInput.cacheдо папки obj, а також додало поточну \binпапку (у мене різні збірки в різних підпапках під \bin). Він очистив усе інше, включаючи 25 інших конфігурацій збірки, які я маю з імпортованих файлів .csproj (так, я знаю).

Будьте обережні, якщо ви пакетно відновлюєте більше одного конфігура, оскільки він просто знищує всі попередні зусилля при кожному відновленні, залишаючи лише останню. Батоги.


1

Просто щоб додати ще одну зморшку, яку я виявив. Я використовую Visual Studio 2015. Опубліковані відповіді, які видаляються за допомогою символів підстановки, для мене все ще клопітні. Я підозрюю, що символи підстановки оцінюються до збірки, а не після . Це означає, що видалення не відбуватиметься, якщо файли, які ви хочете видалити, створюються під час збірки. Це також призводить до чудової поведінки, коли видалення працює кожен другий раз, коли ви створюєте, що робить це все дуже приємним для тестування.

Я відмовляюся від узагальнюючих знаків. Що я роблю, я знаю файли, які викликають проблеми, і я жорстко кодую (якщо це можна назвати так усередині файлу проекту) фактичні імена файлів.


1
Якщо ItemGroup, що використовує символи підстановки, знаходиться всередині Target, його слід оцінювати кожного разу, коли Target виконується. Групи предметів на рівні проекту дійсно оцінюються під час виконання проекту.
Застай
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.