2

COM Interop 経由で MS Access から呼び出されるカスタム .Net dll コンポーネントがあります。

MSACCESS.EXE は呼び出しプロセスであるため、既定では、MS Access がインストールされている場所で、アセンブリの .config ファイルと参照されているすべての ddl を見つけようとします。

配置上の懸念から、すべてのカスタム コードを MS Office フォルダー構造内からではなく、別の場所から実行する必要があります。

以下を使用して、アセンブリにその構成情報をカスタムの場所から強制的にロードさせることができました。

AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", customPath);

typeof(ConfigurationManager)
            .GetField("s_initState", BindingFlags.NonPublic |
                                        BindingFlags.Static)
            .SetValue(null, 0);

typeof(ConfigurationManager)
            .GetField("s_configSystem", BindingFlags.NonPublic |
                                        BindingFlags.Static)
            .SetValue(null, null);

typeof(ConfigurationManager)
            .Assembly.GetTypes()
            .Where(x => x.FullName ==
                        "System.Configuration.ClientConfigPaths")
            .First()
            .GetField("s_current", BindingFlags.NonPublic |
                                    BindingFlags.Static)
            .SetValue(null, null);

これは問題なく機能しているようで、この時点ではロギング以外はすべて機能しているようです。いずれにせよ、log4net.dll ファイルは、MSACCESS.EXE が配置されているディレクトリ以外の場所からはロードされません。

app.config ファイル (log4net.dll は .Net コンポーネントと同じディレクトリにあります) に以下を追加しようとしましたが、無視されているようです。

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

SysInternals procmon を使用して、コンポーネントが Access から呼び出されたときに dll が検出され、正常に配置されていることを確認しましたが、MS Access ディレクトリからロードしようとして失敗しました。

とにかく、必要な場所から log4net.dll を強制的にロードする方法はありますか?

log4net 内部デバッグ ログからの出力は次のとおりです。

log4net:ERROR Failed to parse config file. Is the <configSections> specified as: <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net, Version=1.2.11.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a" />
System.Configuration.ConfigurationErrorsException: An error occurred creating the configuration section handler for log4net: Could not load file or assembly 'log4net' or one of its dependencies. The system cannot find the file specified. (C:\mycomponent\alt.config line 4) ---> System.IO.FileNotFoundException: Could not load file or assembly 'log4net' or one of its dependencies. The system cannot find the file specified.
   at System.Configuration.TypeUtil.GetTypeWithReflectionPermission(IInternalConfigHost host, String typeString, Boolean throwOnError)
   at System.Configuration.RuntimeConfigurationRecord.RuntimeConfigurationFactory.Init(RuntimeConfigurationRecord configRecord, FactoryRecord factoryRecord)
   at System.Configuration.RuntimeConfigurationRecord.RuntimeConfigurationFactory.InitWithRestrictedPermissions(RuntimeConfigurationRecord configRecord, FactoryRecord factoryRecord)
   at System.Configuration.RuntimeConfigurationRecord.CreateSectionFactory(FactoryRecord factoryRecord)
   at System.Configuration.BaseConfigurationRecord.FindAndEnsureFactoryRecord(String configKey, Boolean& isRootDeclaredHere)
   --- End of inner exception stack trace ---
   at System.Configuration.BaseConfigurationRecord.FindAndEnsureFactoryRecord(String configKey, Boolean& isRootDeclaredHere)
   at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)
   at System.Configuration.BaseConfigurationRecord.GetSection(String configKey)
   at System.Configuration.ClientConfigurationSystem.System.Configuration.Internal.IInternalConfigSystem.GetSection(String sectionName)
   at System.Configuration.ConfigurationManager.GetSection(String sectionName)
   at System.Configuration.ConfigurationSettings.GetConfig(String sectionName)
4

1 に答える 1