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

时间:2010-04-30 19:23:51

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

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

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

7 个答案:

答案 0 :(得分:169)

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

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

包含额外文件

如果您对MSBuild感到满意,那么将额外的文件包含在包中会有点困难,但仍然没有bigee,如果您不熟悉,请阅读此内容。为了做到这一点,我们需要挂钩收集文件以进行打包的过程部分。我们需要扩展的目标称为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" />

BTW你可以在VS里面打开项目文件。右键单击项目选择卸载项目。然后右键单击卸载的项目并选择Edit Project。

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

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

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

答案 1 :(得分: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文件夹的先前缺点。我未经验证。

答案 2 :(得分:7)

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

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

答案 3 :(得分: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" />

答案 4 :(得分:5)

希望评论以强调Emil Lerch上面的评论。如果已安装Azure SDK,则查找其他DependencyProperty。

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

这是另一个链接,如果这不适合您并且您已安装Azure SDK: http://forums.iis.net/t/1190714.aspx

答案 5 :(得分: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>

希望有人帮助......

答案 6 :(得分:0)

此外,还可以将文件设置为“内容|始终复制

Also, it is possible to set the file as Content | Copy always