msbuild - 使用 MsBuild 生成自定义的 MsDeploy list (包目标)

标签 msbuild manifest msdeploy slowcheetah

我正在使用 Web Deploy 来打包和部署我的产品的网站。特别是,我的解决方案中有两个不同的项目,我使用此方法进行部署。

我的解决方案中有第三个项目(Windows 服务),也需要安装在 Web 服务器上。

我知道我可以编写自定义 list (针对 dirPathfilePathrunCommand 提供程序)并直接调用 MsDeploy 来部署它。但如果可能的话,我想利用现有的 MsBuild 任务来打包我的服务。

我发现可以通过 msbuild 目标对 list 文件进行一些自定义:

http://social.msdn.microsoft.com/Forums/en/msbuild/thread/1044058c-f762-456b-8a68-b0863027ce47

特别是通过使用 MsDeploySourceManifest 项。

浏览适当的 .targets 文件后,如果我使用 PackagecontentPathiisApp 将被附加到我的 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/

相关文章:

c# - MSBuild 任务不会导致编译生成的 c# 文件

.net - 使用 MSBuild 压缩多个项目目录

java - Activity 类不存在?

scala - 缺少更高类型的 list

visual-studio-2010 - 发布时未执行 wpp.targets 中的 setAcl - Web 部署(但说是)

TFS msbuild 参数/p :DeployOnBuild=true doesn't seem to do anything

c++ - Gitlab CI Runner 预定义宏 MSBuild

visual-studio - OutputPath 设置为 bin\x86\release,但在使用 MSBuild 时显示为 obj\x86\release

gradle - 如何在 Gradle 中操作 Osgi list 的生成的 Import-Package 语句?

asp.net - MSDeploy 只能部署新文件或更改的文件吗?