Here is what I ended up with...
I used WiX and DTF to created a managed code Custom Action to encrypt a given section of a config file:
public static void EncryptConfig(Session session)
{
var configPath = session["APPCONFIGPATH"];
var sectionToEncrypt = session["SECTIONTOENCRYPT"];
var fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = configPath;
var configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
ConfigurationSection section = configuration.GetSection(sectionToEncrypt);
if (!section.SectionInformation.IsProtected)
{
section.SectionInformation.ProtectSection("DataProtectionConfigurationProvider");
section.SectionInformation.ForceSave = true;
configuration.Save(ConfigurationSaveMode.Modified);
}
}
Part of my lack of understanding that prompted this question was not knowing that you can safely create custom actions in managed code using DTF. Documentation is sparse on DTF, but once you get it working, it is great.
I found that this only worked if I scheduled the custom action after InstallFinalize.
Here is the WiX config to make it happen:
<InstallExecuteSequence>
<Custom Action="EncryptConfigurationFiles" After="InstallFinalize" />
</InstallExecuteSequence>
<Fragment>
<Binary Id="YourProject.CustomActions.dll" SourceFile="$(var.YourProject.CustomActions.TargetDir)$(var.YourProject.CustomActions.TargetName).CA.dll" />
<CustomAction Id="EncryptConfigurationFiles" BinaryKey="YourProject.CustomActions.dll" DllEntry="EncryptConfig" Return="check" />
</Fragment>
These blogs/sites helped me get there and much of the code from above was derived from them:
http://geekswithblogs.net/afeng/Default.aspx
http://blog.torresdal.net/2008/10/24/WiXAndDTFUsingACustomActionToListAvailableWebSitesOnIIS.aspx
http://blogs.msdn.com/jasongin/archive/2008/07/09/votive-project-platform-configurations.aspx
@PITADeveloper... Thanks for the response. I found that I did not need to load the assembly to encrypt the config file.
If you use this, you should use a try catch and return an ActionResult... The above is pseudo-code.
Finally, I'm using the DataProtectionConfigurationProvider. For the RSA Provider, I think there are a couple more hoops to jump through.
I hope this helps someone!