Краткий ответ: Да, вы можете. Но это "сложно".
Длинный ответ:
При развертывании сайтов по назначению у нас были обычные web.test.config и web.prod.config. Это работало нормально, пока мы не представили log4net.test.config и log4net.prod.config. MSBuild не будет автоматически проходить и заменять все это. Это будет делать только web.config.
Если вы хотите, чтобы все было в порядке, перейдите к последнему фрагменту кода. Он показывает функции, чтобы взять один конфиг и заменить его на замену. Но ... это будет иметь больше смысла, если я опишу весь процесс.
Процесс:
- Msbuild создает пакет zip-файлов сайта.
- Мы написали специальное приложение .net, которое возьмет этот zip-файл и выполнит замену конфигурации для каждого из файлов. Восстановите почтовый файл.
- Выполните команду msdeploy для развертывания упакованного файла.
MSbuild не будет автоматически заменять все дополнительные настройки. Что интересно, MSBuild удалит все «лишние» конфиги. Таким образом, ваш log4net.test.config исчезнет после сборки. Поэтому первое, что вам нужно сделать, это сказать msdbuild, чтобы эти дополнительные файлы оставались на месте.
Вы должны изменить свой файл vbProj, чтобы включить новый параметр:
<AutoParameterizationWebConfigConnectionStrings>False</AutoParameterizationWebConfigConnectionStrings>
Откройте файл vbProj для веб-приложения в своем любимом текстовом редакторе. Перейдите к каждой конфигурации развертывания, к которой вы хотите применить эту настройку (release, 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-пакет и находит все конфиги, которые соответствуют {configname}. {Env} .config. Он извлечет их, заменит их и вернет обратно. Для фактической замены мы используем те же DLL, что и MSDeploy. Я также использую Ionic.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
Как я уже сказал ... это сложно, но это можно сделать.