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

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

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

Ответы [ 6 ]

169 голосов
/ 01 мая 2010

Отличный вопрос. Я только что опубликовал очень подробную запись в блоге об этом на Инструмент веб-развертывания (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) здесь. Это означает, что он должен находиться в том же относительном месте в пакете, что и в папке «Дополнительные файлы».

Исключая файлы

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

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

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

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

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

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

21 голосов
/ 16 апреля 2011

Более простое решение состоит в том, чтобы отредактировать файл 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. Не проверено мной.

7 голосов
/ 15 мая 2011

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

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

6 голосов
/ 08 апреля 2015

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

В нижней части вашего файла 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" />
5 голосов
/ 17 ноября 2012

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

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

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

3 голосов
/ 12 мая 2011

В качестве дополнения к ответу Сайеда я обнаружил, что статического объявления элементов 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>

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

...