ここでインストール中に web.config を暗号化する例を見つけましたが、私のアプリは Windows サービスです。このaspnetreg_iis
方法は、web.config ファイルに対してのみ機能します。
構成ファイルをプログラムで暗号化する方法は知っていますが、WiX を使用してそれを行うことはできないと思います。私が間違っている?何か案は?
ここでインストール中に web.config を暗号化する例を見つけましたが、私のアプリは Windows サービスです。このaspnetreg_iis
方法は、web.config ファイルに対してのみ機能します。
構成ファイルをプログラムで暗号化する方法は知っていますが、WiX を使用してそれを行うことはできないと思います。私が間違っている?何か案は?
これが私が最終的に得たものです...
WiX と DTF を使用してマネージド コード カスタム アクションを作成し、構成ファイルの特定のセクションを暗号化しました。
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);
}
}
この質問を促した私の理解不足の一部は、DTF を使用してマネージ コードでカスタム アクションを安全に作成できることを知らなかったことです。DTF のドキュメントはまばらですが、一度機能するようになれば素晴らしいものです。
これは、InstallFinalize の後にカスタム アクションをスケジュールした場合にのみ機能することがわかりました。
これを実現するための WiX 設定は次のとおりです。
<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>
これらのブログ/サイトは私がそこにたどり着くのを助け、上記のコードの多くはそれらから派生したものです:
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...返信ありがとうございます。構成ファイルを暗号化するためにアセンブリを読み込む必要がないことがわかりました。
これを使うなら、try catch を使って ActionResult を返せばいいのですが… 上記は疑似コードです。
最後に、DataProtectionConfigurationProvider を使用しています。RSA プロバイダーについては、ジャンプする必要があるフープがさらにいくつかあると思います。
これが誰かに役立つことを願っています!
カスタム アクション内で実行できるはずです。私が見つけたキャッチは、ExeConfigurationFileMap のアセンブリをロードすると例外がスローされることですが、AssemblyResolve ハンドラーを AppDomain に追加することでこれを処理できます。これは、マシン暗号化キーを使用して保護された構成セクションを暗号化/復号化するために作成したリッチ クライアント アプリからの一種のハックアップです。これはおそらく最も美しいコードではありませんが、そこからイメージをつかんでいただければ幸いです。このコードは、使用する ProtectionProvider が構成ファイルで定義されていることを前提としています。
//class global
static System.Reflection.Assembly DefiningAssembly;
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.AssemblyResolve += new ResolveEventHandler(MyResolveEventHandler);
static System.Reflection.Assembly MyResolveEventHandler(object sender, ResolveEventArgs args)
{
return DefiningAssembly;
}
次に、次のように構成をロードできます。
DefiningAssembly = System.Reflection.Assembly.LoadFrom("path to defining assembly for config");
//Set the Configuration using an ExeConfigurationFileMap - This works for any .config file.
ExeConfigurationFileMap CfgMap = new ExeConfigurationFileMap();
CfgMap.ExeConfigFilename = "path to config file";
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(CfgMap, ConfigurationUserLevel.None);
List<string> DefiningAssemblyTypes = new List<string>();
foreach (System.Type type in DefiningAssembly.GetExportedTypes())
{
DefiningAssemblyTypes.Add(type.Name);
}
foreach (ConfigurationSection tempSection in config.Sections)
{
if (DefiningAssemblyTypes.Contains(tempSection.ElementInformation.Type.Name))
{
section = tempSection;
break;
}
}
ProtectionProviderName = section.SectionInformation.ProtectionProvider.Name;
section.SectionInformation.ProtectSection(ProtectionProviderName);
config.Save(ConfigurationSaveMode.Minimal, true);
これがお役に立てば幸いです。