2011-09-15 17 views
18

Estoy utilizando Web Deploy para empacar e implementar sitios web para mi producto. En particular, tengo dos proyectos diferentes en mi solución. Utilizo este método para implementar.Uso de MsBuild para generar el manifiesto personalizado de MsDeploy (destino del paquete)

Tengo un tercer proyecto en la solución (un servicio de Windows) que también debe instalarse en el servidor web.

Sé que puedo escribir un manifiesto personalizado (para los proveedores dirPath, filePath y runCommand) y llamar directamente a MsDeploy para implementarlo. Pero me gustaría aprovechar las tareas existentes de MsBuild para empaquetar mi servicio si es posible.

veo que es posible hacer algún tipo de personalización del archivo de manifiesto a través de los objetivos msbuild:

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

Particularmente utilizando el elemento MsDeploySourceManifest.

Después de meter a través de los archivos .targets apropiadas, parece que sea contentPath o iisApp obtendrá añade a mis manifiesta si utilizo el objetivo Package. Idealmente, me gustaría copiar un ensamblaje (o directorio), posiblemente establecer ACL y ejecutar installutil.exe en el servicio.

¿Es posible personalizar completamente el manifiesto generado por el objetivo Package, editando mi archivo csproj?

Si no, ¿hay una manera simple de construir un nuevo objetivo que haga el equivalente a Package, pero permítanme escupir un manifiesto completamente personalizado?

+0

¿Recibió una respuesta a esto? – musica

+0

@Graci: lo hice. Estoy terminando el tema de trabajo para esto durante esta semana, y publicaré una respuesta después de que todo esté funcionando. Los conceptos clave son crear un archivo '.targets' personalizado, usar sus destinos personalizados para agregar entradas del proveedor' runCommand' para ejecutar archivos por lotes personalizados (para detener/desinstalar el servicio e instalarlo/iniciarlo), agregue un Parámetros personalizado. archivo xml al proyecto y establecer ciertos indicadores, como 'IncludeIisSettingsOnPublish = False' y' IncludeIisSettingsOnPublish = False'. Ah, y la extensión gratuita de transformación no web de SlowCheetah ayudó también. –

+0

@Merlyn: Sería genial si encontraras tiempo para compartir tu solución, de tu último comentario parece que lo tienes bien cubierto. –

Respuesta

16

Aún no tengo un informe completo para las personas que intentan aprender cómo funciona esto, pero ahora tengo un escrito sobre cómo lograr al menos este objetivo.

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

(edición:. Enlace está muerto por ahora Quiero saber si usted está interesado y puedo ponerlo en otro lugar).

Mi guía pasa a través de estos pasos generales:

  • Asegúrese de que el servicio se inicia después de la instalación en sí (no es crucial, pero más fáciles de tratar)
  • añadir el archivo Microsoft.WebApplication.targets a su proyecto, a pesar de que no tienes un proyecto web. Esto habilita el objetivo Package MsBuild.
  • Añadir un archivo personalizado de .targets a su proyecto que construye una costumbre MSBUILD manifiesto del paquete
  • añadir un poco de secuencias de comandos por lotes para su proyecto para detener/desinstalar e instalar el servicio
  • Añadir un archivo parameters.xml para apoyar el cambio de la el directorio de implementación de destino es un poco más fácil
  • Configurar la aplicación.transformaciones de configuración utilizando the SlowCheetah Visual Studio addon

A continuación, puede empaquetar su proyecto con esta línea de comandos:

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

puede implementar el paquete resultante con esta línea de comandos:

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

La parte más indocumentado de esto (a excepción de mi guía) está creando el manifiesto personalizado. Aquí hay un volcado de mi archivo actual (nota, todavía está un poco defectuoso, pero se puede arreglar - Consulte esta pregunta: MsDeploy remoting executing manifest twice - y trate de usar solamente archivos de lotes directos para 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> 
+0

¿Por qué está incluido en los pasos enumera sus valores originales, cuando antes afirma que están vacíos? ¿Es realmente necesario debido a algo horrible? Quiero decir, algunas de las propiedades se ven como ' $ (prop); extensión ', por lo que ambos son" uso si no está configurado "e" inyección, no anulación ". Su muestra se adjunta solo si ya no está conectada ninguna otra, y al mismo tiempo intenta preservar los contenidos originales (se supone que están vacíos directamente antes). Pensaría que esas condiciones o el comportamiento de 'concat' no son necesarios. – quetzalcoatl

+0

De todos modos, gran trabajo! Acabo de obtener parches/extensiones similares antes de encontrar el fragmento, por lo que probablemente esa sea la única forma. Por cierto. También encontré el 'TransformWebConfigEnabled' para tener' true' por defecto, por lo que probablemente también se pueda recortar. Btw2. ¿Has probado la parametrización de la aplicación.config? ¿No hay ningún problema con la aplicación de los valores de 'SetParameters.xml' debido al hecho de que' webconfig/appconfig' se movió y renombró? – quetzalcoatl

+0

Hm .. Sí, estoy bastante seguro de que habrá un problema, ya que hay una referencia clara al antiguo 'App.config' en 'parameters.xml' dentro del paquete.Creo que se necesitan algunas correcciones adicionales para el objetivo 'ImportParametersFiles', o cerca de eso. – quetzalcoatl

Cuestiones relacionadas