web-dev-qa-db-fra.com

Comment inclure des fichiers supplémentaires à l'aide de packages de déploiement Web VS2010?

Je teste actuellement à l'aide de la nouvelle fonctionnalité de packaging Web dans Visual Studio 2010 et je suis tombé sur une situation où j'utilisais un événement de pré-génération pour copier les fichiers .dll requis dans mon dossier bin sur lequel mon application s'appuie pour les appels d'API. Ils ne peuvent pas être inclus en tant que référence car ce ne sont pas des dll COM pouvant être utilisées avec interop.

Lorsque je crée mon package de déploiement, ces fichiers sont exclus lorsque je choisis l'option d'inclure uniquement les fichiers nécessaires à l'exécution de l'application. Existe-t-il un moyen de configurer les paramètres de déploiement pour inclure ces fichiers? Je n'ai pas eu la chance de trouver une bonne documentation à ce sujet.

124
Jason

Excellente question. Je viens de poster une entrée de blog très détaillée à ce sujet sur le site Outil de déploiement Web (MSDeploy): paquetage de construction incluant des fichiers supplémentaires ou excluant des fichiers spécifiques .

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

Y compris les fichiers supplémentaires

L'inclusion de fichiers supplémentaires dans le paquet est un peu plus difficile, mais cela ne pose aucun problème si vous êtes à l'aise avec MSBuild et si vous ne l'êtes pas, lisez ceci. Pour ce faire, nous devons intégrer la partie du processus qui collecte les fichiers pour l’emballage. La cible à étendre est appelée CopyAllFilesToSingleFolder. Cette cible a une propriété de dépendance, PipelinePreDeployCopyAllFilesToOneFolderDependsOn, que nous pouvons exploiter et injecter notre propre cible. Nous allons donc créer une cible nommée CustomCollectFiles et l'injecter dans le processus. Nous y parvenons comme suit (rappelez-vous après la déclaration d'importation).

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

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

Cela ajoutera notre cible au processus. Nous devons maintenant définir la cible elle-même. Supposons que vous avez un dossier nommé Extra Files qui se situe 1 niveau au-dessus de votre projet Web. Vous voulez inclure tous ces fichiers. Voici la cible CustomCollectFiles et nous en discutons par la suite.

<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 Inclure, lui a demandé de ramasser tous les fichiers de ce dossier et de tous les dossiers situés en dessous. Si par hasard vous avez besoin de exclure Pour ajouter quelque chose de cette liste, ajoutez un attribut Exclude à _CustomFiles.

Ensuite, j'utilise cet élément pour renseigner l'élément FilesForPackagingFromProject. C'est l'élément que MSDeploy utilise réellement pour ajouter des fichiers supplémentaires. Notez également que j'ai déclaré la valeur de métadonnées DestinationRelativePath. Cela déterminera le chemin relatif dans lequel il sera placé. J'ai utilisé l'instruction Extra Files% (RecursiveDir)% (Filename)% (Extension) ici. Cela signifie que vous devez le placer dans le même emplacement relatif dans le package que dans le dossier Extra Files.

Fichiers exclus

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

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

En passant, vous pouvez ouvrir le fichier de projet dans VS. Faites un clic droit sur le projet choisi Décharger le projet. Cliquez ensuite avec le bouton droit sur le projet non chargé et sélectionnez Modifier le projet.

Cette déclaration inclura toutes les cibles et tâches dont nous avons besoin. La plupart de nos personnalisations devraient être faites après cette importation, si vous n'êtes pas sûr de les mettre si après! Ainsi, si vous avez des fichiers à exclure, vous pouvez utiliser un nom d’élément, ExcludeFromPackageFiles. Par exemple, disons que vous avez un fichier nommé Sample.Debug.js qui a été inclus dans votre application Web mais que vous voulez que ce fichier soit exclu des packages créés. Vous pouvez placer l'extrait ci-dessous après cette instruction d'importation.

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

En déclarant remplir cet élément, les fichiers seront automatiquement exclus. Notez l'utilisation des métadonnées FromTarget ici. Je ne parlerai pas de cela ici, mais vous devriez savoir de toujours le préciser.

171

Une solution plus simple consiste à éditer le fichier csproj pour inclure la dll requise dans le dossier bin, puis à créer une cible beforebuild pour copier l’élément dans le dossier bin à partir du dossier de la bibliothèque commune dans lequel nous stockons nos dll tierces. 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 un fichier sans ajouter via 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 masquer l'entrée, éliminant ainsi les inconvénients précédents d'un dossier bin visible. Non vérifié par moi.

21
toxaq

Comme @toxaq, une solution encore plus simple consiste à:

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

7
eglasius

Donc, la mise en œuvre de Sayed n'a pas fonctionné pour moi. J'utilise VS2013 et le package Web Deploy et je dois ajouter des DLL de plug-in à partir d'un autre dossier dans le bac du package de déploiement. Voici comment j'ai réussi à le faire fonctionner (beaucoup plus facilement):

Au bas de votre fichier csproj, ajoutez:

<Target Name="AdditionalFilesForPackage" AfterTargets="CopyAllFilesToSingleFolderForMsdeploy">
    <ItemGroup> 
        <Files Include="..\SomeOtherProject\bin\$(Configuration)\*.*"/>
    </ItemGroup>
    <Copy SourceFiles="@(Files)" DestinationFolder="$(_PackageTempDir)\bin\" />  
</Target>

Autres mentables dans le fichier csproj:

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>Prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <DeployOnBuild>true</DeployOnBuild>
    <DeployTarget>Package</DeployTarget>
    <DeployIisAppPath>Default Web Site/MyWebsite</DeployIisAppPath>
    <DesktopBuildPackageLocation>..\output\Service\Service\Service.Release.Zip</DesktopBuildPackageLocation>
    <FilesToIncludeForPublish>OnlyFilesToRunTheApp</FilesToIncludeForPublish>
    <ExcludeGeneratedDebugSymbol>true</ExcludeGeneratedDebugSymbol>
    <PublishDatabases>false</PublishDatabases>
</PropertyGroup>

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

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

Fondamentalement, vous devrez peut-être utiliser "CopyAllFilesToSingleFolderForMsdeployDependsOn au lieu de" CopyAllFilesToSingleFolderForPackageDependsOn ". Je ne suis pas vraiment un gars avancé de MsBuild et je passais des heures à me tirer les cheveux en essayant de déterminer pourquoi mes cibles ne s'appelaient pas.

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

5
Paul Schroeder

En complément de la réponse de Sayed, j'ai constaté qu'une déclaration statique d'éléments ExcludeFromPackageFiles dans mon projet ne suffisait pas. J'avais besoin d'exclure certaines DLL qui n'étaient disponibles que 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 créer ma liste ExcludeFromPackageFiles en utilisant le truc CopyAllFilesToSingleFolderForPackageDependsOn Sayed posté ci-dessus. Toutefois, cela 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 ça aide quelqu'un ...

3
Peter McEvoy