一般來說,.net 的exe assemly會存在一個對應的*.exe.config設定檔。當需要讀取配置資訊的時候,可以直接通過ConfigurationManager.AppSettings[index]來讀取*.exe.config中的索引值,但很少存在dll assembly需要config file的情況。假如當前dll assembly名為test.dll,如果在test.dll中調用ConfigurationManager來讀取test.dll.config,那麼是無法成功的!
當然,在dll assembly中要讀取其*.dll.config這種需求非常少見。但是確要讀取的話,可以採取以下方式,即強行制定其dll assembly的路徑。
以下代碼示範的是:編寫一個.net dll並將其發布為一個regasm test.dll /codebase /tlb將其發布為一個DCOM, 然後通過asp頁面來調用 。其中在test.dll中的公布的方法HelloWorld()需要讀取其test.dll.config中的key value.
dll assembly代碼如下:
C# version:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Configuration;
using System.IO;
using System.Reflection;
namespace AnotherDCOM
{
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface ITestClass
{
string HelloWorld();
}
[ClassInterface(ClassInterfaceType.AutoDispatch)]
public class SimpleClass:ITestClass
{
public string HelloWorld()
{
Assembly assembly;
System.Configuration.Configuration configuration;
ExeConfigurationFileMap map;
Uri uri;
map = new ExeConfigurationFileMap();
assembly = Assembly.GetCallingAssembly();
uri = new Uri(Path.GetDirectoryName(assembly.CodeBase));
map.ExeConfigFilename = Path.Combine(uri.LocalPath, assembly.GetName().Name + ".dll.config");
string str=ConfigurationManager.OpenMappedExeConfiguration(map, 0).AppSettings.Settings["MyString"].Value;
/*
說明:如果採取如下的傳統方法,讀取config key
string str = ConfigurationManager.AppSettings["MyString"];
如果採取這種方式的話, 則assembly不會讀取相應*.dll.config檔案;by default,只有exe assembly的設定檔才會被load
*/
if (str != null)
{
return str;
}
else
{
return "Hello World .net Another DCOM, Can't read config";
}
}
}
}
VB.net version
Imports System
Imports System.Runtime.InteropServices
Imports System.Reflection
Imports System.Configuration
Imports System.IO
Namespace NetDcom
<InterfaceType(ComInterfaceType.InterfaceIsIDispatch)> Public Interface ITestClass
Function HelloWorld() As String
End Interface
<ClassInterface(ClassInterfaceType.AutoDispatch), ProgId("NetDcom.SimpleClass"), ComVisible(True)> Public Class SimpleClass
Implements ITestClass
Public Function HelloWorld() As String Implements ITestClass.HelloWorld
Dim assembly As Assembly
Dim configuration As Configuration
Dim map As ExeConfigurationFileMap
Dim str As String
Dim uri As Uri
map = New ExeConfigurationFileMap
[assembly] = assembly.GetCallingAssembly
uri = New Uri(Path.GetDirectoryName([assembly].CodeBase))
map.ExeConfigFilename = Path.Combine(uri.LocalPath, ([assembly].GetName.Name & ".dll.config"))
str = ConfigurationManager.OpenMappedExeConfiguration(map, 0).AppSettings.Settings.Item("MyString").Value
If String.IsNullOrEmpty(str) <> True Then
HelloWorld = str
Else
HelloWorld = "Hello World, .net DCOM(vb.net)"
End If
End Function
End Class
End Namespace
app.config設定檔如下(編譯後會自動產生test.dll.config檔案):
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="MyString" value="Hello World"/>
</appSettings>
</configuration>
編譯發布之後,運行以下command將其註冊為DCOM
regasm test.dll /codebase /tlb
說明:如果.net dll要註冊成為COM的話,需要幾個必備的條件:
1. dll要設定相應的System.runtime.InteropServices的相應attribute,如山代碼所示。
2. (C#中)assemblyinfo.cs中, comvisible要設定為true。
3. 產生dll assembly的時候,一定要選中 Register for ComInterop複選框,如下所示
然後,通過asp調用該DCOM如下:
<%
set obj=CreateObject("AnotherDCOM.SimpleClass")
Response.write obj.HelloWorld()
%>
通過procmon我們可以看到,該dll.config被爭取讀取了:)