Question

Puis-je utiliser la config de mécanisme transforme MSDeploy pour transformer d'autres fichiers?

Était-ce utile?

La solution

(une autre approche)

L'emballage est msdeploy jsut invoqué lors d'une course MSBuild pour votre projet.

TransformXML est une tâche incluse d'un .csproj ou .vsproj construction.

Il suffit de modifier votre processus de construction d'invoquer cette tâche sur tout fichier dont vous avez besoin.

Par exemple, ce que nous faisons est d'écrire une cible personnalisée

<Target Name="TransformFile">

    <TransformXml Source="$(DestinationPath)\$(Sourcefile)" 
       Transform="$(DestinationPath)\$(TransformFile)" 
       Destination="$(DestinationPath)\$(DestFile)" />
    </Target>

Ensuite, modifiez votre .csproj pour exécuter cette AVANT est appelée la tâche de publication.

<CallTarget Targets="TransformFile" 
   Condition="'$(CustomTransforms)'=='true'" />

Autres conseils

La réponse par Taylor n'a pas fonctionné pour moi et il n'a pas fourni de plus amples détails. Je suis donc allé spéléo dans le fichier Microsoft.Web.Publishing.targets pour trouver une solution. Le Target MSBuild suivant peut être ajouté au dossier de projet pour transformer tous les autres fichiers de configuration dans le répertoire racine de l'application. Enjoy:)

<Target Name="TransformOtherConfigs" AfterTargets="CollectWebConfigsToTransform">
<ItemGroup>
    <WebConfigsToTransform Include="@(FilesForPackagingFromProject)"
                           Condition="'%(FilesForPackagingFromProject.Extension)'=='.config'"
                           Exclude="*.$(Configuration).config;$(ProjectConfigFileName)">
    <TransformFile>%(RelativeDir)%(Filename).$(Configuration).config</TransformFile>
    <TransformOriginalFile>$(TransformWebConfigIntermediateLocation)\original\%(DestinationRelativePath)</TransformOriginalFile>
    <TransformOutputFile>$(TransformWebConfigIntermediateLocation)\transformed\%(DestinationRelativePath)</TransformOutputFile>
    <TransformScope>$([System.IO.Path]::GetFullPath($(_PackageTempDir)\%(DestinationRelativePath)))</TransformScope>
  </WebConfigsToTransform>
  <WebConfigsToTransformOuputs Include="@(WebConfigsToTransform->'%(TransformOutputFile)')" />
</ItemGroup>
</Target>

Réponse courte: Oui, vous pouvez. Mais il est « difficile ».

Réponse longue: Lorsque nous déployons des sites vers des destinations que nous avions l'habitude web.test.config et web.prod.config. Cela a bien fonctionné jusqu'à ce que nous avons introduit log4net.test.config et log4net.prod.config. MSBuild ne passe pas automatiquement par et remplacer toutes ces questions. Il ne le fera que les web.config.

Si vous voulez aller de Nitty Gritty au dernier extrait de code. Il montre les fonctions de prendre une config et le remplacer par un remplacement. Mais ... il aura plus de sens si je décris le processus.

Le processus:

  1. MSBuild fait un paquet de fichier zip du site.
  2. Nous avons écrit une coutume app .net qui prendra ce fichier zip et faire les remplacements de configuration sur chacun des fichiers. Réenregistrez le fichier zip.
  3. Exécuter la commande msdeploy pour déployer le fichier compressé.

MSBuild ne remplacera pas automatiquement toutes les configs supplémentaires. Ce qui est intéressant est MSBuild va supprimer les configs « supplémentaires ». Donc, votre log4net.test.config aura disparu après sa construction. Donc, la première chose que vous devez faire est de dire msdbuild de garder ces fichiers supplémentaires en place.

Vous devez modifier votre fichier vbProj pour inclure un nouveau paramètre:

<AutoParameterizationWebConfigConnectionStrings>False</AutoParameterizationWebConfigConnectionStrings>

Ouvrez votre fichier vbProj pour l'application Web dans votre éditeur de texte favori. Accédez à chaque configuration de déploiement que vous souhaitez que cela s'applique aussi (version, prod, debug, etc.) et d'ajouter que config en elle. Voici un exemple de configuration « release ».

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  ...
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <DefineDebug>false</DefineDebug>
    <DefineTrace>true</DefineTrace>
    <Optimize>true</Optimize>
    <OutputPath>bin\</OutputPath>
    <DocumentationFile>Documentation.xml</DocumentationFile>
    <NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022,42353,42354,42355</NoWarn>
    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
    <DeployIisAppPath>IISAppPath</DeployIisAppPath>
    <AutoParameterizationWebConfigConnectionStrings>False</AutoParameterizationWebConfigConnectionStrings>
  </PropertyGroup>
  ...
</Project>

Alors maintenant msbduild va construire le projet et de garder ces fichiers supplémentaires en place et ne pas faire les remplacements. Maintenant, vous devez les faire manuellement.

Nous avons écrit une application .net qui guetterez ces nouveaux fichiers zip. J'ai écrit un code qui tournera à travers l'ensemble du paquet zip et trouver des configs qui correspondent à la {configname}. {Env} .config. Il les extraire, les remplacer, et les remettre. Pour ce faire, le remplacement réel que nous utilisons les utilisations MSDeploy de la même DLL. Je l'utilise aussi Ionic.Zip pour faire les choses zip.

ajouter une référence à:

Microsoft.Build.dll
Microsoft.Build.Engine.dll
Microsoft.Web.Publishing.Tasks (possibly, not sure if you need this or not)

Importer:

Imports System.IO
Imports System.Text.RegularExpressions
Imports Microsoft.Build.BuildEngine
Imports Microsoft.Build 

Voici le code qui tourne à travers le fichier zip

specificpackage = "mypackagedsite.zip"
configenvironment = "DEV" 'stupid i had to pass this in, but it's the environment in web.dev.config

Directory.CreateDirectory(tempdir)

Dim fi As New FileInfo(specificpackage)

'copy zip file to temp dir   
Dim tempzip As String = tempdir & fi.Name

File.Copy(specificpackage, tempzip)

''extract configs to merge from file into temp dir
'regex for the web.config 
'regex for the web.env.config
'(?<site>\w+)\.(?<env>\w+)\.config$

Dim strMainConfigRegex As String = "/(?<configtype>\w+)\.config$"
Dim strsubconfigregex As String = "(?<site>\w+)\.(?<env>\w+)\.config$"
Dim strsubconfigregex2 As String = "(?<site>\w+)\.(?<env>\w+)\.config2$"

Dim MainConfigRegex As New Regex(strMainConfigRegex, RegexOptions.Compiled Or RegexOptions.IgnoreCase)
Dim SubConfigRegex As New Regex(strsubconfigregex, RegexOptions.Compiled Or RegexOptions.IgnoreCase)
Dim SubConfigRegex2 As New Regex(strsubconfigregex2, RegexOptions.Compiled Or RegexOptions.IgnoreCase)

Dim filetoadd As New Dictionary(Of String, String)
Dim filestoremove As New List(Of ZipEntry)
Using zip As ZipFile = ZipFile.Read(tempzip)
    For Each entry As ZipEntry In From a In zip.Entries Where a.IsDirectory = False
        For Each myMatch As Match In MainConfigRegex.Matches(entry.FileName)
            If myMatch.Success Then
                'found main config. 
                're-loop through, find any that are in the same dir as this, and also match the config name
                Dim currentdir As String = Path.GetDirectoryName(entry.FileName)
                Dim conifgmatchname As String = myMatch.Groups.Item("configtype").Value

                For Each subentry In From b In zip.Entries Where b.IsDirectory = False _
                                     And UCase(Path.GetDirectoryName(b.FileName)) = UCase(currentdir) _
                                     And (UCase(Path.GetFileName(b.FileName)) = UCase(conifgmatchname & "." & configenvironment & ".config") Or
                                          UCase(Path.GetFileName(b.FileName)) = UCase(conifgmatchname & "." & configenvironment & ".config2"))

                    entry.Extract(tempdir)
                    subentry.Extract(tempdir)

                    'Go ahead and do the transormation on these configs
                    Dim newtransform As New doTransform
                    newtransform.tempdir = tempdir
                    newtransform.filename = entry.FileName
                    newtransform.subfilename = subentry.FileName
                    Dim t1 As New Threading.Tasks.Task(AddressOf newtransform.doTransform)
                    t1.Start()
                    t1.Wait()
                    GC.Collect()
                    'sleep here because the build engine takes a while. 
                    Threading.Thread.Sleep(2000)
                    GC.Collect()

                    File.Delete(tempdir & entry.FileName)
                    File.Move(tempdir & Path.GetDirectoryName(entry.FileName) & "/transformed.config", tempdir & entry.FileName)
                    'put them back into the zip file
                    filetoadd.Add(tempdir & entry.FileName, Path.GetDirectoryName(entry.FileName))
                    filestoremove.Add(entry)
                Next
            End If
        Next
    Next

    'loop through, remove all the "extra configs"
    For Each entry As ZipEntry In From a In zip.Entries Where a.IsDirectory = False

        Dim removed As Boolean = False

        For Each myMatch As Match In SubConfigRegex.Matches(entry.FileName)
            If myMatch.Success Then
                filestoremove.Add(entry)
                removed = True
            End If
        Next
        If removed = False Then
            For Each myMatch As Match In SubConfigRegex2.Matches(entry.FileName)
                If myMatch.Success Then
                    filestoremove.Add(entry)
                End If
            Next
        End If
    Next

    'delete them
    For Each File In filestoremove
        zip.RemoveEntry(File)
    Next

    For Each f In filetoadd
        zip.AddFile(f.Key, f.Value)
    Next
    zip.Save()
End Using

Enfin, mais le plus important est que nous faisons en fait le remplacement des web.configs.

Public Class doTransform
    Property tempdir As String
    Property filename As String
    Property subfilename As String
    Public Function doTransform()
        'do the config swap using msbuild
        Dim be As New Engine
        Dim BuildProject As New BuildEngine.Project(be)
        BuildProject.AddNewUsingTaskFromAssemblyFile("TransformXml", "$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll")
        BuildProject.Targets.AddNewTarget("null")
        BuildProject.AddNewPropertyGroup(True)
        DirectCast(BuildProject.PropertyGroups(0), Microsoft.Build.BuildEngine.BuildPropertyGroup).AddNewProperty("GenerateResourceNeverLockTypeAssemblies", "true")

        Dim bt As BuildTask
        bt = BuildProject.Targets("null").AddNewTask("TransformXml")

        bt.SetParameterValue("Source", tempdir & filename)
        bt.SetParameterValue("Transform", tempdir & subfilename)
        bt.SetParameterValue("Destination", tempdir & Path.GetDirectoryName(filename) & "/transformed.config")
        'bt.Execute()
        BuildProject.Build()
        be.Shutdown()

    End Function

End Class

Comme je l'ai dit ... il est difficile, mais il peut être fait.

Juste pour ajouter à cette awnser, afin de modifier d'autres fichiers que le web.config dans une application publiée msdeploy (webdeploy), vous pouvez définir l'attribut scope dans le fichier parameters.xml à la racine du projet:

<parameters>
  <parameter name="MyAppSetting" defaultvalue="_defaultValue_">
    <parameterentry match="/configuration/appSettings/add[@key='MyAppSetting']/@value" scope=".exe.config$" kind="XmlFile">
    </parameterentry>
  </parameter>
</parameters>

scope est une expression régulière qui sera utilisé pour trouver des fichiers pour appliquer le match XPath à. Je nai expérimenté avec ce largement, mais pour autant que je comprends qu'il remplace simplement ce que jamais les matchs de XPath avec la valeur fournie plus tard.

Il y a aussi d'autres valeurs qui peuvent être utilisées pour kind qui ont des comportements différents d'une XPath, voir https://technet.microsoft.com/en-us/library/dd569084 (v = ws.10) .aspx pour plus de détails

Note: cela vaut quand vous utilisez un parameters.xml, pas lorsque vous utilisez le web.config.Debug / fichiers Release

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top