1

COM相互運用に登録されているdllの.netコード内でEntLib 3.1を使用しようとしています。設定ファイルはどこに置くのですか?

または、dll コード内で entlib 構成を取得する場所を指定する方法はありますか? 私のdllはCOMから呼び出されるため、どのexeがそれを呼び出すかは常にわかりません。

「CallingApp」と「MyComThing」の 2 つのクラスを持つ entlib Logging を使用する単純なアプリを作成しました。CallingApp から MyComThing のメソッドを呼び出すと、CallingApp の構成ファイルの構成を使用してログに記録されます。MyComThing のメソッドを vbs スクリプトから、つまり COM を介して呼び出すと、「ログの構成セクションが構成ソースに見つかりません」というエラーが表示されます。私の COMThing.dll.config ファイルは、登録された COMThing.dll と同じフォルダ、つまり bin\debug\ フォルダにあります。

ありがとう!

4

2 に答える 2

3

答えは、Enterprise Library がデフォルトで exe の構成ファイルを使用することです。COM を含む dll を作成している場合、正当な理由により、呼び出し元の実行可能ファイルに依存したくない場合があります。これに対する 1 つの解決策 (他にもあるかもしれません) は、デフォルトのものを使用する代わりにエンタープライズ ライブラリ オブジェクトを自分で作成し、構成の取得元を指定することです。これは見かけほど怖くはなく、entlib などを再コンパイルする必要もありません。

単純に Logger.Write() を使用する代わりに、次のことを行いました: a) dll の構成ファイルを使用して、ログ ライターを作成します。

        string dllConfigFilename = Assembly.GetExecutingAssembly().Location + ".config";
        FileConfigurationSource exceptionsSource = new FileConfigurationSource(dllConfigFilename);
        LogWriterFactory writerFactory = new LogWriterFactory(exceptionsSource);
        logWriter = writerFactory.Create();

b) 次に、コード内でこのログ ライターを使用します。

        LogEntry log = new LogEntry();
        log.Message = message;
        log.Categories = new string[] { "General" };
        logWriter.Write(log);

私が作成したサンプル オブジェクトの完全なコードを次に示します。参照は、Microsoft.Practices.EnterpriseLibrary.Common、Microsoft.Practices.EnterpriseLibrary.Logging、Microsoft.Practices.ObjectBuilder、System、System.Data、System.Windows.Forms、System.Xml でした。

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Reflection;
using System.IO;
using Microsoft.Practices.EnterpriseLibrary.Logging;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;

namespace COMThing
{
    [ComVisible(true)]
    public class MyComThing : MyComInterface
    {
        LogWriter logWriter; 

        public MyComThing()
        {
            string dllConfigFilename = Assembly.GetExecutingAssembly().Location + ".config";
            FileConfigurationSource exceptionsSource = new FileConfigurationSource(dllConfigFilename);
            LogWriterFactory writerFactory = new LogWriterFactory(exceptionsSource);
            logWriter = writerFactory.Create();
        }

        public bool ProcessMessage(string message)
        {
            LogEntry log = new LogEntry();
            log.Message = message;
            log.Categories = new string[] { "General" };
            logWriter.Write(log);
            MessageBox.Show(message);
            return true;
        }
    }

}

プロジェクトには、「出力ディレクトリにコピー」を「常にコピー」に設定した COMThing.dll.config ファイルが含まれていました。これは、アプリケーション イベント ログにログ情報を書き込む単純な構成です。構成ファイルの内容は次のとおりです。

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging, Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    <section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
  </configSections>
  <loggingConfiguration name="Logging Application Block" tracingEnabled="true"
    defaultCategory="General" logWarningsWhenNoCategoriesMatch="true">
    <listeners>
      <add source="COMThing Logger" formatter="Text Formatter" log="Application"
        machineName="" listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FormattedEventLogTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
        traceOutputOptions="None" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FormattedEventLogTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
        name="Formatted EventLog TraceListener" />
    </listeners>
    <formatters>
      <add template="Timestamp: {timestamp}&#xD;&#xA;Message: {message}&#xD;&#xA;Category: {category}&#xD;&#xA;Priority: {priority}&#xD;&#xA;EventId: {eventid}&#xD;&#xA;Severity: {severity}&#xD;&#xA;Title:{title}&#xD;&#xA;Machine: {machine}&#xD;&#xA;Application Domain: {appDomain}&#xD;&#xA;Process Id: {processId}&#xD;&#xA;Process Name: {processName}&#xD;&#xA;Win32 Thread Id: {win32ThreadId}&#xD;&#xA;Thread Name: {threadName}&#xD;&#xA;Extended Properties: {dictionary({key} - {value}&#xD;&#xA;)}"
        type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
        name="Text Formatter" />
    </formatters>
    <categorySources>
      <add switchValue="All" name="General">
        <listeners>
          <add name="Formatted EventLog TraceListener" />
        </listeners>
      </add>
    </categorySources>
    <specialSources>
      <allEvents switchValue="All" name="All Events">
        <listeners>
          <add name="Formatted EventLog TraceListener" />
        </listeners>
      </allEvents>
      <notProcessed switchValue="All" name="Unprocessed Category" />
      <errors switchValue="All" name="Logging Errors &amp; Warnings">
        <listeners>
          <add name="Formatted EventLog TraceListener" />
        </listeners>
      </errors>
    </specialSources>
  </loggingConfiguration>
</configuration>

ビルドの下のプロジェクト プロパティで、[COM 相互運用に登録] をオンにします。プロジェクトをビルドし、次の .vbs ファイルを作成します。

Set obj = CreateObject("COMThing.MyComThing")
obj.ProcessMessage("called from com by vbs")

この vbs ファイルをダブルクリックすると、「called from com by vbs」というテキストを含むメッセージ ボックスが表示され、アプリケーション イベント ログにエントリが書き込まれます。これは、実行中のプロセスが C:\WINDOWS\System32\WScript.exe (または同様のもの) であるときに、dll の構成ファイルから構成を取得していることを示しています。

これは、 「複数の ConfigurationSource を使用する」の下の情報に基づいています。

Logger クラスには、さまざまな引数を持つ便利なヘルパー メソッドが多数含まれていることに注意してください。LogWriter クラスを使用しているため、この魔法は利用できません。個人的には、Logger に基づいて、ライブラリ内に同じジョブを実行する別のクラスを作成します。

参照されている記事では、データベースおよび例外アプリケーション ブロックに適用される同じ原則が示されています。おそらく、それらのほとんど/すべてに同じモデルを適用できます。

于 2008-12-11T18:07:33.407 に答える
0

私が直面した関連する問題を確認してください。多分それはいくつかの助けになります。

公開された .Net サイトに COM コンポーネントを含める方法は?

于 2008-12-11T13:47:19.643 に答える