Могу ли я использовать / получить доступ к app.config из кода .net при вызове через COM - PullRequest
7 голосов
/ 18 февраля 2010

У меня есть набор библиотек .net, которые я хочу вызывать из Excel VBA (эта часть работает нормально). Эти библиотеки зависят от настроек в app.config. Я знаю, что могу ввести эти параметры в файл excel.exe.config (расположенный в том же каталоге, что и файл excel.exe), но это не очень удобное для меня решение, так как я вижу возникновение конфликтов, если более чем одно приложение хочет сделать это.

У меня простой вопрос: есть ли способ, которым открываемые COM-файлы ссылаются на соответствующие файлы конфигурации?

Пример app.config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="test" value="Hello world!" />
  </appSettings>
</configuration>

Образец c #:

namespace ExcelVbaFacingCode
{
    public class SimpleAppSettingReader
    {
        public string GetValue(string key)
        {
            return ConfigurationManager.AppSettings[key];
        }
    }
}

Образец VBA:

Public Sub Test()
    Dim Test As New SimpleAppSettingReader
    Dim sampleValue As String
    sampleValue = Test.GetValue("test")
    MsgBox "Value: '" + sampleValue + "'", vbOKOnly
End Sub

Ответы [ 6 ]

3 голосов
/ 01 марта 2010

У меня были похожие проблемы с web.config .... Я нашел интересное решение. Вы можете капсулировать функцию чтения конфигурации, например. как то так:

public class MyClass {

public static Func<string, string> GetConfigValue = s => ConfigurationManager.AppSettings[s];

//...

}

А потом обычно используйте

string connectionString = MyClass.GetConfigValue("myConfigValue");

но в особом случае сначала "переопределяем" функцию следующим образом:

MyClass.GetConfigValue = s =>  s == "myConfigValue" ? "Hi", "string.Empty";

Подробнее об этом:

http://rogeralsing.com/2009/05/07/the-simplest-form-of-configurable-dependency-injection/

3 голосов
/ 24 февраля 2010

Когда вызывается ConfigurationManager.AppSettings, он автоматически открывает файл конфигурации выполняющейся сборки. В вашем случае Excel является исполняющим приложением, поэтому вы не можете открыть файл конфигурации .Net DLL.

Это было сделано по причине. Одна DLL может быть вызвана из нескольких типов приложений, каждое из которых может иметь разные требования (и, возможно, разные базы данных, например). По этой причине приложение указывает настройки, а не ссылочную сборку.

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

1 голос
/ 02 марта 2010

Вы действительно можете указать файл конфигурации, который будет использоваться API-интерфейсами конфигурации .NET, но вы должны сделать это до создания AppDomain (что не так просто, как кажется). Так работает ASP.NET дляпример.Он настраивает AppDomain для использования файла "web.config", расположенного в виртуальном каталоге, в отличие от необходимости w3p.exe.config или чего-то другого.

Вы можете сделать это тоже, но вам нужно создатьвторичный AppDomain.Само по себе это хорошая идея по многим причинам, связанным с несколькими надстройками и ссылками на сборки.Но одна из вещей, которую вы можете вставить в настройку AppDomain , - это имя / путь к файлу «app.config».

Для создания нового AppDomain вы можете использовать «shim»это немного стандартного кода C ++, который настраивает и запускает AppDomain, а остальным кодом с этого момента можно управлять кодом.

Есть статья на MSDN, написанная Эндрю Уайтчепелом и названная IsolatingРасширения Office с помощью мастера COM Shim .Я не буду лгать, это не тривиальная концепция, но и не так уж плохо.Для вас есть мастер, который создает проект C ++, который загружает надстройку .NET в новый домен приложений.Конфигурирование AppDomain должно быть выполнено до его загрузки, поэтому вам нужно добавить следующее в созданный мастером код:

// CLRLoader.cpp
HRESULT CCLRLoader::CreateLocalAppDomain()
{

    ... snip ...

    // Configure the AppDomain to use a specific configuration file
    pDomainSetup->put_ConfigurationFile(CComBSTR(szConfigFile));

    ... snip ...

}

Стоит также отметить, что если / когда вы конвертируете в VSTOпроект, среда выполнения VSTO делает всю эту конфигурацию AppDomain для вас.Каждый надстройка VSTO работает в своем собственном домене приложений со своим собственным файлом app.config.

1 голос
/ 18 февраля 2010

Попробуйте:

ConfigurationManager.OpenExeConfiguration("foo.config");
0 голосов
/ 26 декабря 2010

Существует еще один способ загрузки файлов .config из компонентов COM, которые я использую в течение нескольких лет.

Работает так:

  • Открыть dcomcnfg.exe
  • Создание нового приложения COM +
  • Введите папку с вашим com-объектом в «Root Directory приложения» на вкладке «Активация»
  • Добавьте ваш ком объект в приложение
  • Поместите файл с именем «Application.manifest» в папку. Файл должен содержать:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" />

  • Поместите файл конфигурации в ту же папку. Имя файла конфигурации должно быть «Application.config», т.е. не «myapp.config»

Вы можете использовать все обычные теги в application.config (например, время выполнения, system.diagnostics и т. Д.)


Я использую vbscript для создания приложения COM +:

Dim allapps, newapp
Set allapps = objCatalog.GetCollection("Applications")

Set newapp = allapps.Add()
newapp.Value("Name") = MyComAppName
newapp.Value("ApplicationAccessChecksEnabled") = False 
newapp.Value("Activation") = 1 '  own process
newapp.Value("ApplicationDirectory") = WScript.CreateObject("WScript.Shell").CurrentDirectory
allapps.SaveChanges
WScript.Echo "Created application " & ComAppName

objCatalog.ImportComponent ComAppName, MyComName
WScript.Echo "Installed component " & MyComName
0 голосов
/ 28 февраля 2010

Насколько я понимаю, вы хотите, чтобы конфигурация была глобальной для машины, на которой установлена ​​dll. Существует файл machine.config для глобальных параметров конфигурации машины. Я никогда не использовал его сам, поэтому у меня нет более подробной информации, но, возможно, стоит посмотреть. http://msdn.microsoft.com/en-us/library/ms229697(VS.71).aspx. Поиск в Google по запросу "machine.config" дает больше просмотров, которые выглядят информативными.

Другой способ - поместить пользовательский XML-файл в установочный каталог DLL-файла. Чтобы получить путь к файлу, используйте System.Reflection.Assembly.GetExecutingAssembly.Location (или, возможно, CodeBase вместо Location). К сожалению, вам придется создать собственное управление конфигурацией поверх файла xml, но благодаря Linq to XML я думаю, что XML более безболезнен, чем когда-либо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...