2008-12-11 18 views
1

我想在.net代碼中使用EntLib 3.1來註冊COM互操作的DLL。我在哪裏放置配置文件?Entlib和interop:它工作,配置文件去哪裏?

或者,有沒有辦法在dll代碼中指定應該從哪裏獲取entlib配置?由於我的DLL將從COM調用,我並不總是知道什麼exe會調用它。

我創建了一個簡單的應用程序,它使用entlib Logging和兩個類:'CallingApp'和'MyComThing'。當我從CallingApp調用MyComThing的方法時,它使用CallingApp的配置文件中的配置進行記錄。當我從vbs腳本調用MyComThing的方法時,即通過COM,我收到一條錯誤消息:「在配置源中找不到配置部分」。我的COMThing.dll.config文件與註冊的COMThing.dll位於同一文件夾中,即在bin \ debug \文件夾中。

謝謝!

回答

3

答案是,企業庫默認使用的exe的配置文件。如果你正在生成一個dll,包括COM,那麼出於很好的理由你可能不想依賴於調用的可執行文件。對此的一種解決方案(可能有其他解決方案)是自己創建企業庫對象,而不是使用默認的對象,並告訴他們從哪裏獲取配置。這並不像看起來那麼可怕,也不需要重新編譯entlib或類似的東西。

簡單地使用Logger.Write(),而不是我做了如下: 一)創建日誌寫入,使用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.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> 

在構建檢查'Register for COM interop'下的項目屬性。生成項目,然後創建下面的.vbs文件:

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

如果您雙擊這個VBS文件要顯示以「由VBS從COM叫」文本的消息框,並寫信給你的應用程序中的條目事件日誌。這表明,雖然執行過程是C:\ WINDOWS \ System32 \ WScript.exe(或類似),它從您的dll的配置文件獲取配置。

我基於'使用多個配置資源'下的信息here

請注意,Logger類包含大量不同參數的好助手方法。由於我們正在使用LogWriter類,所以我們沒有得到這個魔法。就我個人而言,我將在我的圖書館內創建另一個課程,以Logger爲基礎執行相同的工作。

引用的文章顯示了應用於數據庫和異常應用程序塊的相同原理。大概相同的模型可以適用於大多數/全部。

0

檢查我遇到的相關問題。也許它有一些幫助。

How to include COM components on a published .Net site?

+0

謝謝,但我沒有創建COM obj的問題,問題是EntLib使用exe的配置文件的配置信息。我有一個COM對象,並想使用EntLib的日誌記錄,但我不知道什麼exe會調用COM對象,所以想要指定配置文件的diff位置。 – Rory 2008-12-11 13:59:28