2011-01-20 9 views

答えて

5

(別のアプローチ)

場合msdeployパッケージがjsut MSBuildの中に呼び出され、プロジェクトのために実行します。

TransformXmlは.csprojまたは.vsprojビルドの含ま作業です。

ビルドプロセスを変更して、必要なファイルでそのタスクを呼び出すだけです。例えば

、私たちがやっていることは公開タスクが呼び出される前にこれを実行するために、あなたの.csprojを変更すると

<Target Name="TransformFile"> 

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

カスタムターゲットを作成しています。

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

DestinationPath、Sourcefile、TransformFile、DestFileの設定サンプルを与えることはできますか?私はこれらを動的に設定するためにMSBuildの書き込みプロパティを見つけることができないようです。 – chief7

+0

ターゲット名を "AfterBuild"に設定すると、それだけが実行され、(少なくともVS2012プロジェクトでは) "CallTarget"は必要ありません。 – nateirvin

2

短い回答:はいできます。しかし、それは「難しい」。

長い答え: 私たちはいつものweb.test.config、およびweb.prod.configを持っていた目的地にサイトを展開します。これは、log4net.test.configとlog4net.prod.configを導入するまでうまくいきました。 MSBuildは自動的にこれらのすべてを通過して置き換えません。それはweb.configだけを行います。

最終的なコードスニペットに行きます。これは、1つの設定を取って代わりに置き換える機能を示しています。しかし...私がプロセス全体を記述すると、より意味をなさないでしょう。

プロセス:

  1. MSBuildのは、サイトのzipファイルパッケージを作成します。
  2. 私たちは、そのzipファイルを受け取り、それぞれのファイルのconfigの置き換えを行うカスタム.net appを書きました。 zipファイルを再保存します。
  3. msdeployコマンドを実行してパッケージファイルを展開します。

MSbuildはすべての追加の設定を自動的に置き換えません。興味深いのは、MSBuildが「特別な」設定を削除することです。したがって、log4net.test.configはビルド後に消えてしまいます。したがって、最初に行う必要があるのは、msdbuildに追加のファイルを保存させることです。

あなたは、新しい設定を含めるようにvbProjファイルを変更する必要があります。

<AutoParameterizationWebConfigConnectionStrings>False</AutoParameterizationWebConfigConnectionStrings> 

がお好きなテキストエディタに、Webアプリケーションのためのあなたの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はプロジェクトをビルドし、余分なファイルを保存して置き換えません。今すぐ手動で行う必要があります。

これらの新しいzipファイルを監視する.netアプリを作成しました。私は、zipパッケージ全体を回転し、{configname}。{env} .configと一致するすべての設定を見つけるコードを書きました。それはそれらを抽出し、それらを置き換え、それらを戻すでしょう。実際の置き換えを行うには、MSDeployが使用するのと同じDLLを使用します。私はまた、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 

私が言ったように...それは困難ですが、それはできます。

+0

優れた包括的な答えですが、MsBuildでこれをすべて実行できます。私の返事を見てください。 「余分な」ファイルに問題がある場合は、パブリッシュ/パッケージコール –

+0

の良いアイデアになる入力/出力ファイルを含むItemGroupsを変更するだけで済みます。私のシナリオでのみ問題があります。私たちは15のサイトで、同じ設定をすべて異なる設定などで行っているので、デプロイ時にこれを「行う」ように構築しました。あなたのものははるかに簡単です。 –

+0

その主な理由を完全に忘れてしまった...それは私にそれが設定されているすべての環境のパッケージを提供する。だから私はdev、test、qa、stage、prodなどに同じ正確なパッケージをデプロイすることができます。 –

3

テイラーの答えは私のためには機能しませんでした。彼は詳細を述べませんでした。そこで、私はMicrosoft.Web.Publishing.targetsファイルにspelunkingして解決策を見つけました。次のMSBuild Targetをプロジェクトファイルに追加して、ルートアプリケーションディレクトリ内の他のすべての設定ファイルを変換することができます。お楽しみください:)

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

をちょうどあなたがでparameters.xmlファイルでscope属性を設定することができます場合msdeploy(webdeploy)で公開されているアプリケーションで、web.configファイル以外のファイルを変更するためには、このawnserに追加しますプロジェクトのルート:

<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が一致するものを後で提供される値と置き換えるだけである。

、XPathのとは異なる振る舞いを持って詳細

ため https://technet.microsoft.com/en-us/library/dd569084(v=ws.10).aspxが表示されますその kindのために使用することができる他の値もあります

注:これは、あなたがparameters.xmlを使用しているときに適用されますがありませんweb.config.Debug/Releaseファイルを使用してください。

関連する問題