MSDeploy の構成変換メカニズムを使用して他のファイルを変換できますか?
4 に答える
(別のアプローチ)
msdeploy パッケージは、プロジェクトの MSbuild 実行中に呼び出される jsut です。
TransformXmlは、.csproj または .vsproj ビルドに含まれるタスクです。
ビルド プロセスを変更して、必要なファイルでそのタスクを呼び出すだけです。
たとえば、カスタム ターゲットを作成します。
<Target Name="TransformFile">
<TransformXml Source="$(DestinationPath)\$(Sourcefile)"
Transform="$(DestinationPath)\$(TransformFile)"
Destination="$(DestinationPath)\$(DestFile)" />
</Target>
次に、Publish タスクが呼び出される前にこれを実行するように .csproj を変更します。
<CallTarget Targets="TransformFile"
Condition="'$(CustomTransforms)'=='true'" />
テイラーによる答えは私にはうまくいかず、彼はそれ以上の詳細を提供しませんでした. そこで、解決策を見つけるためにMicrosoft.Web.Publishing.targetsファイルを詳しく調べました。次の MSBuildTarget
をプロジェクト ファイルに追加して、ルート アプリケーション ディレクトリ内の他のすべての構成ファイルを変換できます。楽しみ :)
<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 のみを実行します。
要点を知りたい場合は、最後のコード スニペットに進んでください。1 つの構成を取り、それを代替品に置き換える関数を示します。しかし... 全体のプロセスを説明すれば、より意味があります。
プロセス:
- Msbuild は、サイトの zip ファイル パッケージを作成します。
- その zip ファイルを取得し、各ファイルで構成の置換を行うカスタム .net アプリを作成しました。zip ファイルを再保存します。
- msdeploy コマンドを実行して、パッケージ化されたファイルをデプロイします。
MSbuild は、すべての余分な構成を自動的に置き換えるわけではありません。興味深いのは、MSBuild が「余分な」構成を削除することです。したがって、ビルド後に log4net.test.config はなくなります。したがって、最初にやらなければならないことは、msdbuild にこれらの余分なファイルを保持するように指示することです。
vbProj ファイルを変更して、新しい設定を含める必要があります。
<AutoParameterizationWebConfigConnectionStrings>False</AutoParameterizationWebConfigConnectionStrings>
Web アプリケーションの vbProj ファイルをお気に入りのテキスト エディターで開きます。これも適用する各デプロイ構成 (リリース、本番、デバッグなど) に移動し、その構成をそれに追加します。「リリース」構成の例を次に示します。
<?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 はプロジェクトをビルドし、それらの余分なファイルを所定の位置に保持し、置換を行いません。ここで、それらを手動で行う必要があります。
これらの新しい zip ファイルを監視する .net アプリを作成しました。zip パッケージ全体を調べて、{configname}.{env}.config に一致する構成を見つけるコードを書きました。それらを抽出し、置き換え、元に戻します。実際の置換を行うには、MSDeploy が使用するのと同じ DLL を使用します。また、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 に追加するだけで、msdeploy (webdeploy) で公開されたアプリケーションの web.config 以外のファイルを変更するに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 を適用するファイルを検索するために使用される正規表現です。私はこれを広範囲に試したことはありませんが、理解する限り、xpath が後で提供される値と一致するものを単に置き換えます。
kind
xpath とは異なる動作をするために使用できる他の値もあります。詳細については、 https: //technet.microsoft.com/en-us/library/dd569084(v=ws.10).aspx を参照してください。
注: これは、web.config.Debug/Release ファイルを使用する場合ではなく、parameters.xml を使用する場合に適用されます。