Як ви включаєте додаткові файли за допомогою пакетів веб-розгортання VS2010?


125

Я тестую, використовуючи нову функціональність веб-упаковки у візуальній студії 2010, і натрапив на ситуацію, коли я використовую подію попереднього збирання, щоб скопіювати потрібні. Вони не можуть бути включені в якості посилань, оскільки вони не є COM-колами, які можна використовувати з interop.

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

Відповіді:


176

Чудове запитання. Щойно я опублікував дуже детальну запис про це в блозі в Інструменті веб-розгортання (MSDeploy): Пакет збірки, включаючи додаткові файли або виключаючи конкретні файли .

Ось конспект Після включення файлів я показую, як виключити файли.

У тому числі додаткові файли

Додавання додаткових файлів до пакету трохи складніше, але все-таки жодного клопату, якщо вам зручно з MSBuild, і якщо ви цього ще не прочитали. Для цього нам потрібно підключити частину процесу, який збирає файли для упаковки. Ціль, яку нам потрібно розширити, називається CopyAllFilesToSingleFolder. Ця ціль має властивість залежності - PipelinePreDeployCopyAllFilesToOneFolderDependsOn, яку ми можемо використовувати та вводити власну ціль. Таким чином, ми створимо ціль під назвою CustomCollectFiles і введемо її в процес. Ми досягаємо цього наступним чином (пам’ятайте після заяви про імпорт).

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

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

Це додасть нашій цілі до процесу, тепер нам потрібно визначити саму ціль. Припустимо, у вас є папка з назвою "Додаткові файли", яка знаходиться на 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 і в атрибуті Включити сказав йому зібрати всі файли в цій папці та будь-яку папку під нею. Якщо випадково вам потрібно виключити щось із цього списку, додайте Excludeатрибут до _CustomFiles.

Потім я використовую цей елемент, щоб заповнити елемент FilesForPackagingFromProject. Це предмет, який MSDeploy фактично використовує для додавання додаткових файлів. Також зауважте, що я оголосив метадані значення DestinationRelativePath. Це визначить відносний шлях, який він буде розміщений в пакеті. Тут я використовував оператор Додаткові файли% (RecursiveDir)% (Ім'я файлу)% (Розширення). Це говорить про те, щоб розмістити його в тому самому відносному місці в пакеті, що і в папці "Додаткові файли".

Виключення файлів

Якщо ви відкриєте файл проекту веб-програми, створеної за допомогою VS 2010, внизу, ви знайдете рядок.

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

До речі, ви можете відкрити файл проекту всередині VS. Клацніть правою кнопкою миші на виборі проекту Unload Project. Потім клацніть правою кнопкою миші на завантажений проект і виберіть «Змінити проект».

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

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

При оголошенні заповнення цього елемента файли автоматично будуть виключені. Зверніть увагу на використання FromTargetметаданих тут. Я не вникатиму в це тут, але ви повинні знати, що завжди це вказуйте.


3
Чи можете ви розширити свій приклад, щоб включити додатковий вихідний проект у публікацію?
Антоній Сердюков

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

2
Це чудово. Використовуючи це для розгортання деякої інформації про версію, що зберігається у файлі txt.
ламаран

5
Це, здається, не працює для мене. Я використовую VStudio 2013. :( Чи працює вищевказана установка
msbuild

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

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
Це працює у багатьох випадках, але не працює, якщо у вас є файли, які потрібно включити за межі папки.
Натан

5
@toxaq, я міг щось пропустити, але проблема, з якою я зіткнулася, полягала в тому, що мені насправді потрібні файли в розташуванні в пакеті розгортання, який не знаходився в папці бін. Так, так, ви можете скопіювати файли з будь-якого місця в папку bin, але вони не будуть включені в потрібне місце в пакеті розгортання в цьому сценарії. Наскільки це варте, ситуація, з якою я зіткнувся, була з проектом ClearScript.V8 - нативні .dlls не повинні відображатися в каталозі бін, а повинні з’являтися в його батьківському - для обговорення див. Clearscript.codeplex.com/discussions/438696 .
Натан

3
Я б підніс ще десять разів, якби міг. Це має бути прийнятою відповіддю. Я також хотів би додати, що ви можете налаштувати <Visible>false</Visible>його приховати від Провідника рішень.
вівторок

1
@До дякую, внесли цю редакцію. Немає матеріалів для тестування, тому я не підтверджував це.
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, і мені також потрібно було додати DLLS з іншої папки бін проекту. Ваше рішення було найпростішим і працювало бездоганно.
Рафаель

5

Хотів прокоментувати, щоб підкреслити коментар Еміля Лерча вище. Якщо ви встановили пакет SDK Azure, то знайдіть іншу властивість DependencyProperty.

В основному, вам може знадобитися використовувати "CopyAllFilesToSingleFolderForMsdeployDependsOn замість" CopyAllFilesToSingleFolderForPackageDependsOn ". Я насправді не просунутий хлопець MsBuild, і я витрачав години на витягування волосся, намагаючись визначити, чому мої цілі не викликали.

Ось ще одне посилання, якщо це не працює для вас, і ви встановили пакет SDK Azure: http://forums.iis.net/t/1190714.aspx


3

Як доповнення до відповіді Саєда, я виявив, що статичної декларації елементів ExcludeFromPackageFiles в рамках мого проекту недостатньо. Мені потрібно було виключити певні DLL-файли, які були доступні лише після компіляції (конкретні модулі Ninject Azure, які не потрібні, коли я розгортаюсь до 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>

Сподіваюся, що хтось допомагає ...


1

Також можна встановити файл як Вміст | Копіюйте завжди

Також можна встановити файл як Вміст |  Копіюйте завжди


1
Здається, це має бути головною відповіддю, оскільки це найпростіше і очевидніше
J Miglietta,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.