Сборка ComVisible .NET и app.config

  • У меня есть сборка.NET с некоторыми классами, помеченными как ComVisible
  • Эта сборка зарегистрирована в regasm /codebase "assembly_path"
  • У меня есть имя app.config (на самом деле - MyAssemblyName.dll.config) которые находятся в папке сборки
  • Я получаю доступ к appSettings в моей сборке через ConfigurationManager.AppSettings["SettingName"]
  • У меня есть файл VBScript, который создает мой COM-объект через CreateObject("...")
  • Когда объект создан (из VBScript), ConfigurationManager.AppSettings["SettingName"] возвращает ноль. Похоже, что сборка не видит файл конфигурации.

Что я должен сделать, чтобы это работало?

4 ответа

Решение

Один из возможных способов, как сказал Комыг, - это читать конфигурационный файл напрямую, а не использовать встроенное поведение ConfigurationManager. Для тех, у кого будет такая же проблема: вместо

ConfigurationManager.AppSettings["SettingName"]

ты можешь использовать:

var _setting = ConfigurationManager.AppSettings["SettingName"];
// If we didn't find setting, try to load it from current dll's config file
if (string.IsNullOrEmpty(_setting))
{
    var filename = Assembly.GetExecutingAssembly().Location;
    var configuration = ConfigurationManager.OpenExeConfiguration(filename);
    if (configuration != null)
        _setting = configuration.AppSettings.Settings["SettingName"].Value;
}

Таким образом, вы всегда будете использовать настройки чтения из файла YourAssemblyName.dll.config который лежит в папке вашей сборки. Это позволит вам использовать и другие функции для app.config (лайк appSetting"s file attribute), который будет недоступен, если вы будете использовать XPath или что-то подобное.

У меня такая же проблема. Расширение оболочки проводника (видимое Com, зарегистрированное через regasm /codebase), для которого требовался файл app.config, не смог найти ни строки подключения, ни настройки.

Что я сделал:

string assemblyLoc          = GetType().Assembly.Location;
string configName           = assemblyLoc + ".config";
AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", configName);

Это предполагает, что файл конфигурации хранится в том же каталоге, что и сборка.

Я использовал ответ спутника, отлично работал в одной тестовой среде IIS, но не в другой. Оказывается, что после того, как вы установили свойство APP_CONFIG_FILE, вам может понадобиться использовать отражение, чтобы прикоснуться к классу ConfigurationManager, чтобы внести изменения. Я использовал эту функцию после установки свойства APP_CONFIG_FILE:

    private static void ResetConfiguration()
    {
        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);
    }

Помимо этого, вероятно, хорошей идеей будет сначала сохранить свойство, а затем восстановить его, когда вы закончите:

string oldConfigName = AppDomain.CurrentDomain.GetData("APP_CONFIG_FILE").ToString();
        //do custom stuff in here
        AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", oldConfigName); //re-point to the original configuration.
        ResetConfiguration();

Все в одной папке (ваш dll, скрипт vb, файл конфигурации и т. Д.)? Если нет, вы можете попытаться добавить полный путь к файлу конфигурации в переменной окружения PATH...

Также, если вы запускаете этот скрипт VB в Internet Explorer, у вас могут возникнуть проблемы с безопасностью (обычно IE не позволяет вам получить доступ к жесткому диску). В этом случае вы можете попытаться поместить файл конфигурации на свой рабочий стол, я не знаю почему, но это похоже на путь по умолчанию при запуске программы ActiveX, поэтому это также может быть верно для сценария VB.

Наконец, вы можете добавить некоторую отладку в вашу dll, что-то вроде создания простого текстового файла и последующего его поиска, чтобы вы могли увидеть, где ваша система фактически выполняет вашу библиотеку.

Другие вопросы по тегам