如何使用VS2010 Web部署程序包包含其他文件?


125

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

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

Answers:


176

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

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

包括额外文件

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

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

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

这会将我们的目标添加到流程中,现在我们需要定义目标本身。假设您有一个名为Extra Files的文件夹,该文件夹位于Web项目的上一级。您要包括所有这些文件。这是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应用程序中,但是您希望将该文件从创建的包中排除。您可以将该代码段放在该import语句之后。

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

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


3
您可以扩展您的示例以便将其他项目输出包含到发布中吗?
Anthony Serdyukov

7
我已经安装了VS2012(RC),对我来说还有一个不同的DependencyProperty。为了支持混合团队(和我们的构建服务器),我拥有原始的CopyAllFilesToSingleFolderForPackageDependsOn配置,使用DependencyProperty CopyAllFilesToSingleFolderForMsdeployDependsOn复制了副本
Emil Lerch,

2
太好了 使用它来部署一些存储在txt文件中的版本信息。
lamarant

5
这似乎对我不起作用。我正在使用VStudio2013。:(以上msbuild设置是否适用于2013?
irperez 2014年

8
@SayedIbrahimHashimi和co。已在asp.net网站上创建了本指南的最新版本。我强烈建议该链接,因为那是我无法修改csproj文件而不是pubxml文件之间的区别。
Adam Venezia

21

一个更简单的解决方案是编辑csproj文件以在bin文件夹中包含所需的dll,然后创建一个beforebuild目标,以将项目从我们存储第三方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文件夹的先前缺点。我未验证。


3
“简单是终极的成熟”
BornToCode

1
这在许多情况下都可以使用,但是如果您需要将文件包含在bin文件夹之外,则无法使用。
内森

5
@toxaq,我可能会丢失一些东西,但是我遇到的问题是,我实际上需要部署文件夹中bin文件夹中没有的文件。因此,可以的,您可以将文件从任何位置复制到bin文件夹,但是在这种情况下,它们将不会包含在部署包中的正确位置。对于它的价值,我遇到的情况是ClearScript.V8项目-本机.dll 不得出现在bin目录中,而必须出现在其父目录中- 有关讨论,请参见clearscript.codeplex.com/discussions/438696
内森2013年

3
如果可以的话,我会再投票十次。这应该是公认的答案。我还想补充一点,您可以设置<Visible>false</Visible>为从解决方案资源管理器中隐藏它。
tuespetre 2014年

1
@Tohid谢谢,已经进行了编辑。没有可测试的MS资料,因此我尚未验证。
toxaq

7

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

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


3
-1假定项目希望具有显式的链接器-时间关系。不适合于插入型系统
MickyD

6

因此,Sayed的实施对我不起作用。我正在使用VS2013,并且正在使用Web Deploy软件包,并且需要从另一个文件夹中将一些插件DLL添加到deploy软件包的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。您的解决方案是最简单且完美的解决方案。
拉斐尔

5

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

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

如果这不适用于您并且您已经安装了Azure SDK,则下面是另一个链接: http://forums.iis.net/t/1190714.aspx


3

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

因此,我尝试使用上面所说的CopyAllFilesToSingleFolderForPackageDependsOn技巧来生成我的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>

希望能帮助某人...


1

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

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


1
似乎这应该是最佳答案,因为这是最简单,最明显的方法
J Miglietta
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.