我正在使用 Web Deploy 来打包和部署我的产品的网站。特别是,我的解决方案中有两个不同的项目,我使用此方法进行部署。
我的解决方案中有第三个项目(Windows 服务),也需要安装在 Web 服务器上。
我知道我可以编写自定义 list (针对 dirPath
、filePath
和 runCommand
提供程序)并直接调用 MsDeploy 来部署它。但如果可能的话,我想利用现有的 MsBuild 任务来打包我的服务。
我发现可以通过 msbuild 目标对 list 文件进行一些自定义:
http://social.msdn.microsoft.com/Forums/en/msbuild/thread/1044058c-f762-456b-8a68-b0863027ce47
特别是通过使用 MsDeploySourceManifest
项。
浏览适当的 .targets 文件后,如果我使用 Package
,contentPath
或 iisApp
将被附加到我的 list 中> 目标。理想情况下,我只想复制程序集(或目录),可能设置 ACL,并在服务上执行 installutil.exe。
是否可以通过编辑我的 csproj 文件来完全自定义 Package
目标生成的 list ?
如果没有,是否有一种简单的方法来构建一个新目标,该目标将执行与Package
相同的操作,但允许我吐出一个完全自定义的 list ?
最佳答案
对于那些试图了解其工作原理的人来说,我还没有完整的文章,但我现在有一篇关于如何至少实现这一目标的文章。
<罢工> http://thehappypath.net/2011/11/21/using-msdeploy-for-windows-services/ 罢工>
(编辑:链接目前已失效。如果您有兴趣,请告诉我,我可以将其发布到其他地方)。
我的指南完成了这些总体步骤:
- 确保服务在安装后自行启动(并不重要,但更容易处理)
- 将 Microsoft.WebApplication.targets 文件添加到您的项目中,即使您没有 Web 项目也是如此。这将启用
Package
MsBuild 目标。 - 将自定义 .targets 文件添加到您的项目中,以构建自定义 MsBuild 包 list
- 向您的项目添加一些批处理脚本以停止/卸载和安装服务
- 添加Parameters.xml 文件以支持更轻松地更改目标部署目录
- 使用 the SlowCheetah Visual Studio addon 设置 app.config 转换
然后您可以使用此命令行打包您的项目:
msbuild MyProject.csproj /t:Package /p:Configuration=Debug
您可以使用此命令行部署生成的包:
MyService.Deploy.cmd /Y /M:mywebserver -allowUntrusted
其中最没有记录的部分(除了我的指南)是创建自定义 list 。这是我当前文件的转储(注意,它仍然有点错误,但可以修复 - 请参阅这个问题: MsDeploy remoting executing manifest twice - 并尝试继续仅使用 runCommand
的直接批处理文件)。
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- This file must be included before Microsoft.Web.Publishing.targets so we can hook into BeforeAddIisSettingAndFileContentsToSourceManifest -->
<PropertyGroup>
<!-- Include our targets -->
<IncludeStopServiceCommand>True</IncludeStopServiceCommand>
<IncludeSetCustomAclsProvider>True</IncludeSetCustomAclsProvider>
<IncludeInstallServiceCommand>True</IncludeInstallServiceCommand>
<IncludeMoveAppConfigToCorrectPackagePath>True</IncludeMoveAppConfigToCorrectPackagePath>
<!-- Uncomment to enable more verbose MsBuild logging -->
<!-- <EnablePackageProcessLoggingAndAssert>True</EnablePackageProcessLoggingAndAssert> -->
<!-- Enable web.config transform, but hack it to work for app.config -->
<ProjectConfigFileName>app.config</ProjectConfigFileName>
<TransformWebConfigEnabled>True</TransformWebConfigEnabled>
<UseParameterizeToTransformWebConfig>True</UseParameterizeToTransformWebConfig>
<!-- Enable web project packaging, but hack it to work for non-web app -->
<DeployAsIisApp>False</DeployAsIisApp>
<IncludeIisSettingsOnPublish>False</IncludeIisSettingsOnPublish>
<IncludeSetAclProviderOnDestination>False</IncludeSetAclProviderOnDestination>
<DisableAllVSGeneratedMSDeployParameter>True</DisableAllVSGeneratedMSDeployParameter>
<!-- Insert our custom targets into correct places in build process -->
<BeforeAddIisSettingAndFileContentsToSourceManifest Condition="'$(BeforeAddIisSettingAndFileContentsToSourceManifest)'==''">
$(BeforeAddIisSettingAndFileContentsToSourceManifest);
AddStopServiceCommand;
</BeforeAddIisSettingAndFileContentsToSourceManifest>
<AfterAddIisSettingAndFileContentsToSourceManifest Condition="'$(AfterAddIisSettingAndFileContentsToSourceManifest)'==''">
$(AfterAddIisSettingAndFileContentsToSourceManifest);
AddSetCustomAclsProvider;
AddInstallServiceCommand;
</AfterAddIisSettingAndFileContentsToSourceManifest>
<OnAfterCopyAllFilesToSingleFolderForPackage Condition="'$(OnAfterCopyAllFilesToSingleFolderForPackage)'==''">
$(OnAfterCopyAllFilesToSingleFolderForPackage);
MoveAppConfigToCorrectPackagePath;
</OnAfterCopyAllFilesToSingleFolderForPackage>
</PropertyGroup>
<!-- Custom targets -->
<Target Name="AddStopServiceCommand" Condition="'$(IncludeStopServiceCommand)'=='true'">
<Message Text="Adding runCommand to stop the running Service" />
<ItemGroup>
<MsDeploySourceManifest Include="runCommand">
<path>$(_MSDeployDirPath_FullPath)\bin\servicestop.bat</path>
<waitInterval>20000</waitInterval>
<AdditionalProviderSettings>waitInterval</AdditionalProviderSettings>
</MsDeploySourceManifest>
</ItemGroup>
</Target>
<Target Name="AddSetCustomAclsProvider" Condition="'$(IncludeSetCustomAclsProvider)'=='true'">
<ItemGroup>
<MsDeploySourceManifest Include="setAcl">
<Path>$(_MSDeployDirPath_FullPath)</Path>
<setAclUser>LocalService</setAclUser>
<setAclAccess>FullControl</setAclAccess> <!-- Todo: Reduce these permissions -->
<setAclResourceType>Directory</setAclResourceType>
<AdditionalProviderSettings>setAclUser;setAclAccess;setAclResourceType</AdditionalProviderSettings>
</MsDeploySourceManifest>
</ItemGroup>
</Target>
<Target Name="AddInstallServiceCommand" Condition="'$(IncludeInstallServiceCommand)'=='true'">
<Message Text="Adding runCommand to install the Service" />
<ItemGroup>
<MsDeploySourceManifest Include="runCommand">
<path>cmd.exe /c $(_MSDeployDirPath_FullPath)\bin\serviceinstall.bat</path>
<waitInterval>20000</waitInterval>
<dontUseCommandExe>false</dontUseCommandExe>
<AdditionalProviderSettings>waitInterval;dontUseCommandExe</AdditionalProviderSettings>
</MsDeploySourceManifest>
</ItemGroup>
</Target>
<Target Name="MoveAppConfigToCorrectPackagePath"
Condition="'$(IncludeMoveAppConfigToCorrectPackagePath)'=='true'">
<PropertyGroup>
<OriginalAppConfigFilename>$(_PackageTempDir)\App.Config</OriginalAppConfigFilename>
<TargetAppConfigFilename>$(_PackageTempDir)\bin\$(TargetFileName).config</TargetAppConfigFilename>
</PropertyGroup>
<Copy SourceFiles="$(OriginalAppConfigFilename)" DestinationFiles="$(TargetAppConfigFilename)"
Condition="Exists($(OriginalAppConfigFilename))" />
<Delete Files="$(OriginalAppConfigFilename)"
Condition="Exists($(OriginalAppConfigFilename))" />
</Target>
</Project>
关于msbuild - 使用 MsBuild 生成自定义的 MsDeploy list (包目标),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7429185/