Вопрос

Могу ли я использовать механизм преобразования конфигурации MSDeploy для преобразования других файлов?

Это было полезно?

Решение

(Другой подход)

Упаковка MSDeploy приводится в эксплуатацию во время пробега MSBuild для вашего проекта.

Transformxml является включенной задачей .csproj или .vsproj сборка.

Просто измените процесс сборки, чтобы вызвать эту задачу в любой файл, который вам нужен.

Например, мы пишем пользовательскую цель

<Target Name="TransformFile">

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

Затем измените свой.

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

Другие советы

Ответ Тейлора не работал для меня, и он не предоставил дополнительных подробностей. Итак, я пошел в Microsoft.Web.Publishing.Targets Файл, чтобы найти решение. Следующая MSBuild Target может быть добавлен в файл проекта, чтобы преобразовать все другие файлы конфигурации в каталоге Root Application. Наслаждаться :)

<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>

Короткий ответ: Да, ты можешь. Но это "сложно".

Длинный ответ: Когда мы развертываем сайты в пункты назначения, у нас был обычный web.test.config и web.prod.config. Это работало нормально, пока мы не представили log4net.test.config и log4net.prod.config. MSBuild не будет автоматически проходить и заменить все это. Он будет делать только Web.Config.

Если вы хотите, чтобы Nitty Gritty перейти к последнему фрагменту кода. Он показывает функции, чтобы взять одну конфигурацию и заменить его на замену. Но ... это будет иметь больше смысла, если я опишу весь процесс.

Процесс:

  1. MSBUILD производит пакет файлов ZIP на сайте.
  2. Мы написали пользовательское приложение .NET, которое возьмет этот ZIP -файл и выполнит замену конфигурации в каждом из файлов. Поменить файл ZIP.
  3. Выполните команду MSDEPLOY, чтобы развернуть упакованный файл.

MSBuild не будет автоматически заменить все дополнительные конфигурации. Что интересно, так это то, что MSBuild удалит любые «дополнительные» конфигурации. Таким образом, ваш log4net.test.config уйдет после его сборки. Так что первое, что вам нужно сделать, это сказать MSDBuild, чтобы сохранить эти дополнительные файлы на месте.

Вы должны изменить свой файл VBPROJ, чтобы включить новую настройку:

<AutoParameterizationWebConfigConnectionStrings>False</AutoParameterizationWebConfigConnectionStrings>

Откройте свой файл VBPROJ для веб -приложения в ваш любимый текстовый редактор. Перейдите к каждой конфигурации развертывания, которую вы хотите, чтобы это также применило (выпуск, Prod, Debug и т. Д.) И добавьте в нее эту конфигурацию. Вот пример нашей конфигурации «выпуск».

<?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>

Так что теперь MSBDuild создаст проект и сохранит эти дополнительные файлы на месте и не выполняет замены. Теперь вам нужно вручную сделать их.

Мы написали приложение .NET, которое будет смотреть эти новые файлы ZIP. Я написал какой -то код, который пройдет через весь пакет ZIP и найдет любые конфигурации, которые соответствуют {contigname}. {Env} .config. Это извлечет их, заменит их и поставит обратно. Чтобы сделать фактическую замену, мы используем тот же DLL, который использует MSDeploy. Я также использую ionic.zip, чтобы сделать zip.

Так что добавьте ссылку на:

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

Импорт:

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

Вот код, который проходит через файл 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

Наконец, но самое важное - это то, где мы на самом деле делаем замену 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

Как я уже сказал ... это сложно, но это можно сделать.

Просто чтобы добавить к этому awnser, чтобы изменить другие файлы, чем web.config в приложении, опубликованном с помощью msdeploy (webdeploy), вы можете установить scope Атрибут в файле parameters.xml в корне проекта:

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

scope это регулярность, которая будет использоваться для поиска файлов для применения match xpath to. Я не экспериментировал с этим тщательно, но, насколько я понимаю, это просто заменяет то, что когда -либо совпадает со значением, которое предоставлено позже.

Есть также и другие значения, которые можно использовать для kind это будет иметь другое поведение, чем xpath, см. https://technet.microsoft.com/en-us/library/dd569084(v=ws.10).aspx Для деталей

Примечание. Это относится к тому, когда вы используете параметры. xml, а не при использовании файлов web.config.debug/lepred

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top