18

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

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

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

我看到可以通过 msbuild 目标对清单文件进行一些自定义:

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

特别是通过使用该MsDeploySourceManifest项目。

在浏览适当的 .targets 文件后,如果我使用目标,它看起来像contentPath或者iisApp将被附加到我的清单中。Package理想情况下,我只想复制一个程序集(或目录),可能设置 ACL,然后在服务上执行 installutil.exe。

Package是否可以通过编辑我的 csproj 文件来完全自定义目标生成的清单?

如果没有,是否有一种简单的方法来构建一个新的目标,它相当于Package,但允许我吐出一个完全自定义的清单?

4

1 回答 1

17

我还没有完整的文章供人们尝试了解它是如何工作的,但我现在有一篇关于如何至少实现这个目标的文章。

http://thehappypath.net/2011/11/21/using-msdeploy-for-windows-services/

编辑:链接暂时失效。如果您有兴趣,请告诉我,我可以将其发布到其他地方)。

我的指南经历了这些总体步骤:

  • 确保服务在安装时自行启动(不是关键,但更容易处理)
  • 将 Microsoft.WebApplication.targets 文件添加到您的项目中,即使您没有 Web 项目。这将启用PackageMsBuild 目标。
  • 将自定义 .targets 文件添加到构建自定义 MsBuild 包清单的项目中
  • 向您的项目添加一些批处理脚本以停止/卸载和安装服务
  • 添加一个 Parameters.xml 文件以支持更轻松地更改目标部署目录
  • 使用SlowCheetah Visual Studio 插件设置 app.config 转换

然后你可以用这个命令行打包你的项目:

msbuild MyProject.csproj /t:Package /p:Configuration=Debug

您可以使用以下命令行部署生成的包:

MyService.Deploy.cmd /Y /M:mywebserver -allowUntrusted

其中最无证的部分(除了我的指南)是创建自定义清单。这是我当前文件的转储(请注意,它仍然有点错误,但可以修复 - 请参阅此问题:MsDeploy remoting execution manifest two- and try to keep to use only direct batch files for 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>
于 2011-11-22T06:30:22.573 回答