2010-04-30 3 views
120

Я тестирую, используя новую функциональность веб-упаковки в visual studio 2010, и столкнулся с ситуацией, когда я использую событие предварительной сборки, чтобы скопировать необходимые DLL-файлы в мою папку bin, на которую мое приложение опирается на вызовы API. Они не могут быть включены в качестве ссылки, поскольку они не являются COM-библиотеками, которые могут использоваться с interop.Как вы добавляете дополнительные файлы с помощью пакетов развертывания VS2010?

Когда я создаю свой пакет развертывания, эти файлы исключаются, когда я выбираю вариант включения файлов, необходимых для запуска приложения. Есть ли способ настроить параметры развертывания для включения этих файлов? Мне не повезло найти хорошую документацию по этому поводу.

ответ

161

Большой вопрос. Я только что опубликовал очень подробную запись в блоге об этом на Web Deployment Tool (MSDeploy) : Build Package including extra files or excluding specific files.

Вот краткий обзор. После включения файлов я также показываю, как исключать файлы.

Включая дополнительные файлы

Включая дополнительные файлы в пакет немного сложнее, но до сих пор нет bigee, если вы знакомы с MSBuild, и если вы не то читаете эти строки. Для этого нам нужно подключиться к той части процесса, которая собирает файлы для упаковки. Цель, которую нам нужно расширить, называется CopyAllFilesToSingleFolder. Эта цель имеет свойство зависимости, PipelinePreDeployCopyAllFilesToOneFolderDependsOn, которое мы можем задействовать и внедрить в нашу собственную цель. Таким образом, мы создадим объект с именем CustomCollectFiles и добавим его в этот процесс. Мы достигаем этого со следующим (помните после оператора импорта).

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

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

Это добавит нашу цель процесса, теперь нам нужно определить саму цель. Предположим, что у вас есть папка с надписью Extra Files, которая находится на 1 уровне над вашим веб-проектом. Вы хотите включить все эти файлы. Вот цель CustomCollectFiles, и мы обсудим это.

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

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

Вот что я сделал создать запись _CustomFiles и в Include атрибуте сказал это, чтобы забрать все файлы в этой папке и любую папку под ним. Если вам нужно исключить из этого списка, добавьте Exclude атрибут _CustomFiles.

Затем я использую этот элемент для заполнения элемента FilesForPackagingFromProject. Это элемент, который MSDeploy фактически использует для добавления дополнительных файлов. Также обратите внимание, что я объявил значение метаданных DestinationRelativePath. Это определит относительный путь, который будет помещен в пакет. Я использовал заявление Extra Files% (RecursiveDir)% (Filename)% (Extension) здесь. То, что это говорит, - разместить его в том же относительном местоположении в пакете, что и в папке «Дополнительные файлы».

исключающие файлы

Если открыть файл проекта веб-приложения, созданного с VS 2010 к нижней части его вы найдете строку с.

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

BTW вы можете открыть файл проекта внутри VS. Щелкните правой кнопкой мыши проект, выбрав «Проект разгрузки». Затем щелкните правой кнопкой мыши на выгруженном проекте и выберите «Редактировать проект».

Это заявление будет содержать все цели и задачи, которые нам нужны.Большинство наших настроек должны быть после этого импорта, если вы не уверены, если после! Поэтому, если у вас есть файлы для исключения, есть имя элемента, ExcludeFromPackageFiles, которое можно использовать для этого. Например, предположим, что у вас есть файл с именем Sample.Debug.js, который включен в ваше веб-приложение, но вы хотите, чтобы этот файл был исключен из созданных пакетов. Вы можете поместить сниппет ниже после этого оператора импорта.

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

Объявление путем заполнения этого элемента автоматически исключается. Обратите внимание на использование метаданных FromTarget. Я не буду вдаваться в это здесь, но вы должны знать, чтобы всегда указывать это.

+3

Не могли бы вы расширить ваш пример, чтобы включить дополнительный выпуск проекта в публикацию? –

+0

Есть ли способ получить диагностическую информацию о файлах, которые (или в моем случае не включены) цели? Я задал это как новый вопрос: http://stackoverflow.com/questions/11557915/debugging-msbuild-actions – Overflew

+0

@SayedIbrahimHashimi Можете ли вы использовать эту технику для включения двух наборов файлов? –

21

Более простым решением является отредактировать файл csproj, чтобы включить требуемую DLL в папку bin, а затем создать цель перед созданием для копирования элемента в папку bin из общей папки библиотеки, где мы храним наши DLL-файлы сторонних разработчиков. Поскольку элемент существует в файле решения, он развертывается с помощью msbuild/msdeploy и ничего сложного не требуется.

Тэг используется для включения файла без добавления через VS (который хотите добавить их к VCS обычно)

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

Это цель BeforeBuild, который работал на меня:

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

Отредактировано для включения предложения @ tuespetre, чтобы скрыть запись, удалив предыдущий недостаток папки с видимым бипом. Непроверено мной.

+3

" простота - это высшая сложность " – BornToCode

+1

Это работает во многих случаях, но не работает, если у вас есть файлы, которые необходимо включить вне папки bin. – Nathan

+0

@Nathan это копия, вы можете включить ее из любого места, где у вас есть разрешение на чтение и запись. – toxaq

3

В качестве дополнения к ответу Sayed я обнаружил, что статического объявления элементов ExcludeFromPackageFiles в моем проекте было недостаточно. Мне нужно было исключить определенные библиотеки DLL, которые были доступны только после компилировать (Azure конкретные модули Ninject, которые не нужны при развертывании в IIS).

Итак, я попытался подключиться к генерации моего списка ExcludeFromPackageFiles, используя трюк CopyAllFilesToSingleFolderForPackageDependsOn, сказанный выше. Однако это слишком поздно, так как процесс упаковки уже удалил элементы ExcludeFromPackageFiles. Таким образом, я использовал ту же технику, но чуть раньше:

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

Надеется, что кто-то помогает ...

7

Как @toxaq, но еще более простое решение заключается в следующем:

В explorer explorer добавляет файл в качестве ссылки на папку с библиотекой/ссылками, а затем в свойствах он должен быть скопирован для вывода сборки.

+2

-1 это предполагает, что проект хочет иметь явное отношение линкер-время. Не подходит для подключаемых систем – MickyD

5

Хотел, чтобы комментировать, чтобы подчеркнуть комментарий Эмиля Лерха выше. Если вы установили Azure SDK, найдите другой DependencyProperty.

В принципе, возможно, придется использовать «CopyAllFilesToSingleFolderForMsdeployDependsOn вместо„CopyAllFilesToSingleFolderForPackageDependsOn“. Я не очень продвинутый MsBuild парень, и я впустую часов потянув меня за волосы, пытаясь определить, почему мои цели не вызывался.

Вот еще одна ссылка, если это не сработает для вас, и вы установили Azure SDK: http://forums.iis.net/t/1190714.aspx

5

Реализация Sayed не помогла мне.Я использую VS2013 и использую пакет Web Deploy, и вам нужно добавить некоторые DLL-модули из другой папки в корзину пакета развертывания. Вот как мне удалось заставить его работать (намного проще):

В нижней части файла csproj добавить:

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

Другие mentionables в файле 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" /> 
+0

Спасибо. Я использую VS2015, и мне также нужно добавить DLLS из другой папки bin проекта. Ваше решение было самым простым и работало безупречно. – Rafael