Answers:
好问题。我刚刚在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
此处注意元数据的用法。我不会在这里讨论,但是您应该知道始终指定它。
一个更简单的解决方案是编辑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文件夹的先前缺点。我未验证。
<Visible>false</Visible>
为从解决方案资源管理器中隐藏它。
因此,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" />
想要发表评论以强调Emil Lerch的上述评论。如果已安装Azure SDK,则查找其他DependencyProperty。
基本上,您可能需要使用“ CopyAllFilesToSingleFolderForMsdeployDependsOn”而不是“ CopyAllFilesToSingleFolderForPackageDependsOn”。我不是MsBuild高级人,我浪费了很多时间试图确定为什么我的目标没有被调用。
如果这不适用于您并且您已经安装了Azure SDK,则下面是另一个链接: http://forums.iis.net/t/1190714.aspx
作为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>
希望能帮助某人...