127 votes

Comment inclure des fichiers supplémentaires en utilisant les paquets de déploiement web de VS2010 ?

Je suis en train de tester l'utilisation de la nouvelle fonctionnalité de packaging web dans Visual Studio 2010 et j'ai rencontré une situation où j'utilise un événement pré-build pour copier les .dll nécessaires dans mon dossier bin sur lequel mon application repose pour les appels API. Ils ne peuvent pas être inclus en tant que référence car ce ne sont pas des dll COM qui peuvent être utilisées avec l'interopérabilité.

Lorsque je construis mon paquet de déploiement, ces fichiers sont exclus lorsque je choisis l'option de n'inclure que les fichiers requis pour exécuter l'application. Existe-t-il un moyen de configurer les paramètres de déploiement pour inclure ces fichiers ? Je n'ai pas eu de chance de trouver une bonne documentation à ce sujet.

176voto

Sayed Ibrahim Hashimi Points 25707

Excellente question. Je viens de publier un article de blog très détaillé à ce sujet à l'adresse suivante Outil de déploiement Web (MSDeploy) : Construire le paquet en incluant des fichiers supplémentaires ou en excluant des fichiers spécifiques .

Voici le synopsis. Après avoir inclus des fichiers, je montre comment les exclure également.

Inclure des fichiers supplémentaires

L'inclusion de fichiers supplémentaires dans le paquet est un peu plus difficile, mais ce n'est pas grave si vous êtes à l'aise avec MSBuild, et si vous ne l'êtes pas, lisez ceci. Pour ce faire, nous devons nous connecter à la partie du processus qui collecte les fichiers à empaqueter. La cible que nous devons étendre s'appelle CopyAllFilesToSingleFolder. Cette cible possède une propriété de dépendance, PipelinePreDeployCopyAllFilesToOneFolderDependsOn, dans laquelle nous pouvons puiser pour injecter notre propre cible. Nous allons donc créer une cible nommée CustomCollectFiles et l'injecter dans le processus. Nous y parviendrons avec ce qui suit (rappelez-vous après l'instruction import).

<PropertyGroup>
  <CopyAllFilesToSingleFolderForPackageDependsOn>
    CustomCollectFiles;
    $(CopyAllFilesToSingleFolderForPackageDependsOn);
  </CopyAllFilesToSingleFolderForPackageDependsOn>

  <CopyAllFilesToSingleFolderForMsdeployDependsOn>
    CustomCollectFiles;
    $(CopyAllFilesToSingleFolderForMsdeployDependsOn);
  </CopyAllFilesToSingleFolderForMsdeployDependsOn>
</PropertyGroup>

Cela ajoutera notre cible au processus, maintenant nous devons définir la cible elle-même. Supposons que vous ayez un dossier nommé Extra Files qui se trouve 1 niveau au-dessus de votre projet web. Vous voulez inclure tous ces fichiers. Voici la cible CustomCollectFiles et nous discutons après cela.

<Target Name="CustomCollectFiles">
  <ItemGroup>
    <_CustomFiles Include="..\Extra Files\**\*" />

    <FilesForPackagingFromProject  Include="%(_CustomFiles.Identity)">
      <DestinationRelativePath>Extra Files\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
    </FilesForPackagingFromProject>
  </ItemGroup>
</Target>

Ici, j'ai créé l'élément _CustomFiles et, dans l'attribut Include, je lui ai demandé de récupérer tous les fichiers de ce dossier et de tout dossier inférieur. Si par hasard vous avez besoin de exclure quelque chose de cette liste, ajoutez un Exclude de l'attribut _CustomFiles .

J'utilise ensuite cet élément pour alimenter l'élément FilesForPackagingFromProject. C'est l'élément que MSDeploy utilise réellement pour ajouter des fichiers supplémentaires. Remarquez également que j'ai déclaré la valeur DestinationRelativePath de la métadonnée. Cela déterminera le chemin relatif dans lequel il sera placé dans le paquet. J'ai utilisé la déclaration Extra Files%(RecursiveDir)%(Filename)%(Extension) ici. Cela signifie qu'il faut le placer dans le paquet au même endroit relatif qu'il se trouve dans le dossier Extra Files.

Exclusion de fichiers

Si vous ouvrez le fichier de projet d'une application web créée avec VS 2010, vers le bas de celui-ci, vous trouverez une ligne avec.

<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />

En fait, vous pouvez ouvrir le fichier du projet dans VS. Faites un clic droit sur le projet et choisissez "Unload Project". Ensuite, faites un clic droit sur le projet déchargé et sélectionnez Edit Project.

Cette déclaration comprendra tous les objectifs et toutes les tâches dont nous avons besoin. La plupart de nos personnalisations devraient se faire après cette importation, si vous n'êtes pas sûr, mettez "si" après ! Si vous avez des fichiers à exclure, il existe un élément, ExcludeFromPackageFiles, qui peut être utilisé pour le faire. Par exemple, disons que vous avez un fichier nommé Sample.Debug.xml qui est inclus dans votre application web mais que vous voulez que ce fichier soit exclu des paquets créés. Vous pouvez placer le snippet ci-dessous après l'instruction import.

<ItemGroup>
  <ExcludeFromPackageFiles Include="Sample.Debug.xml">
    <FromTarget>Project</FromTarget>
  </ExcludeFromPackageFiles>
</ItemGroup>

En déclarant le remplissage de cet élément, les fichiers seront automatiquement exclus. Notez l'utilisation de l'élément FromTarget métadonnées ici. Je ne m'y attarderai pas ici, mais vous devez savoir qu'il faut toujours le spécifier.

3 votes

Pourriez-vous étendre votre exemple afin d'inclure des sorties de projet supplémentaires dans la publication ?

0 votes

Existe-t-il un moyen d'obtenir des informations de diagnostic sur les fichiers qui sont (ou dans mon cas, ne sont pas) inclus par la cible ? J'ai posé cette question en tant que nouvelle question stackoverflow.com/questions/11557915/debugging-msbuild-actions

0 votes

@SayedIbrahimHashimi Pouvez-vous utiliser cette technique pour inclure deux ensembles de fichiers ?

22voto

toxaq Points 2427

Une solution plus simple est d'éditer le fichier csproj pour inclure la dll requise dans le dossier bin et ensuite de créer une cible beforebuild pour copier l'élément dans le dossier bin à partir du dossier common library où nous stockons nos dlls tiers. Comme l'élément existe dans le fichier de solution, il est déployé par msbuild/msdeploy et rien de compliqué n'est nécessaire.

Balise utilisée pour inclure le fichier sans passer par VS (qui voudra généralement l'ajouter à votre VCS).

<Content Include="Bin\3rdPartyNative.dll" ><Visible>false</Visible></Content>

C'est la cible BeforeBuild qui a fonctionné pour moi :

<Target Name="BeforeBuild">
    <Message Text="Copy $(SolutionDir)Library\3rdPartyNative.dll to '$(TargetDir)'3rdPartyNative.dll" Importance="high" />
    <Copy SourceFiles="$(SolutionDir)Library\3rdPartyNative.dll" DestinationFiles="$(TargetDir)3rdPartyNative.dll" />
</Target>

Modifié pour inclure la suggestion de @tuespetre de cacher l'entrée, supprimant ainsi l'inconvénient précédent d'un dossier de poubelle visible. Non vérifié par moi.

3 votes

"la simplicité est la sophistication ultime"

1 votes

Cela fonctionne dans de nombreux cas, mais ne fonctionne pas si vous avez des fichiers qui doivent être inclus en dehors du dossier bin.

0 votes

@Nathan c'est une copie, vous pouvez l'inclure à partir de n'importe quel endroit où vous avez la permission de lire et d'écrire.

7voto

eglasius Points 26221

Tout comme @toxaq, mais une solution encore plus simple consiste à :

Dans l'explorateur de solutions, ajoutez le fichier en tant que lien dans le dossier bibliothèque/références, puis dans les propriétés, définissez-le pour qu'il soit copié dans la sortie de la construction.

3 votes

-1 cela suppose que le projet souhaite avoir une relation explicite entre le linker et le temps. Ne convient pas aux systèmes de type plug-in

5voto

Paul Schroeder Points 51

Je voulais faire un commentaire pour souligner le commentaire d'Emil Lerch ci-dessus. Si vous avez installé un SDK Azure, recherchez une DependencyProperty différente.

En gros, vous devrez peut-être utiliser "CopyAllFilesToSingleFolderForMsdeployDependsOn" au lieu de "CopyAllFilesToSingleFolderForPackageDependsOn". Je ne suis pas vraiment un spécialiste de MsBuild et j'ai passé des heures à m'arracher les cheveux à essayer de déterminer pourquoi mes cibles n'étaient pas appelées.

Voici un autre lien si cela ne fonctionne pas pour vous et que vous avez installé un SDK Azure : http://forums.iis.net/t/1190714.aspx

3voto

Peter McEvoy Points 1653

En complément de la réponse de Sayed, j'ai trouvé qu'une déclaration statique des éléments ExcludeFromPackageFiles dans mon projet n'était pas suffisante. J'avais besoin d'exclure certaines DLLs qui étaient seulement disponibles après compiler (modules Ninject spécifiques à Azure qui ne sont pas nécessaires lorsque je déploie sur IIS).

J'ai donc essayé de générer ma liste ExcludeFromPackageFiles en utilisant l'astuce CopyAllFilesToSingleFolderForPackageDependsOn que Sayed a postée ci-dessus. Cependant, c'est trop tard car le processus d'emballage a déjà supprimé les éléments ExcludeFromPackageFiles. J'ai donc utilisé la même technique, mais un peu plus tôt :

<PropertyGroup>
    <ExcludeFilesFromPackageDependsOn>
        $(ExcludeFilesFromPackageDependsOn);
        _ExcludeAzureDlls
    </ExcludeFilesFromPackageDependsOn>
</PropertyGroup>

<Target Name="_ExcludeAzureDlls">
    <ItemGroup>
        <FilesForPackagingFromProjectWithNoAzure Include="@(FilesForPackagingFromProject)"
                               Exclude="%(RootDir)%(Directory)*Azure*.dll" />
        <AzureFiles Include="@(FilesForPackagingFromProject)"
                    Exclude="@(FilesForPackagingFromProjectWithNoAzure)" />
        <ExcludeFromPackageFiles Include="@(AzureFiles)">
            <FromTarget>_ExcludeAzureEnvironmentDlls</FromTarget>
        </ExcludeFromPackageFiles>
    </ItemGroup>
</Target>

J'espère que cela aidera quelqu'un...

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X