Come si includono file aggiuntivi utilizzando i pacchetti di distribuzione Web VS2010?


125

Sto testando utilizzando la nuova funzionalità di packaging Web in Visual Studio 2010 e mi sono imbattuto in una situazione in cui utilizzo un evento pre-build per copiare i dll necessari nella mia cartella bin su cui si basa la mia app per le chiamate API. Non possono essere inclusi come riferimento poiché non sono DLL COM che possono essere utilizzate con l'interoperabilità.

Quando creo il mio pacchetto di distribuzione, quei file vengono esclusi quando scelgo l'opzione per includere solo i file necessari per eseguire l'app. C'è un modo per configurare le impostazioni di distribuzione per includere questi file? Non ho avuto fortuna a trovare buona documentazione su questo.

Risposte:


176

Ottima domanda Ho appena pubblicato un post di blog molto dettagliato al riguardo su Web Deployment Tool (MSDeploy): Build Package con file extra o esclusione di file specifici .

Ecco la sinossi. Dopo aver incluso i file, mostro anche come escludere i file.

Compresi file extra

Includere file extra nel pacchetto è un po 'più difficile ma non è ancora un problema se sei a tuo agio con MSBuild e se non lo sei, leggi questo. Per fare ciò dobbiamo agganciarci alla parte del processo che raccoglie i file per il packaging. L'obiettivo che dobbiamo estendere si chiama CopyAllFilesToSingleFolder. Questo target ha una proprietà di dipendenza, PipelinePreDeployCopyAllFilesToOneFolderDependsOn, che possiamo attingere e iniettare il nostro target. Quindi creeremo un target chiamato CustomCollectFiles e lo inietteremo nel processo. Otteniamo questo risultato nel modo seguente (ricordare dopo la dichiarazione di importazione).

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

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

Ciò aggiungerà il nostro obiettivo al processo, ora dobbiamo definire l'obiettivo stesso. Supponiamo che tu abbia una cartella chiamata Extra Files che si trova 1 livello sopra il tuo progetto web. Vuoi includere tutti quei file. Ecco il target CustomCollectFiles e ne discuteremo dopo.

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

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

Qui quello che ho fatto è stato creare l'elemento _CustomFiles e nell'attributo Include gli ha detto di raccogliere tutti i file in quella cartella e qualsiasi cartella sottostante. Se per caso è necessario escludere qualcosa dall'elenco, aggiungere un Excludeattributo a _CustomFiles.

Quindi uso questo articolo per popolare l'elemento FilesForPackagingFromProject. Questo è l'elemento che MSDeploy utilizza effettivamente per aggiungere file extra. Si noti inoltre che ho dichiarato il valore DestinationRelativePath dei metadati. Ciò determinerà il percorso relativo che verrà inserito nel pacchetto. Ho usato l'istruzione File extra% (RecursiveDir)% (Nome file)% (Estensione) qui. Ciò che sta dicendo è posizionarlo nella stessa posizione relativa nel pacchetto in cui si trova nella cartella File extra.

Escludendo i file

Se apri il file di progetto di un'applicazione web creata con VS 2010 verso il fondo, troverai una riga con.

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

A proposito, puoi aprire il file di progetto all'interno di VS. Fare clic con il tasto destro del mouse sul progetto, selezionare Scarica progetto. Quindi fare clic con il tasto destro del mouse sul progetto scaricato e selezionare Modifica progetto.

Questa dichiarazione includerà tutti gli obiettivi e le attività di cui abbiamo bisogno. La maggior parte delle nostre personalizzazioni dovrebbe avvenire dopo tale importazione, se non si è sicuri di averlo fatto dopo! Quindi, se hai dei file da escludere, c'è un nome articolo, ExcludeFromPackageFiles, che può essere usato per farlo. Ad esempio, supponiamo che tu abbia un file chiamato Sample.Debug.xml che includeva nella tua applicazione web ma che vuoi che quel file venga escluso dai pacchetti creati. Puoi posizionare lo snippet di seguito dopo tale istruzione di importazione.

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

Dichiarando il popolamento di questo elemento, i file verranno automaticamente esclusi. Nota qui l'uso dei FromTargetmetadati. Non entrerò in questo qui, ma dovresti sapere di specificarlo sempre.


3
Potresti estendere il tuo esempio per includere l'output del progetto aggiuntivo nella pubblicazione?
Anthony Serdyukov,

7
Ho VS2012 (RC) installato e per me c'era una DependencyProperty diversa. Per supportare team misti (e il nostro server di build), avevo l'originale CopyAllFilesToSingleFolderForPackageDependsOn configuration e un duplicato usando DependencyProperty CopyAllFilesToSingleFolderForMsdeployDependsOn
Emil Lerch

2
Questo è meraviglioso. Usandolo per distribuire alcune informazioni sulla versione memorizzate in un file txt.
Lamarant,

5
Questo non sembra funzionare per me. Sto usando VStudio 2013. :( Il setup di msbuild sopra funziona per il 2013?
irperez,

8
@SayedIbrahimHashimi and co. hanno creato una versione molto più aggiornata di questa guida sul sito Web asp.net . Consiglio vivamente questo link, poiché questa è stata la differenza tra me bloccandomi a modificare il file csproj invece del file pubxml.
Adam Venezia

21

Una soluzione più semplice è quella di modificare il file csproj per includere la dll richiesta nella cartella bin e quindi creare una destinazione pre-build per copiare l'elemento nella cartella bin dalla cartella della libreria comune in cui archiviamo le nostre dll di terze parti. Poiché l'elemento esiste nel file della soluzione, viene distribuito da msbuild / msdeploy e non è necessario nulla di complicato.

Tag usato per includere il file senza aggiungerlo tramite VS (che di solito vorrà aggiungerlo al VCS)

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

Questo è l'obiettivo di BeforeBuild che ha funzionato per me:

<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>

Modificato per includere il suggerimento di @ tuespetre di nascondere la voce rimuovendo così il rovescio della medaglia di una cartella bin visibile. Non verificato da me.


3
"la semplicità è la massima raffinatezza"
BornToCode

1
Funziona in molti casi, ma non funziona se si hanno file che devono essere inclusi al di fuori della cartella bin.
Nathan,

5
@toxaq, potrei mancare qualcosa, ma il problema che ho riscontrato è che avevo effettivamente bisogno dei file in una posizione nel pacchetto di distribuzione che non si trovava nella cartella bin. Quindi sì, è possibile copiare i file da qualsiasi luogo nella cartella bin, ma non saranno inclusi nella posizione corretta nel pacchetto di distribuzione in quello scenario. Per quello che vale, la situazione in cui mi sono imbattuto è stata con il progetto ClearScript.V8 - i dll nativi non devono apparire nella directory bin, ma devono apparire nel suo genitore - vedi clearscript.codeplex.com/discussions/438696 per la discussione .
Nathan,

3
Vorrei votare altre dieci volte se potessi. Questa dovrebbe essere la risposta accettata. Vorrei anche aggiungere che è possibile impostare <Visible>false</Visible>per nasconderlo da Esplora soluzioni.
tuespetre,

1
@ Grazie grazie, hai apportato questa modifica. Non ho roba MS con cui testare, quindi non l'ho verificato.
Toxaq,

7

Proprio come @toxaq, ma una soluzione ancora più semplice è:

In Esplora soluzioni aggiungi il file come collegamento alla cartella librerie / riferimenti, quindi nelle proprietà impostalo per essere copiato nell'output della build.


3
-1 questo presuppone che il progetto desideri avere una relazione esplicita tra linker e tempo. Non adatto per sistemi di tipo plug-in
MickyD

6

Quindi l'implementazione di Sayed non ha funzionato per me. Sto usando VS2013 e sto usando il pacchetto Web Deploy e dovevo aggiungere alcune DLL di plugin da un'altra cartella nel cestino del pacchetto deploy. Ecco come sono riuscito a farlo funzionare (molto più facilmente):

Nella parte inferiore del tuo file csproj aggiungi:

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

Altri menzionabili nel file 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" />

Grazie. Sto usando VS2015 e avevo anche bisogno di aggiungere DLLS da un'altra cartella bin del progetto. La tua soluzione è stata la più semplice e ha funzionato perfettamente.
Rafael,

5

Volevo commentare per sottolineare il commento di Emil Lerch sopra. Se è stato installato un SDK di Azure, cercare un'altra DependencyProperty.

Fondamentalmente, potresti dover usare "CopyAllFilesToSingleFolderForMsdeployDependsOn invece di" CopyAllFilesToSingleFolderForPackageDependsOn ". Non sono davvero un ragazzo MsBuild avanzato e ho perso ore a strapparmi i capelli cercando di capire perché i miei obiettivi non venivano chiamati.

Ecco un altro collegamento se questo non funziona per te e hai installato Azure SDK: http://forums.iis.net/t/1190714.aspx


3

Come addendum alla risposta di Sayed, ho scoperto che una dichiarazione statica di elementi ExcludeFromPackageFiles all'interno del mio progetto non era sufficiente. Ho dovuto escludere alcune DLL che erano disponibili solo dopo la compilazione (moduli Ninject specifici di Azure che non sono necessari quando eseguo la distribuzione su IIS).

Quindi ho provato ad agganciarmi nel generare la mia lista ExcludeFromPackageFiles usando CopyAllFilesToSingleFolderForPackageDependsOn trucco Detto precedentemente pubblicato. Tuttavia, questo è troppo tardi poiché il processo di imballaggio ha già rimosso gli articoli ExcludeFromPackageFiles. Quindi, ho usato la stessa tecnica, ma un po 'prima:

<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>

Spero che aiuti qualcuno ...


1

Inoltre, è possibile impostare il file come Contenuto | Copia sempre

Inoltre, è possibile impostare il file come Contenuto |  Copia sempre


1
Sembra che questa dovrebbe essere la risposta migliore in quanto è la più semplice e ovvia
J Miglietta,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.