Сборка 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, что-то вроде создания простого текстового файла и последующего его поиска, чтобы вы могли увидеть, где ваша система фактически выполняет вашу библиотеку.