我正在使用visual studio 2010中的新网络打包功能进行测试,并遇到了一种情况,我使用预构建事件将所需的.dll复制到我的应用程序依赖于API调用的bin文件夹中。它们不能作为参考包含在内,因为它们不是可与interop一起使用的COM dll。
当我构建部署包时,当我选择仅包含运行应用程序所需文件的选项时,将排除这些文件。有没有办法配置部署设置以包含这些文件?我没有找到任何关于此的好文件。
答案 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)