c# - studio - no se encontro el archivo de metadatos dll
Archivo de configuración DLL C# (16)
Al usar ConfigurationManager, estoy bastante seguro de que está cargando el archivo de configuración del proceso / AppDomain
(app.config / web.config). Si desea cargar un archivo de configuración específico, tendrá que pedir específicamente ese archivo por nombre ...
Tu podrías intentar:
var config = ConfigurationManager.OpenExeConfiguration("foo.dll");
config.ConnectionStrings. [etc]
Estoy tratando de agregar un archivo app.config a mi DLL, pero todos los intentos han fallado.
Según MusicGenesis en '' Poner información de configuración en una DLL '' esto no debería ser un problema. Entonces obviamente estoy haciendo algo mal ...
El siguiente código debería devolver mi ConnectionString desde mi DLL:
return ConfigurationManager.AppSettings["ConnectionString"];
Sin embargo, cuando copio el archivo app.config en mi aplicación de consola, funciona bien.
¿Algunas ideas?
Como dice Marc, esto no es posible (aunque Visual Studio le permite agregar un archivo de configuración de la aplicación en un proyecto de biblioteca de clase).
Es posible que desee comprobar la clase AssemblySettings que parece hacer posibles los archivos de configuración de ensamblaje.
Como el ensamblado reside en un caché temporal, debe combinar la ruta para obtener la configuración del dll:
var appConfig = ConfigurationManager.OpenExeConfiguration(
Path.Combine(Environment.CurrentDirectory, Assembly.GetExecutingAssembly().ManifestModule.Name));
ConfigurationManager.AppSettings devuelve la configuración definida para la aplicación, no para la DLL específica, puede acceder a ellos, pero es la configuración de la aplicación que se devolverá.
Si está utilizando dll desde otra aplicación, ConnectionString estará en la aplicación de la aplicación.
En esta publicación, se discutió un problema similar y resolvió mi problema. ¿Cómo cargar un archivo separado de Configuración de la aplicación de forma dinámica y fusionarlo con la configuración actual? podría ser helpfu
He encontrado lo que parece ser una buena solución para este problema. Estoy usando VS 2008 C #. Mi solución implica el uso de espacios de nombres distintos entre múltiples archivos de configuración. Publiqué la solución en mi blog: http://tommiecarter.blogspot.com/2011/02/how-to-access-multiple-config-files-in.html .
Por ejemplo:
Este espacio de nombres lee / escribe la configuración de dll:
var x = company.dlllibrary.Properties.Settings.Default.SettingName;
company.dlllibrary.Properties.Settings.Default.SettingName = value;
Este espacio de nombres lee / escribe la configuración del exe:
company.exeservice.Properties.Settings.Default.SettingName = value;
var x = company.exeservice.Properties.Settings.Default.SettingName;
Hay algunas advertencias mencionadas en el artículo. HTH
La solución completa no se encuentra a menudo en un solo lugar ...
1) Cree un archivo de configuración de aplicación y asígnele el nombre "yourDllName.dll.config"
2) Haga clic con el botón derecho en el archivo de configuración creado anteriormente en VS Solution Explorer, haga clic en Propiedades
--- establecer "Build Action" = Contenido
--- establecer "Directorio de Copiar a Salida" = Siempre
3) Agregue una sección appSettings al archivo de configuración (yourDllName.dll.config) con su yourKeyName y yourKeyValue
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="yourKeyName" value="yourKeyValue"/>
</appSettings>
</configuration>
4) Agregue System.Configuration a sus referencias de dll / class / project
5) Agregue las instrucciones de uso a su código donde tiene la intención de acceder a la configuración de configuración
using System.Configuration;
using System.Reflection;
6) Para acceder al valor
string keyValue = ConfigurationManager.OpenExeConfiguration(Assembly.GetExecutingAssembly().Location).AppSettings.Settings["yourKeyName"].Value;
7) regocíjate, funciona
En mi humilde opinión, esto solo debería usarse cuando se desarrolla una nueva biblioteca dll /.
#if (DEBUG && !FINALTESTING)
string keyValue = ConfigurationManager.OpenExeConfiguration...(see 6 above)
#else
string keyValue = ConfigurationManager.AppSettings["yourKeyName"];
#endif
El archivo de configuración termina siendo una gran referencia para cuando agrega las aplicaciones de dll a su aplicación real.
No es trivial crear un archivo de configuración .NET para .DLL, y por una buena razón. El mecanismo de configuración de .NET tiene muchas funciones incorporadas para facilitar la actualización / actualización de la aplicación y para proteger las aplicaciones instaladas contra el pisoteo de los archivos de configuración de los demás.
Hay una gran diferencia entre cómo se usa un archivo DLL y cómo se usa una aplicación. Es poco probable que tenga múltiples copias de una aplicación instalada en la misma máquina para el mismo usuario. Pero es muy posible que tenga 100 aplicaciones o bibliotecas diferentes, todas haciendo uso de algunas .NET DLL.
Mientras que rara vez es necesario realizar un seguimiento de la configuración por separado para diferentes copias de una aplicación dentro de un perfil de usuario, es muy poco probable que desee que todos los diferentes usos de una DLL compartan la configuración entre ellos. Por esta razón, cuando recupera un objeto de Configuración usando el método "normal", el objeto que obtiene está vinculado a la configuración del Dominio de Aplicación en el que se está ejecutando, en lugar del ensamblaje en particular.
App Domain está vinculado al ensamblaje raíz que cargó el ensamblado en el que está realmente el código. En la mayoría de los casos, este será el ensamblaje de su .EXE principal, que es lo que cargó el .DLL. Es posible girar otros dominios de aplicación dentro de una aplicación, pero debe proporcionar información explícita sobre el ensamblaje raíz de ese dominio de aplicación.
Debido a todo esto, el procedimiento para crear un archivo de configuración específico de la biblioteca no es tan conveniente. Es el mismo proceso que utilizaría para crear un archivo de configuración portátil arbitrario no vinculado a ningún ensamblado en particular, pero para el cual desea hacer uso del esquema XML de .NET, la sección de configuración y los mecanismos del elemento de configuración, etc. Esto implica crear un ExeConfigurationFileMap
objeto, cargar los datos para identificar dónde se almacenará el archivo de configuración y luego llamar a ConfigurationManager
. OpenMappedExeConfiguration
para abrirlo en una nueva instancia de Configuration
. Esto lo desconectará de la protección de versión que ofrece el mecanismo de generación de ruta automática.
Estadísticamente hablando, probablemente esté utilizando esta biblioteca en una configuración interna, y es poco probable que tenga varias aplicaciones que lo utilicen dentro de una máquina / usuario. Pero si no, hay algo que debes tener en cuenta. Si usa un único archivo de configuración global para su DLL, independientemente de la aplicación que lo haga referencia, debe preocuparse por los conflictos de acceso. Si dos aplicaciones que hacen referencia a su biblioteca se ejecutan al mismo tiempo, cada una con su propio objeto de Configuration
abierto, cuando guarde los cambios, se producirá una excepción la próxima vez que intente recuperar o guardar datos en la otra aplicación.
La forma más segura y sencilla de evitar esto es exigir que el ensamblado que está cargando su DLL también brinde cierta información sobre sí mismo o que lo detecte examinando el Dominio de aplicación del ensamblado de referencia. Use esto para crear una especie de estructura de carpetas para mantener archivos de configuración de usuario separados para cada aplicación que haga referencia a su DLL.
Si está seguro de que desea tener una configuración global para su archivo DLL, sin importar a dónde se haga referencia, tendrá que determinar su ubicación en lugar de que .NET encuentre una adecuada automáticamente. También deberá ser agresivo para administrar el acceso al archivo. Deberá almacenar en caché todo lo que sea posible, manteniendo la instancia de Configuration
SOLAMENTE el tiempo que sea necesario para cargar o guardar, abrir inmediatamente antes y eliminar inmediatamente después. Y, por último, necesitará un mecanismo de bloqueo para proteger el archivo mientras está siendo editado por una de las aplicaciones que usan la biblioteca.
Para un dll, no debe depender de la configuración, ya que la configuración es propiedad de la aplicación y no de dll.
Esto se explica here
Parece que los archivos de configuración son realmente confusos para aclarar a medida que su comportamiento cambia del entorno de desarrollo a la implementación. Aparentemente una DLL puede tener su propio archivo de configuración, pero una vez que copie y pegue el dll (junto con su archivo de configuración) en otro lugar, todo dejó de funcionar. La única solución es fusionar manualmente los archivos app.config en un solo archivo, que solo será utilizado por el ejecutivo. Por ejemplo, myapp.exe tendrá un archivo myapp.exe.config que contiene todas las configuraciones para todas las dlls usadas por myapp.exe. Estoy usando VS 2008.
Kenny Liew
Sé que es tarde para la fiesta, sin embargo, pensé que compartiría la solución que uso para las DLL.
Soy más de la escuela de pensamiento KISS, así que cuando tengo una DLL .NET que quiere almacenar puntos de datos externos que controlan cómo funciona o hacia dónde va, etc. simplemente creo una clase "config" que solo tiene propiedades públicas que almacene todos los puntos de datos que necesita y que me gustaría tener controlado externamente al DLL para evitar recompilarlo para hacer los cambios. Luego uso .Net''s XML Serializing para guardar y cargar la representación del objeto de la clase en un archivo.
Hay muchas formas de manejar la lectura y el acceso a ella, desde Singleton, una clase de utilidad estática hasta métodos de extensión, etc. Esto depende de cómo esté estructurado su DLL y qué método se adaptará mejor a su DLL.
Si está utilizando bibliotecas que buscan una gran cantidad de conflictos detrás de las escenas, como WCF, puede considerar hacer esto:
AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", "MyWcfClientWrapper.dll.config");
O en PowerShell:
[AppDomain]::CurrentDomain.SetData("APP_CONFIG_FILE", "MyWcfClientWrapper.dll.config")
IMO esta técnica es un olor de código y solo es realmente adecuada para el uso en scripts ad hoc. Si desea hacer esto en el código de producción, quizás sea el momento de una revisión arquitectónica.
Lo siguiente NO es recomendado:
Como curiosidad técnica, aquí hay una variación del tema. Puede crear un constructor estático dentro de una de las clases alojadas en el archivo DLL y realizar esta llamada desde allí. No recomendaría hacer esto excepto como último recurso.
Tuve el mismo problema y busqué en la web durante varias horas, pero no pude encontrar ninguna solución, así que hice mi propia. Me preguntaba por qué el sistema de configuración .net es tan inflexible.
Antecedentes: quiero que mi DAL.dll tenga su propio archivo de configuración para la base de datos y la configuración DAL. También necesito app.config para Enterprise Library y sus propias configuraciones. Por lo tanto, necesito tanto la aplicación.config y dll.config.
Lo que no quería hacer es pasar todas las propiedades / configuraciones desde la aplicación a mi capa DAL.
doblar el "AppDomain.CurrentDomain.SetupInformation.ConfigurationFile" no es posible porque lo necesito para el comportamiento normal de app.config.
Mis requisitos / puntos de vista fueron:
- NO hay copia manual de nada de ClassLibrary1.dll.config a WindowsFormsApplication1.exe.config porque esto no es reproducible para otros desarrolladores.
- retiene el uso de tipeo fuerte "Propiedades.Configuración.Defecto.NombreDeDeValor" (comportamiento de Configuración) porque creo que esta es una característica importante y no quería perderla
- Descubrí la falta de ApplicationSettingsBase para inyectar su propia configuración / archivo de configuración personalizada (todos los campos necesarios son privados en estas clases)
- el uso de la redirección de archivos "configSource" no es posible porque tendríamos que copiar / reescribir ClassLibrary1.dll.config y proporcionar varios archivos XML para varias secciones (esto tampoco me gustó)
- No me gusta escribir mi propio Proveedor de Configuraciones para esta sencilla tarea como lo sugiere MSDN porque pensé que simplemente sería demasiado
- Solo necesito secciones applicationSettings y connectionStrings del archivo de configuración
Se me ocurrió modificar el archivo Settings.cs e implementé un método que abre ClassLibrary1.dll.config y lee la información de la sección en un campo privado. Después de eso, he reemplazado "this [string propertyName]" por lo que el generado Settings.Desginer.cs llama a mi nueva propiedad en lugar de a la clase base. Allí se lee la configuración de la lista.
Finalmente está el siguiente código:
internal sealed partial class Settings
{
private List<ConfigurationElement> list;
/// <summary>
/// Initializes a new instance of the <see cref="Settings"/> class.
/// </summary>
public Settings()
{
this.OpenAndStoreConfiguration();
}
/// <summary>
/// Opens the dll.config file and reads its sections into a private List of ConfigurationElement.
/// </summary>
private void OpenAndStoreConfiguration()
{
string codebase = System.Reflection.Assembly.GetExecutingAssembly().CodeBase;
Uri p = new Uri(codebase);
string localPath = p.LocalPath;
string executingFilename = System.IO.Path.GetFileNameWithoutExtension(localPath);
string sectionGroupName = "applicationSettings";
string sectionName = executingFilename + ".Properties.Settings";
string configName = localPath + ".config";
ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = configName;
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
// read section of properties
var sectionGroup = config.GetSectionGroup(sectionGroupName);
var settingsSection = (ClientSettingsSection)sectionGroup.Sections[sectionName];
list = settingsSection.Settings.OfType<ConfigurationElement>().ToList();
// read section of Connectionstrings
var sections = config.Sections.OfType<ConfigurationSection>();
var connSection = (from section in sections
where section.GetType() == typeof(ConnectionStringsSection)
select section).FirstOrDefault() as ConnectionStringsSection;
if (connSection != null)
{
list.AddRange(connSection.ConnectionStrings.Cast<ConfigurationElement>());
}
}
/// <summary>
/// Gets or sets the <see cref="System.Object"/> with the specified property name.
/// </summary>
/// <value></value>
public override object this[string propertyName]
{
get
{
var result = (from item in list
where Convert.ToString(item.ElementInformation.Properties["name"].Value) == propertyName
select item).FirstOrDefault();
if (result != null)
{
if (result.ElementInformation.Type == typeof(ConnectionStringSettings))
{
return result.ElementInformation.Properties["connectionString"].Value;
}
else if (result.ElementInformation.Type == typeof(SettingElement))
{
return result.ElementInformation.Properties["value"].Value;
}
}
return null;
}
// ignore
set
{
base[propertyName] = value;
}
}
Simplemente deberá copiar su ClassLibrary1.dll.config del directorio de salida ClassLibrary1 al directorio de salida de su aplicación. Quizás alguien lo encuentre útil.
puedes usar este código:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace GClass1
{
[Guid("D6F88E95-8A27-4ae6-B6DE-0542A0FC7039")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface _GesGasConnect
{
[DispId(1)]
int SetClass1Ver(string version);
}
[Guid("13FE32AD-4BF8-495f-AB4D-6C61BD463EA4")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("InterfacesSMS.Setting")]
public class Class1 : _Class1
{
public Class1() { }
public int SetClass1(string version)
{
return (DateTime.Today.Day);
}
}
}
si desea leer la configuración desde el archivo de configuración de la DLL pero no desde las aplicaciones raíz web.config o app.config, use el código siguiente para leer la configuración en la dll.
var appConfig = ConfigurationManager.OpenExeConfiguration(Assembly.GetExecutingAssembly().Location);
string dllConfigData = appConfig.AppSettings.Settings["dllConfigData"].Value;
tienes razón, puedes leer el archivo de configuración de un dll. Luché con esto por un día hasta que descubrí que el archivo de configuración de mi era el problema. Ver mi código a continuación. fue capaz de correr
ExeConfigurationFileMap map = new ExeConfigurationFileMap();
map.ExeConfigFilename = Assembly.GetExecutingAssembly().Location + ".config";
Configuration libConfig = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
AppSettingsSection section = (libConfig.GetSection("appSettings") as AppSettingsSection);
Console.WriteLine(section.Settings["dnd_shortcodes"].Value);
mi Plugin1.dll.config
veía como a continuación;
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="cmd_location" value="http://..."/>
<add key="dnd_shortcodes" value="142,145,146,157,165,167,168,171,173,176,178,404,40"/>
</appSettings>
</configuration>
Descubrí que mi archivo de configuración carecía de la etiqueta <appSettings>
, así que mira a tu alrededor, tu problema podría haber sido diferente pero no tan lejos del mío.