Convert file using msdeploy

Can I use the MSDeploy configuration conversion engine to convert other files?

+4
webdeploy msdeploy
Jan 20 '11 at 17:00
source share
4 answers

(another approach)

The msdeploy package is the jsut invoked during MSbuild startup for your project.

TransformXml is the included build task .csproj or .vsproj.

Just change the build process to call this task in any file you need.

For example, we record a custom goal

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

Then modify your .csproj to run this BEFORE calling the publication.

 <CallTarget Targets="TransformFile" Condition="'$(CustomTransforms)'=='true'" /> 
+5
Feb 08 2018-11-11T00:
source share

Taylor's answer did not help me, and he did not provide further details. So I went to the Microsoft.Web.Publishing.targets file to find a solution. You can add the following MSBuild Target to the project file to convert all other configuration files to the application root directory. Enjoy :)

 <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> 
+3
Mar 21 '11 at 17:36
source share

Short answer: Yes you can. But it is difficult".

Long answer: When we deploy sites to destinations, we have the usual web.test.config and web.prod.config. This worked fine until we introduced log4net.test.config and log4net.prod.config. MSBuild will not automatically go through and replace all of these. It will only work with web.config.

If you want nitty gritty to go to the last piece of code. It shows the functions that need to be taken with one configuration and replaced with a replacement. But ... it will make more sense if I describe the whole process.

Process:

  • Msbuild creates a package of zip files for the site.
  • We wrote a custom .net application that will take this zip file and replace the configuration on each of the files. Restart the zip file.
  • Run the msdeploy command to deploy the packaged file.

MSbuild will not automatically replace all additional configs. Interestingly, MSBuild will remove any "additional" configs. This way your log4net.test.config will disappear after building it. So, the first thing you need to do is say msdbuild so that these additional files are in place.

You need to modify the vbProj file to include the new parameter:

 <AutoParameterizationWebConfigConnectionStrings>False</AutoParameterizationWebConfigConnectionStrings> 

Open the vbProj file for the web application in your favorite text editor. Go to each deployment configuration that you want to apply this application to (release, prod, debug, etc.) and add this configuration to it. Here is an example of our "release" configuration.

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

So, now msbduild will build the project and store these additional files in place, rather than perform replacements. Now you have to manually execute them.

We wrote a .net application that will keep track of these new zip files. I wrote code that will scroll through the entire zip package and find any configs that match {configname}. {Env} .config. He will remove, replace and return them. To perform a real replacement, we use the same DLL as MSDeploy. I also use Ionic.Zip to work with the zip file.

So add a link to:

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

Import:

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

Here is the code that rotates through the zip file

 specificpackage = "mypackagedsite.zip" configenvironment = "DEV" 'stupid i had to pass this in, but it 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 

Finally, but most importantly, we are actually doing a replacement for 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 

Like I said ... it's hard, but it can be done.

+2
Feb 03 2018-11-11T00:
source share

To add awnser to this, to change files other than the web.config file in an application published using msdeploy (webdeploy), you can set the scope attribute in the parameters.xml file in the project root

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

scope is a regular expression that will be used to search for files to apply match xpath to. I have not experimented with this extensively, but as I understand it, it just replaces what xpath ever matches with the value provided later.

There are other values ​​that can be used for kind , which will have different types of behavior than xpath, see https://technet.microsoft.com/en-us/library/dd569084(v=ws.10).aspx .

Note: this applies when you use the .xml parameter, and not when using the web.config.Debug / Release files

+1
Oct 20 '16 at 8:12
source share



All Articles