2011-01-20 3 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"로 설정하면 실행되고 "CallTarget"(최소한 일부 VS2012 프로젝트에서는)이 필요하지 않습니다. – nateirvin

2

짧은 대답 : 가능합니다. 그러나 "어렵다".

긴 답변 : 대상에 사이트를 배포 할 때 우리는 보통 web.test.config 및 web.prod.config를 사용했습니다. 이것은 log4net.test.config와 log4net.prod.config를 소개 할 때까지 잘 돌아갔다. MSBuild는 자동으로 통과하지 않으며 이들 모두를 대체하지 않습니다. web.config 파일 만 수행합니다.

마지막 코드 스 니펫으로 이동하십시오. 그것은 하나의 설정을 가져와 대체로 대체하는 기능을 보여줍니다. 그러나 ... 전체 과정을 설명하면 더 의미가 있습니다.

과정 :

  1. MSBUILD 사이트의 zip 파일 패키지를 만든다.
  2. 우리는 zip 파일을 가져 와서 각 파일에 대한 구성 바꾸기를 수행 할 사용자 지정 .net 응용 프로그램을 작성했습니다. zip 파일을 다시 저장하십시오.
  3. msdeploy 명령을 실행하여 패키지 파일을 배포합니다.

MSbuild는 모든 추가 구성을 자동으로 대체하지 않습니다. 흥미로운 점은 MSBuild가 "추가"구성을 제거한다는 것입니다. 따라서 log4net.test.config 파일은 빌드 된 후에 사라질 것입니다. 그러므로 제일 먼저해야 할 일은 msdbuild가 여분의 파일을 제자리에 유지하도록하는 것입니다.

은 새 설정을 포함하도록 vbProj 파일을 수정해야합니다 :

<AutoParameterizationWebConfigConnectionStrings>False</AutoParameterizationWebConfigConnectionStrings> 

이 좋아하는 텍스트 편집기에 웹 애플리케이션에 대한 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을 사용합니다.

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.config를 대체하십시오.

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를 사용하면이 모든 것을 훌륭하게 수행 할 수 있습니다. 내 대답보기. "추가"파일에 문제가있는 경우 Publish/Package 호출 인 –

+0

에 대한 입/출력 파일이 포함 된 ItemGroups를 수정하면됩니다. 좋은 생각입니다. 내 시나리오에서 유일한 문제는 우리 가이 같은 일을 모두 다른 configs 등 15 일 사이트를 가지고 그래서 내가 구축 시간에 그냥 "할"이 내장되어 있습니다. 너의 것이 훨씬 더 간단하다. –

+0

그 주된 이유에 대해 완전히 잊어 버렸습니다 ... 모든 환경 설정 패키지를 제공합니다. 그래서 dev, test, qa, stage, prod 등과 같은 정확한 패키지를 배포 할 수 있습니다. –

3

테일러의 답변이 저에게 효과적이지 않으며 자세한 내용을 제공하지 않았습니다. 그래서 해결책을 찾으려면 Microsoft.Web.Publishing.targets 파일에 동굴 탐험에 나갔습니다. 다음 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 파일 사용

관련 문제