Como encontrar o caminho do arquivo app.config ativo?

167

Estou tentando terminar este manipulador de exceção:

if (ConfigurationManager.ConnectionStrings["ConnectionString"]==null)
{
    string pathOfActiveConfigFile = ...?
    throw new ConfigurationErrorsException(
       "You either forgot to set the connection string, or " +
       "you're using a unit test framework that looks for  "+
       "the config file in strange places, update this file : " 
       + pathOfActiveConfigFile);
}

Esse problema parece acontecer apenas quando estou usando o nUnit.

MatthewMartin
fonte

Respostas:

363

Tente isto

AppDomain.CurrentDomain.SetupInformation.ConfigurationFile

Espero que ajude

Cédric Rup
fonte
Isso é muito melhor do que tentar usar Assembly.GetEntryAssembly () + ".config", que não funciona em algumas situações no ASP.NET e em algumas situações ao usar AppDomains.
Contango 8/10
4
como posso mudar esse caminho?
Vignesh Subramanian
Obrigado. Eu tive um projeto atualizado do VS2008 -> VS2013 que se recusou a ler o arquivo app.config. Aprendi, por meio do AppDomain.CurrentDomain.SetupInformation.ConfigurationFile, que estava procurando por XXX.vshost.exe.config, que não estava sendo gerado. Então, eu desliguei o VS Hosting na guia de depuração das propriedades do projeto. Então eu tive que mudar o nome de meu arquivo app.config para {projectName} .config, colocá-lo na pasta bin e finalmente funcionou
drzounds
1
Não funcionou para mim. Esta resposta fez no entanto.
precisa saber é o seguinte
4
E o núcleo .net?
jjxtra
64

A rigor, não existe um único arquivo de configuração. Excluindo o ASP.NET 1 , pode haver três arquivos de configuração usando o System.Configurationsuporte inbuilt ( ). Além da configuração da máquina:, app.exe.configroaming do usuário e local do usuário.

Para obter a configuração "global" ( exe .config):

ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None)
                    .FilePath

Use ConfigurationUserLevelvalores diferentes para arquivos de configuração de roaming e não-roaming por uso.


1 Que possui um modelo completamente diferente, no qual o conteúdo de pastas filho (IIS-virtual ou sistema de arquivos) web.configpode (dependendo da configuração) adicionar ou substituir o pai web.config.

Richard
fonte
2
Eu levantei primeiro a "Resposta", que foi muito útil. Mas, no final, eu realmente precisava dessa abordagem, então obrigado por colocá-la aqui também.
Noam Gal
Não se esqueça de adicionar uma referência ao System.configuration
Black Horus
9

Se você deseja obter apenas um retorno nulo ao usar o NUnit, provavelmente precisará copiar o valor ConnectionString do seu app.config do seu aplicativo para o app.config da sua biblioteca de teste.

Quando executado pelo carregador de teste, o assembly de teste é carregado em tempo de execução e procurará em seu próprio app.config (renomeado para testAssembly.dll.config em tempo de compilação) e não no arquivo de configuração dos aplicativos.

Para obter o local da montagem que você está executando, tente

System.Reflection.Assembly.GetExecutingAssembly().Location
Colin Desmond
fonte
1
Sugira "AppDomain.CurrentDomain.SetupInformation.ConfigurationFile" do @Cedric Rup, caso contrário, você receberá uma exceção em algumas situações no ASP.NET e em algumas situações ao usar AppDomains.
Contango8
6

Certifique-se de clicar nas propriedades do arquivo e configurá-lo para "copiar sempre" ou ele não estará na pasta Debug \ com suas DLLs felizes para configurar onde precisa estar e adicionar mais cowbell

Chad Grant
fonte
6

A primeira vez que percebi que o projeto de teste de unidade referenciava o app.config nesse projeto, e não o app.config associado ao meu projeto de código de produção (claro, DOH), acabei de adicionar uma linha no evento Post Build do projeto Prod que copiará o app.config para a pasta bin do projeto de teste.

Problema resolvido

Não notei nenhum efeito colateral estranho até agora, mas não tenho certeza de que seja a solução certa, mas pelo menos parece funcionar.

Kasper
fonte
4

Mais uma opção que vi está faltando aqui:

const string APP_CONFIG_FILE = "APP_CONFIG_FILE";
string defaultSysConfigFilePath = (string)AppDomain.CurrentDomain.GetData(APP_CONFIG_FILE);
selalerer
fonte
O bom disso, por mais hacky que pareça, é que ele é compilado no .NET Standard 2.0. Ele retorna nulo no .NET Core 2.0, mas é útil durante a migração.
EM0 18/0118
3

Dependendo da localização do seu arquivo de configuração, System.Reflection.Assembly.GetExecutingAssembly().Locationvocê pode fazer o que precisa.

William Edmondson
fonte
2
Além disso, você pode ter vários arquivos de configuração "ativos" ao mesmo tempo. Machine.config, web.config no nível da estrutura, configuração no nível do aplicativo, etc ... então não acho que haja uma maneira de localizar automaticamente um local exclusivo do arquivo da cadeia de conexão sem analisar todos os possíveis arquivos de configuração disponíveis para o seu aplicativo.
William Edmondson
3

Tentei uma das respostas anteriores em um aplicativo Web (na verdade, uma função da Web do Azure em execução localmente) e não funcionou muito bem. No entanto, essa abordagem semelhante funcionou:

var map = new ExeConfigurationFileMap { ExeConfigFilename = "MyComponent.dll.config" };
var path = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None).FilePath;

O arquivo de configuração estava em C: \ Arquivos de Programas \ IIS Express \ MyComponent.dll.config. Lugar interessante para isso.

RedGreenCode
fonte