127

我正在使用 Visual Studio 2010 中的新 Web 打包功能进行测试,遇到了一种情况,我使用预构建事件将所需的 .dll 复制到我的应用程序依赖于 API 调用的 bin 文件夹中。它们不能作为参考包含在内,因为它们不是可与互操作一起使用的 COM dll。

当我构建我的部署包时,当我选择仅包含运行应用程序所需的文件的选项时,这些文件将被排除。有没有办法配置部署设置以包含这些文件?我没有找到任何关于此的好的文档。

4

7 回答 7

176

好问题。我刚刚在Web 部署工具 (MSDeploy) 上发布了一个非常详细的博客条目:包含额外文件或排除特定文件的构建包

这是概要。在包含文件之后,我还将展示如何排除文件。

包括额外文件

在包中包含额外的文件有点困难,但如果您对 MSBuild 感到满意,那么仍然没有什么大不了的,如果您不熟悉,请阅读本文。为了做到这一点,我们需要挂钩收集用于打包的文件的过程部分。我们需要扩展的目标称为 CopyAllFilesToSingleFolder。这个目标有一个依赖属性,PipelinePreDeployCopyAllFilesToOneFolderDependsOn,我们可以利用它并注入我们自己的目标。因此,我们将创建一个名为 CustomCollectFiles 的目标并将其注入到进程中。我们通过以下方式实现这一点(请记住在 import 语句之后)。

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

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

这会将我们的目标添加到流程中,现在我们需要定义目标本身。假设您有一个名为 Extra Files 的文件夹,它位于您的 Web 项目上方 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 创建的 Web 应用程序的项目文件,您会在其底部找到一行。

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

顺便说一句,您可以在 VS 中打开项目文件。右键单击项目选择卸载项目。然后右键单击卸载的项目并选择编辑项目。

该声明将包括我们需要的所有目标和任务。如果您不确定是否在之后进行,我们的大多数定制都应该在该导入之后!因此,如果您有要排除的文件,则可以使用项目名称 ExcludeFromPackageFiles 来执行此操作。例如,假设您有一个名为 Sample.Debug.xml 的文件,该文件包含在您的 Web 应用程序中,但您希望将该文件从创建的包中排除。您可以将下面的代码段放在该导入语句之后。

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

通过声明填充此项,文件将被自动排除。请注意FromTarget此处元数据的使用。我不会在这里讨论,但您应该知道始终指定这一点。

于 2010-05-01T03:15:25.360 回答
22

一个更简单的解决方案是编辑 csproj 文件以在 bin 文件夹中包含所需的 dll,然后创建一个 beforebuild 目标以将项目从我们存储第 3 方 dll 的公共库文件夹中复制到 bin 文件夹中。因为该项目存在于解决方案文件中,所以它由 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 文件夹的先前缺点。未经我核实。

于 2011-04-16T05:49:44.110 回答
7

所以赛义德的实施对我不起作用。我正在使用 VS2013 并使用 Web Deploy 包,需要将一些插件 DLL 从另一个文件夹添加到部署包的 bin 中。这是我设法使它工作的方法(更容易):

在您的 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" />
于 2015-04-08T00:12:32.627 回答
6

就像@toxaq 一样,但更简单的解决方案是:

在解决方案资源管理器中将文件添加为库/引用文件夹的链接,然后在属性中将其设置为复制到构建的输出。

于 2011-05-15T03:13:11.400 回答
5

想发表评论以强调 Emil Lerch 的上述评论。如果已安装 Azure SDK,则查找不同的 DependencyProperty。

基本上,您可能需要使用“CopyAllFilesToSingleFolderForMsdeployDependsOn”而不是“CopyAllFilesToSingleFolderForPackageDependsOn”。我并不是一个真正的高级 MsBuild 人,我浪费了数小时试图确定为什么我的目标没有被调用。

如果这对您不起作用并且您已经安装了 Azure SDK,那么这里是另一个链接:http://forums.iis.net/t/1190714.aspx

于 2012-11-17T03:43:13.103 回答
3

作为 Sayed 回答的附录,我发现我的项目中 ExcludeFromPackageFiles 项的静态声明是不够的。我需要排除某些仅编译后才可用的 DLL(部署到 IIS 时不需要的 Azure 特定 Ninject 模块)。

所以我尝试使用上面发布的 CopyAllFilesToSingleFolderForPackageDependsOn 技巧 Sayed 来生成我的 ExcludeFromPackageFiles 列表。但是,这为时已晚,因为打包过程已经删除了 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>

希望对某人有所帮助...

于 2011-05-12T12:57:27.410 回答
1

此外,可以将文件设置为 Content | 始终复制

此外,可以将文件设置为 Content |  始终复制

于 2019-10-24T07:48:12.687 回答