21

構成ファイルのカスタム構成セクションにアクセスしようとして非常に苦労しています。

構成ファイルは、プラグインとしてロードされた .dll から読み取られています。Configuration Section Designer VS アドインを使用して、構成と必要なコードを作成しました。

名前空間は「ImportConfiguration」です。ConfigurationSection クラスは「ImportWorkflows」です。アセンブリは ImportEPDMAddin です。

xml:

  <configSections>
    <section name="importWorkflows" type="ImportConfiguration.ImportWorkflows, ImportEPDMAddin"/>
  </configSections>

構成を読み込もうとすると、次のエラーが表示されます。

importWorkflows の構成セクション ハンドラーの作成中にエラーが発生しました: ファイルまたはアセンブリ 'ImportEPDMAddin.dll' またはその依存関係の 1 つを読み込めませんでした。システムは、指定されたファイルを見つけることができません。

プラグインをロードするソフトウェアがdllとその依存関係を独自のディレクトリに配置するため、dllは実行可能ファイルと同じディレクトリには存在しません。(私はそれを制御することはできません。)

シングルトン インスタンスのコードを次のように編集しました。

string path = System.Reflection.Assembly.GetCallingAssembly().CodeBase;
path = path.Replace("file:///", "");
System.Configuration.Configuration configuration = System.Configuration.ConfigurationManager.OpenExeConfiguration(path);
return configuration.GetSection(ImportWorkflowsSectionName) as ImportConfiguration.ImportWorkflows;

単純な NameValueFileSectionHandler も使用してみましたが、ファイルまたはアセンブリ 'System' を読み込めないという例外が発生します。

多数のブログ投稿や記事を読んだことがありますが、dll の構成ファイルを読み取ることができるように思えますが、それを機能させることはできません。何か案は?ありがとう。

4

7 に答える 7

36

残念ながら、ImportEPDMAddinアセンブリを実行可能ファイルと同じフォルダーに配置するか、使用している .Net フレームワークに関連する .Net フレームワーク フォルダー (つまり、C:\Windows\Microsoft.NET\Framework\v2) に配置する必要があります。 .0.50727)、またはグローバル アセンブリ キャッシュに登録されています。

他の唯一のオプションは、構成ハンドラーの定義クラスを含むアセンブリへのパスがわかっている場合、次のような参照なしでそれをロードできることです。

//Class global
private Assembly configurationDefiningAssembly;

protected TConfig GetCustomConfig<TConfig>(string configDefiningAssemblyPath, 
    string configFilePath, string sectionName) where TConfig : ConfigurationSection
{
    AppDomain.CurrentDomain.AssemblyResolve += new 
        ResolveEventHandler(ConfigResolveEventHandler);
    configurationDefiningAssembly = Assembly.LoadFrom(configDefiningAssemblyPath);
    var exeFileMap = new ExeConfigurationFileMap();
    exeFileMap.ExeConfigFilename = configFilePath;
    var customConfig = ConfigurationManager.OpenMappedExeConfiguration(exeFileMap, 
        ConfigurationUserLevel.None);
    var returnConfig = customConfig.GetSection(sectionName) as TConfig;
    AppDomain.CurrentDomain.AssemblyResolve -= ConfigResolveEventHandler;
    return returnConfig;
}

protected Assembly ConfigResolveEventHandler(object sender, ResolveEventArgs args)
{
    return configurationDefiningAssembly;
}

これがないと例外がスローされるため、AssemblyResolve イベントを必ず処理してください。

于 2009-11-05T19:30:42.207 に答える
6

メイン アプリケーションの構成ファイルで、次を追加します (ここで、plugins はアセンブリの読み込み元のフォルダーです。セミコロンで区切られた複数のパスを使用できます。

<runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
        <probing privatePath=".;.\Plugins"/>
    </assemblyBinding>
</runtime>

http://msdn.microsoft.com/en-us/library/823z9h8w%28v=vs.90%29.aspxから取得

于 2013-01-09T09:17:55.243 に答える
1

DLL が最初にロードされていることを確認しましたか? おそらくAssembly.LoadFile("PATH")

System.Configuration のクラスを正しく動作させることができない場合は、いつでも XmlDocument を使用して構成ファイルを手動で解析することに頼ることができます。XPath を使用して、データの取得を容易にします。例(上記のパス変数を想定):

var document = new XmlDocument();
document.Load(path);
var node = document.SelectSingleNode("configuration/importWorkflows/add[@name='KEY']");
// Do whatever with node
于 2009-11-05T18:54:45.757 に答える
1

ホスト アプリケーションの構成ファイルでプローブ パスが正しく設定されていることを確認できますか? 必要な参照が現在のアプリケーション ドメインに読み込まれていない可能性があります。

アセンブリ バインド -> プローブ

于 2009-11-05T19:28:06.987 に答える
0

rileywhite のサプリメントを使用して AJ の回答を試しましたが、うまくいかないことがわかりました。

私のシナリオでは、カスタム ConfigurationSection クラスが既に実行中のアセンブリにあり、それを読み込もうとするとスタック オーバーフローが発生します。OPから報告されたように問題を解決したとしても、GACに入れたくありませんでした。

最終的に、これは私の目的には十分に機能することがわかりました。多分他の人はそれが役に立つと思うでしょう:

public class CustomConfigurationSection : ConfigurationSection {
  public CustomConfigurationSection()
  {
    var reader = XmlReader.Create(<path to my dll.config>);
    reader.ReadToDescendant("CustomConfigurationSection");
    base.DeserializeElement(reader,false);
  }

  // <rest of code>
}
于 2014-05-23T18:17:21.380 に答える