Como obter a localização da DLL em execução no momento?

91

Tenho um arquivo de configuração que preciso carregar como parte da execução de uma dll que estou escrevendo.

O problema que estou tendo é que o local onde coloco a dll e o arquivo de configuração não é o "local atual" quando o aplicativo está em execução.

Por exemplo, coloco o arquivo dll e xml aqui:

D: \ Arquivos de programas \ Microsoft Team Foundation Server 2010 \ Application Tier \ Web Services \ bin \ Plugins

Mas se eu tentar fazer referência ao arquivo xml (em minha dll) assim:

XDocument doc = XDocument.Load(@".\AggregatorItems.xml")

então . \ AggregatorItems.xml se traduz em:

C: \ windows \ system32 \ inetsrv \ AggregatorItems.xml

Portanto, preciso encontrar uma maneira (espero) de saber onde está localizada a dll que está sendo executada no momento. Basicamente, estou procurando por isso:

XDocument doc = XDocument.Load(CoolDLLClass.CurrentDirectory+@"\AggregatorItems.xml")
Vaccano
fonte

Respostas:

135

Você está procurando por System.Reflection.Assembly.GetExecutingAssembly()

string assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string xmlFileName = Path.Combine(assemblyFolder,"AggregatorItems.xml");

Nota:

A .Locationpropriedade retorna a localização do arquivo DLL em execução no momento.

Em algumas condições, a DLL é copiada antes da execução e a .Locationpropriedade retornará o caminho da cópia. Se você quiser o caminho da DLL original, use a Assembly.GetExecutingAssembly().CodeBasepropriedade.

.CodeBasecontém um prefixo ( file:\), que pode ser necessário remover.

Vidro quebrado
fonte
8
Ai de mim! Que retornaC:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\Temporary ASP.NET Files\\tfs\\de3c0c8e\\c1bdf790\\assembly\\dl3\\20b156cb\\22331f24_bfb9cb01\\AggregatorItems.xml
Vaccano
22
Ah! Mas Assembly.GetExecutingAssembly().CodeBasetem!
Vaccano
2
CodeBase me deu o arquivo: \\ c: \ myassemblypath, que é estranho
Matt
9
@Matt use o novo Uri (Assembly.GetExecutingAssembly (). CodeBase) .LocalPath para obter um nome real
Larry
2
string curAssemblyFolder = new System.Uri(System.Reflection.Assembly.GetExecutingAssembly().CodeBase).LocalPath;
Martin Connell
36

A reflexão é sua amiga, como foi apontado. Mas você precisa usar o método correto;

Assembly.GetEntryAssembly()     //gives you the entrypoint assembly for the process.
Assembly.GetCallingAssembly()   // gives you the assembly from which the current method was called.
Assembly.GetExecutingAssembly() // gives you the assembly in which the currently executing code is defined
Assembly.GetAssembly( Type t )  // gives you the assembly in which the specified type is defined.
Nicholas Carey
fonte
16

No meu caso (lidando com meus assemblies carregados [como arquivo] no Outlook):

typeof(OneOfMyTypes).Assembly.CodeBase

Observe o uso de CodeBase(não Location) no Assembly. Outros apontaram métodos alternativos de localização da montagem.


fonte
5
System.Reflection.Assembly.GetExecutingAssembly().Location
Hawxby
fonte
1

Se você estiver trabalhando com um aplicativo asp.net e desejar localizar assemblies ao usar o depurador, eles geralmente são colocados em algum diretório temporário. Escrevi este método para ajudar nesse cenário.

private string[] GetAssembly(string[] assemblyNames)
{
    string [] locations = new string[assemblyNames.Length];


    for (int loop = 0; loop <= assemblyNames.Length - 1; loop++)       
    {
         locations[loop] = AppDomain.CurrentDomain.GetAssemblies().Where(a => !a.IsDynamic && a.ManifestModule.Name == assemblyNames[loop]).Select(a => a.Location).FirstOrDefault();
    }
    return locations;
}

Para obter mais detalhes, consulte esta postagem do blog http://nodogmablog.bryanhogan.net/2015/05/finding-the-location-of-a-running-assembly-in-net/

Se você não pode alterar o código-fonte ou reimplantar, mas pode examinar os processos em execução no computador, use o Process Explorer. Eu escrevi uma descrição detalhada aqui .

Ele listará todas as dlls em execução no sistema, você pode precisar determinar a identificação do processo do aplicativo em execução, mas isso geralmente não é muito difícil.

Eu escrevi uma descrição completa de como fazer isso para uma dll dentro do IIS - http://nodogmablog.bryanhogan.net/2016/09/locating-and-checking-an-executing-dll-on-a-running-web -servidor/

Bryan
fonte