2011-12-28 12 views
5
  • ho assembly .NET con alcune classi contrassegnate come ComVisible
  • Questo gruppo è stato registrato con il nome regasm /codebase "assembly_path"
  • ho App.config (in realtà - MyAssemblyName.dll.config), che sono in la cartella di montaggio
  • accedo al appSettings nel mio assemblaggio attraverso ConfigurationManager.AppSettings["SettingName"]
  • ho file VBScript che crea il mio oggetto COM tramite CreateObject("...")
  • Quando viene creato l'oggetto (da VBScript), ConfigurationManager.AppSettings["SettingName"] restituisce null. Sembra che l'assembly non veda il file di configurazione.

Cosa devo fare per renderlo funzionante?ComVisible .NET montaggio e app.config

risposta

4

Un modo possibile, come ha affermato Komyg, è leggere direttamente il file di configurazione, invece di utilizzare il comportamento incorporato di ConfigurationManager. Per coloro, che avranno lo stesso problema: invece di

ConfigurationManager.AppSettings["SettingName"] 

è possibile utilizzare:

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

In questo modo sarete sempre utilizzare leggere le impostazioni da file YourAssemblyName.dll.config che stabilisce nella cartella di vostra assemblea. Ti consentirà di utilizzare anche un'altra funzionalità per l'attributo app.config (come l'attributo), che non sarà disponibile se utilizzerai XPath o qualcosa del genere.

0

È tutto nella stessa cartella (la DLL, lo script VB, il file di configurazione, ecc.)? In caso contrario, potresti provare ad aggiungere il percorso completo al file di configurazione nella variabile PATH evironment ...

Anche se stai eseguendo questo VB Script in Internet Explorer potresti avere alcuni problemi di sicurezza (normalmente l'IE non lo fa) ti permettono di accedere al disco rigido). In questo caso puoi provare a mettere il file di configurazione sul desktop, non so perché, ma sembra essere il percorso predefinito quando esegue un programma ActiveX, quindi potrebbe anche essere vero per uno script VB.

Infine puoi aggiungere un po 'di debug alla tua DLL, qualcosa come creare un semplice file di testo e cercarlo in seguito, in questo modo puoi vedere dove il tuo sistema sta effettivamente eseguendo la tua libreria.

+0

Naturalmente, tutto non è nella stessa cartella. Dll e il file di configurazione sono in una cartella, vbscript - in un altro. E vbscript sta eseguendo 'wscript.exe'. Quindi la cartella predefinita per il 99% sarà 'c: \ windows \ system32' (lo controllerò ora) – chopikadze

+0

' Directory.GetCurrentDirectory() 'restituisce la cartella dello script – chopikadze

+0

Forse potresti aprire direttamente il tuo file di configurazione e ottenere la tua configurazione usando XPath, non è il modo ideale ma potrebbe funzionare ... – Felipe

3

Ho avuto lo stesso problema. Un'estensione shell explorer (Com visibile, registrata tramite regasm/codebase) che richiedeva un file app.config, non riusciva a trovare né le stringhe di connessione né le impostazioni.

Quello che ho fatto:

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

Ciò presuppone che il file di configurazione viene memorizzato nella stessa directory del montaggio.

0

Ho usato la risposta di sputnik, ha funzionato benissimo in un ambiente di test IIS, ma non in un altro. Si scopre che dopo aver impostato la proprietà APP_CONFIG_FILE, potrebbe essere necessario utilizzare la reflection per toccare la classe ConfigurationManager per rendere il change stick.Ho usato questa funzione dopo l'impostazione della proprietà 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); 
    } 

Al di là di questo, è probabilmente una buona idea per salvare in primo luogo fuori la proprietà e quindi ripristinarlo quando si è fatto:

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