【问题标题】:How do you include additional files using VS2010 web deployment packages?如何使用 VS2010 Web 部署包包含附加文件?
【发布时间】:2010-04-30 19:23:51
【问题描述】:

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

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

【问题讨论】:

    标签: visual-studio-2010 visual-studio web-deployment msdeploy


    【解决方案1】:

    很好的问题。我刚刚在Web Deployment Tool (MSDeploy) : Build Package including extra files or excluding specific files 上发布了一篇非常详细的博客文章。

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

    包括额外文件

    在包中包含额外的文件有点困难,但如果您对 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 应用程序中,但您希望将该文件从创建的包中排除。您可以将 sn-p 放在该 import 语句之后。

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

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

    【讨论】:

    • 您能否扩展您的示例以将其他项目输出包含到发布中?
    • 我安装了 VS2012 (RC),对我来说有一个不同的 DependencyProperty。为了支持混合团队(和我们的构建服务器),我使用了 DependencyProperty CopyAllFilesToSingleFolderForMsdeployDependsOn 的原始 CopyAllFilesToSingleFolderForPackageDependsOn 配置副本
    • 这太棒了。使用它来部署一些存储在 txt 文件中的版本信息。
    • 这似乎对我不起作用。我正在使用 VStudio 2013。:( 上面的 msbuild 设置是否适用于 2013 年?
    • @SayedIbrahimHashimi 和 co。在asp.net website 上创建了本指南的更新版本。我强烈推荐这个链接,因为那是我在修改 csproj 文件而不是 pubxml 文件时遇到问题的区别。
    【解决方案2】:

    一个更简单的解决方案是编辑 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 文件夹的先前缺点。未经我验证。

    【讨论】:

    • “简约才是极致”
    • 这在很多情况下都有效,但如果您有需要包含在 bin 文件夹之外的文件,则无效。
    • @Nathan 这是一个副本,你可以在任何你有读写权限的地方包含它。
    • @toxaq,我可能遗漏了一些东西,但我遇到的问题是我实际上需要部署包中一个位置中的文件 not 在 bin 文件夹中。所以是的,您可以将文件从任何地方复制到 bin 文件夹,但在这种情况下,它们不会包含在部署包中的正确位置。对于它的价值,我遇到的情况是 ClearScript.V8 项目 - 本机 .dll 必须出现在 bin 目录中,但必须出现在其父目录中 - 请参阅 clearscript.codeplex.com/discussions/438696讨论。
    • @Tohid 谢谢,进行了编辑。没有任何 MS 的东西可以测试,所以我没有验证它。
    【解决方案3】:

    所以 Sayed 的实施对我不起作用。我正在使用 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" />
    

    【讨论】:

    • 谢谢。我正在使用 VS2015,我还需要从另一个项目 bin 文件夹中添加 DLLS。您的解决方案是最简单的,而且运行良好。
    【解决方案4】:

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

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

    【讨论】:

    • -1 这假设项目希望有一个明确的链接器时间关系。不适用于插件式系统
    【解决方案5】:

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

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

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

    【讨论】:

      【解决方案6】:

      作为 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>
      

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

      【讨论】:

        【解决方案7】:

        另外,可以将文件设置为 Content |一直复制

        【讨论】:

        • 似乎这应该是最佳答案,因为它是最简单和最明显的
        • 但前提是它是项目的一部分。否则此选项不可用。
        猜你喜欢
        • 2016-03-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-08-15
        相关资源
        最近更新 更多