2011-12-28 13 views
5
  • tengo NET con algunas clases marcados como ComVisible
  • Este conjunto está registrada con el nombre regasm /codebase "assembly_path"
  • He App.config (en realidad - MyAssemblyName.dll.config) que se encuentran en carpeta de montaje
  • puedo acceder a mi appsettings en conjunto a través ConfigurationManager.AppSettings["SettingName"]
  • tengo archivo VBScript que crea mi objeto COM a través CreateObject("...")
  • Cuando se crea el objeto (desde VBScript), ConfigurationManager.AppSettings["SettingName"] devuelve nulo. Parece que el ensamblado no ve el archivo de configuración.

¿Qué debo hacer para que sea viable?montaje ComVisible .NET y app.config

Respuesta

4

Una forma posible, como dijo Komyg, es leer el archivo de configuración directamente, en lugar de usar el comportamiento integrado de ConfigurationManager. Para aquellos, que tendrá el mismo problema: en lugar de

ConfigurationManager.AppSettings["SettingName"] 

puede utilizar:

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; 
} 

De esta manera siempre usará leer la configuración de archivo YourAssemblyName.dll.config que se establecen en la carpeta de su montaje. Le permitirá usar también otras características para app.config (como appSetting's file atributo), que no estarán disponibles si va a utilizar XPath o algo así.

0

¿Está todo en la misma carpeta (su dll, secuencia de comandos vb, archivo de configuración, etc.)? De lo contrario, podría intentar agregar la ruta completa al archivo de configuración en la variable de entorno PATH ...

Además, si ejecuta este script VB dentro de Internet Explorer puede tener algunos problemas de seguridad (normalmente el IE no lo hace) t le permite acceder al disco duro). En este caso, puede tratar de poner el archivo de configuración en su escritorio, no sé por qué, pero esa parece ser la ruta predeterminada cuando ejecuta un programa ActiveX, por lo que también podría ser cierto para una secuencia de comandos VB.

Finalmente, podría agregar algo de depuración a su dll, algo así como crear un archivo de texto simple y buscarlo después, de esta manera usted puede ver dónde está realmente su sistema ejecutando su biblioteca.

+0

Por supuesto, todo lo no está en la misma carpeta. Dll y el archivo de configuración están en una carpeta, vbscript, en otra. Y vbscript se ejecuta a través de 'wscript.exe'. Así que la carpeta predeterminada para el 99% será 'c: \ windows \ system32' (lo verificaré ahora) – chopikadze

+0

' Directory.GetCurrentDirectory() 'devuelve la carpeta del script – chopikadze

+0

Tal vez podrías abrir tu archivo de configuración directamente y obtener tu configuración usando XPath, no es la manera ideal, pero puede funcionar ... – Felipe

3

Tuve el mismo problema. Una extensión de shell de explorador (Com visible, registrada a través de regasm/codebase) que requería un archivo app.config, no podía encontrar ni las cadenas de conexión ni la configuración.

Lo que hice:

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

que asume, que el archivo de configuración se almacena en el mismo directorio que el montaje.

0

Utilicé la respuesta de sputnik, funcionó muy bien en un entorno de prueba IIS, pero no en otro. Resulta que después de establecer la propiedad APP_CONFIG_FILE, es posible que deba usar el reflejo para tocar la clase ConfigurationManager y hacer que el cambio se adhiera.He utilizado esta función después de establecer la propiedad 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); 
    } 

Más allá de esto, es probablemente una buena idea para ahorrar primera fuera de la propiedad y luego restaurarla cuando haya terminado:

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(); 
Cuestiones relacionadas