J'essaie d'écrire une tâche MSBuild qui supprime le répertoire Obj et les PDB de mon dossier bin sur mes scripts de génération de production et n'arrive pas à le faire fonctionner correctement.
Quelqu'un at-il un exemple où il fait cela ou similaire, ou un lien vers un exemple simple de suppression de fichiers et d'un répertoire avec MSBuild?
Si vous cherchez à supprimer un répertoire entier, vous avez besoin de la tâche RemoveDir :
<RemoveDir Directories="Path/To/Obj" />
Et si vous souhaitez supprimer les fichiers PDB du bac, vous aurez besoin de la tâche Supprimer :
<Delete Files="Path/To/Bin/MyApp.pdb" />
Notez que vous ne pouvez pas utiliser de caractères génériques dans la tâche Supprimer, donc si vous avez plusieurs fichiers pdb, vous devez fournir un ItemGroup comme argument.
Vous pouvez d'abord supprimer les fichiers de ces répertoires, puis le répertoire lui-même avec
<Target Name="SomeTarget">
<ItemGroup>
<FilesToDelete Include="Path\To\Obj\**\*"/>
</ItemGroup>
<Delete Files="@(FilesToDelete)" />
<RemoveDir Directories="Path\To\Obj\" />
</Target>
Publier pour d'autres personnes qui auraient pu rencontrer le même problème que moi.
La tâche de suppression ne peut pas supprimer les fichiers en lecture seule, ce dont j'avais besoin pour pouvoir le faire, car lorsque MSBuild obtient la dernière version de TFS, les fichiers sont marqués en lecture seule. J'ai utilisé la commande EXEC pour supprimer des fichiers en lecture seule:
<ItemGroup>
<FileToDelete Include="c:\temp\fileToDelete.txt"/>
</ItemGroup>
<Exec Command="del /F /Q "@(FileToDelete)""/>
Les réponses publiées fonctionneront aussi longtemps que vous devrez traiter avec un seul répertoire. Si vous avez des dossiers imbriqués, RemoveDir
échouera avec Directory not empty
Erreur.
Une approche légèrement générique prend également en charge les dossiers imbriqués:
<Target Name="CleanOutDir">
<ItemGroup>
<FilesToClean Include="$(OutDir)\**\*.*" />
<!-- Bit of .Net to get all folders and subfolders -->
<FoldersToClean Include="$([System.IO.Directory]::GetDirectories("$(OutDir)"))" />
</ItemGroup>
<Delete Files="@(FilesToClean)"/>
<RemoveDir Directories="@(FoldersToClean)" />
</Target>
Ce code est si moche qu'il devrait venir avec un sac de mal de l'air. ;-) Mais c'est rapide car il ne construit pas de liste de fichiers à supprimer etc.
<Target Name="DeleteBuildFolder">
<Exec Command="RmDir /S /Q "$(BuildFolder)"" />
<Exec Command="RmDir /S /Q "$(BuildFolder)"" />
<Exec Command="RmDir /S /Q "$(BuildFolder)"" />
<Exec Command="RmDir /S /Q "$(BuildFolder)"" />
<Exec Command="RmDir /S /Q "$(BuildFolder)"" />
<Exec Command="RmDir /S /Q "$(BuildFolder)"" />
<Exec Command="RmDir /S /Q "$(BuildFolder)"" />
</Target>
Combien de commandes RmDir sont nécessaires? Assez donc quelques commandes RmDir renvoient "Le système ne peut pas trouver le fichier spécifié" au lieu de "Le répertoire n'est pas vide". Sur ma machine, il semble prendre un autre RmDir si $ (BuildFolder) est ouvert dans l'Explorateur Windows. Le programme antivirus peut affecter RmDir comme il le fait parfois Subversion, mais je préfère avoir une protection AV globale que (mal) gérer une liste d'exclusion.
Il est également possible de supprimer d'abord la propriété en lecture seule du fichier et d'exécuter la tâche de suppression msbuild.
Ainsi:
<Target Name="DeleteFiles">
<Message Text="Delete File" Importance="high"/>
<Attrib Files="$(FileToDelete)" ReadOnly="false" />
<Delete Files="$(FileToDelete)" />
</Target>`
Dans Visual Studio 2013, j'ai ajouté ceci à la fin de mon fichier .csproj juste avant la balise de fermeture </Project>
<Target Name = "clean_folders" AfterTargets="Clean">
<Exec Command = "rd /S /Q obj" />
<Exec Command = "rd /S /Q bin" />
</Target>
Au début, cela ne semblait pas fonctionner, mais j'ai remarqué que Visual Studio (ou R #, pas sûr) avait de nouveau ajouté DesignTimeResolveAssemblyReferencesInput.cache
Au dossier obj et avait également ajouté le \bin
(J'ai différentes versions dans différents sous-dossiers sous \bin
). Il a nettoyé tout le reste, y compris les 25 autres configurations de construction que j'ai des fichiers .csproj importés (oui, je sais).
Soyez prudent si vous reconstruisez par lots plusieurs configurations car cela efface simplement tous les efforts précédents à chaque reconstruction, vous laissant avec le dernier. Whups.
Juste pour ajouter une autre ride que j'ai découverte. J'utilise Visual Studio 2015. Les réponses publiées qui sont supprimées via un caractère générique sont toujours gênantes pour moi. je soupçonne que les caractères génériques sont évalués avant la construction, pas après. Cela signifie que les suppressions ne se produiront pas si les fichiers que vous souhaitez supprimer sont créés pendant la génération. Cela conduit également à un comportement merveilleux où la suppression fonctionne toutes les deux fois que vous créez, ce qui rend tout cela très agréable à tester.
J'abandonne les caractères génériques. Pour ce que je fais, je connais les fichiers qui causent des problèmes et je code en dur (si cela peut être appelé à l'intérieur d'un fichier de projet) les noms de fichiers réels.