Adding behaviorExtensions to machine.config via C#

I’ve been playing around with BizTalk Deployment Framework lately and for one particular BizTalk application, I need to add 4 custom behaviorExtensions. I’ve had some very specific logic that I needed to put into some WCF Message Inspectors.

When you think about automating the installation of a BizTalk application, you don’t want to be manually adding the behaviorExtensions to the machine.config. So I set out to add these via a C# application. Seems this was not as trivial as I though it would be.

First things first, we need to be able to retrieve the location of the machine.config file:

 // Get the machine.config file.
 Configuration machineConfig = ConfigurationManager.OpenMachineConfiguration();
 // Get the machine.config file path.
 ConfigurationFileMap configFile = new ConfigurationFileMap(machineConfig.FilePath);

The above code, will give you the path of the machine.config file, depending on what runtime (x86 or x64) you are running the code under.

When running as x86, you will get the following path:

"C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\machine.config"

When running as x64, you will get the following path:

"C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\machine.config"

Once the path has been found, we need to open the file and position ourselves at the correct location in the file (system.serviceModel/extensions):

// Map the application configuration file to the machine 
 // configuration file.
 Configuration config = ConfigurationManager.OpenMappedMachineConfiguration(configFile);

ConfigurationSectionGroup svcModel = config.SectionGroups.Get("system.serviceModel");
 ExtensionsSection extensions = (ExtensionsSection) svcModel.Sections.Get("extensions");

Now this is the point where I initially got stuck. I had no idea I had to cast the Section as a System.ServiceModel.Configuration.ExtensionsSection. Doing so, allows you to add your behaviorExtension in the config file as such:

ExtensionElement e = new ExtensionElement("MyName", "MyType, MyNamespace.MyType, Version=1.0.0.0, Culture=neutral, PublicKeyToken=4275f802b89cdd22");
 extensions.BehaviorExtensions.Add(e);
 extensions.SectionInformation.ForceSave = true;

config.Save(ConfigurationSaveMode.Full);

Don’t forget to set the ForceSave, as – without it – it doesn’t seem to write the update.

All together, this gives you the following code:

// Get the machine.config file.
 Configuration machineConfig = ConfigurationManager.OpenMachineConfiguration();
 // Get the machine.config file path.
 ConfigurationFileMap configFile = new ConfigurationFileMap(machineConfig.FilePath);

// Map the application configuration file to the machine 
 // configuration file.
 Configuration config = ConfigurationManager.OpenMappedMachineConfiguration(configFile);

ConfigurationSectionGroup svcModel = config.SectionGroups.Get("system.serviceModel");
 ExtensionsSection extensions = (ExtensionsSection) svcModel.Sections.Get("extensions");

ExtensionElement e = new ExtensionElement("MyName", "MyType, MyNamespace.MyType, Version=1.0.0.0, Culture=neutral, PublicKeyToken=4275f802b89cdd22");
 extensions.BehaviorExtensions.Add(e);
 extensions.SectionInformation.ForceSave = true;

config.Save(ConfigurationSaveMode.Full);

If you do like me and you want to adapt the x86 AND the x64 machine.config file, just replace the “Framework” in the x86 machine.config path into “Framework64” before doing the same.

I made myself a simple console application which allows me to call it while running the MSI for my BizTalk application. Only make sure the MSI runs as an administrator!

 

This post has been cross-posted at http://www.codit.eu/blog/2016/05/31/adding-behaviorextensions-to-machineconfig-via-c/

Advertisements