INDEX
MSBuild で、config をマージする
ConfigMerge
クラスライブラリ(DLL)で、設定などを行ったときに、app.config に設定され、内容が参照される。実際に実行時には、アプリケーション(EXE)の config が参照されるため、アセンブリ名の config ファイルに内容が入っている必要がある。
なので、ビルド時に、クラスライブラリの設定(ClassLibrary.dll.config)の内容を、アプリケーションの設定(Application.exe.config)の内容にマージするようにビルドタスクを設定する。
Visual Studio のGUIでは設定出来ないので、直接プロジェクトファイルを編集する。
MSBuildTask
config ファイル、つまり、XMLファイルを読み込んでマージするタスク。
1 |
<UsingTask TaskName="ConfigMerge" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v$(MSBuildToolsVersion).dll" >
<ParameterGroup>
<!-- SauceConfig: マージする DLL の config ファイル -->
<SauceConfig ParameterType="System.String" Required="true" />
<!-- MergedConfig: マージされる EXE の config ファイル -->
<MergedConfig ParameterType="System.String" Required="true" />
</ParameterGroup>
<Task>
<!-- app.config をマージする MSBuildTask -->
<Reference Include="System" />
<Reference Include="System.Xml" />
<Using Namespace="System" />
<Using Namespace="System.IO" />
<Using Namespace="System.Xml" />
<Code Type="Fragment" Language="cs"><![CDATA[
Log.LogMessage(MessageImportance.High, "SauceConfig=" + SauceConfig);
Log.LogMessage(MessageImportance.High, "MergedConfig=" + MergedConfig);
if (File.Exists(SauceConfig) && File.Exists(MergedConfig))
{
XmlDocument sDoc = new XmlDocument();
sDoc.Load(SauceConfig);
XmlDocument mDoc = new XmlDocument();
mDoc.Load(MergedConfig);
_Success = MergeXmlElement(mDoc, sDoc);
mDoc.Save(MergedConfig);
}
return _Success;
}
private bool MergeXmlElement(XmlNode mergeNode, XmlNode sauceNode)
{
bool _Success = true;
if (mergeNode == null || sauceNode == null) return false;
foreach (XmlNode scn in sauceNode.ChildNodes)
{
if (scn.NodeType != XmlNodeType.Element) continue; // 要素以外は無視
bool needAdd = true; // 見つからないときは追加する
foreach (XmlNode mcn in mergeNode.ChildNodes)
{
if (mcn.NodeType != XmlNodeType.Element) continue; // 要素以外は無視
if (!string.Equals(mcn.Name, scn.Name)) continue; // 同じ要素以外はスキップ
if (string.Equals(scn.OuterXml, mcn.OuterXml)) return true; // 同じXMLの内容なら終わり
XmlNode sAttr = scn.Attributes["name"];
if (sAttr == null) sAttr = scn.Attributes["key"];
XmlNode mAttr = mcn.Attributes["name"];
if (mAttr == null) mAttr = mcn.Attributes["key"];
if (sAttr == null || mAttr == null)
{
// name/key 属性なし
if (mcn.HasChildNodes)
{
if (!MergeXmlElement(mcn, scn)) _Success = false;
}
else
{
mergeNode.ReplaceChild(mergeNode.OwnerDocument.ImportNode(scn, true), mcn);
}
needAdd = false;
break;
}
else if (!string.Equals(mAttr.Name, sAttr.Name))
{
// name/key 属性なし(属性名違い)
}
else if (!string.Equals(mAttr.Value, sAttr.Value))
{
// name/key 属性あり(属性値違い)
}
else
{
// name/key 属性あり(同じキー項目)
if (mcn.HasChildNodes)
{
if (!MergeXmlElement(mcn, scn)) _Success = false;
}
else
{
mergeNode.ReplaceChild(mergeNode.OwnerDocument.ImportNode(scn, true), mcn);
}
needAdd = false;
break;
}
} /* foreach (XmlNode node in mergeNode.ChildNodes) */
if (needAdd)
{
mergeNode.AppendChild(mergeNode.OwnerDocument.ImportNode(scn, true));
}
} /* foreach (XmlNode node in sauceNode.ChildNodes) */
]]></Code>
</Task>
</UsingTask>
|
Target
上記の MSBuildTask を呼び出して、config ファイルをマージするようにする。
1 |
<Target Name="AfterBuild" Condition="exists('$(TargetDir)$(TargetName).config')">
<!-- CommonLibrary is Reference DLL project. -->
<ConfigMerge MergedConfig="$(TargetDir)$(TargetName).config" SauceConfig="$(SolutionDir)CommonLibrary\$(OutDir)CommonLibrary.dll.config" />
</Target>
|
最終更新時間:2016年12月04日 16時04分57秒 指摘や意見などあればSandBoxのBBSへ。