Как включить дополнительные файлы с помощью пакетов веб-развертывания 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. Не проверено мной.

toxaq
источник
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, но еще более простое решение:

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

eglasius
источник
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" />
K0D4
источник
Спасибо. Я использую 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 |  Копировать всегда

Fabito
источник
1
Кажется, это должен быть лучший ответ, так как он самый простой и очевидный
Дж. Миглитта,