Как включить дополнительные файлы с помощью пакетов веб-развертывания VS2010?


125

Я тестирую новую функциональность веб-упаковки в Visual Studio 2010 и сталкиваюсь с ситуацией, когда я использую событие предварительной сборки для копирования необходимых .dll в папку bin, на которую мое приложение полагается для вызовов API. Их нельзя включить в качестве справочных, поскольку они не являются COM-библиотеками, которые можно использовать с взаимодействием.

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

Ответы:


176

Отличный вопрос. Я только что опубликовал очень подробную запись в блоге об этом в средстве веб-развертывания (MSDeploy): сборка пакета, включая дополнительные файлы или исключая определенные файлы .

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

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

Включение дополнительных файлов в пакет немного сложнее, но все равно неважно, если вам нравится 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). То, что он говорит, - это разместить его в том же относительном месте в пакете, что и в папке Extra Files.

Исключение файлов

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

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

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

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

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

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


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

7
У меня установлен VS2012 (RC), и для меня было другое DependencyProperty. Для поддержки смешанных команд (и нашего сервера сборки) у меня была исходная конфигурация CopyAllFilesToSingleFolderForPackageDependsOn и дубликат с использованием DependencyProperty CopyAllFilesToSingleFolderForMsdeployDependsOn
Эмиль Лерх

2
Это замечательно. Используя это для развертывания некоторой информации о версии, хранящейся в текстовом файле.
lamarant 01

5
Похоже, у меня это не работает. Я использую VStudio 2013. :( Работает ли вышеуказанная установка msbuild на 2013 год?
irperez

8
@SayedIbrahimHashimi и другие. создали более свежую версию этого руководства на веб-сайте asp.net . Я настоятельно рекомендую эту ссылку, так как из-за этого я застрял при изменении файла csproj вместо файла pubxml.
Адам Венеция

21

Более простое решение - отредактировать файл csproj, чтобы включить необходимую dll в папку bin, а затем создать цель beforebuild, чтобы скопировать элемент в папку 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 скрыть запись, тем самым удалив предыдущую обратную сторону видимой папки bin. Не проверено мной.


3
«Простота - это высшая изощренность»
BornToCode 03

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

5
@toxaq, я мог что-то упустить, но проблема, с которой я столкнулся, заключалась в том, что мне действительно нужны файлы в том месте в пакете развертывания, которого не было в папке bin. Итак, да, вы можете скопировать файлы из любого места в папку bin, но они не будут включены в нужное место в пакете развертывания в этом сценарии. Как бы то ни было, ситуация, с которой я столкнулся, была связана с проектом ClearScript.V8 - собственные библиотеки .dll не должны появляться в каталоге bin, а должны появляться в его родительском каталоге - см. Clearscript.codeplex.com/discussions/438696 для обсуждения ,
Натан

3
Если бы я мог, я бы проголосовал еще десять раз. Это должен быть принятый ответ. Я также хотел бы добавить, что вы можете <Visible>false</Visible>скрыть его из обозревателя решений.
tuespetre

1
@Tohid спасибо, внесли это изменение. У меня нет материалов MS для тестирования, поэтому я не проверял это.
toxaq

7

Так же, как @toxaq, но еще более простое решение:

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


3
-1 это предполагает, что проект хочет иметь явную связь компоновщика-времени. Не подходит для систем с
подключаемыми модулями

6

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

Внизу вашего файла csproj добавьте:

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

Другие упоминания в файле 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" />

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

5

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

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

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


3

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

Поэтому я попытался создать свой список ExcludeFromPackageFiles, используя трюк CopyAllFilesToSingleFolderForPackageDependsOn Sayed, опубликованный выше. Однако это слишком поздно, так как процесс упаковки уже удалил элементы 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>

Надеюсь, это кому-то поможет ...


1

Кроме того, можно установить файл как Content | Копировать всегда

Кроме того, можно установить файл как Content |  Копировать всегда


1
Кажется, это должен быть лучший ответ, так как он самый простой и очевидный
Дж. Миглитта,
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.