Pergunta

Existe uma maneira de obter o caminho para a assembléia em que o código atual reside?Eu não quero o caminho do assembly chamada, apenas o que contém o código.

Basicamente o meu teste de unidade precisa ler alguns arquivos de teste xml que estão localizados em relação a dll.Eu quero que o caminho para resolver sempre corretamente, independentemente de se o teste de dll é executado a partir de TestDriven.NET o o mbunit GUI ou de qualquer outra coisa.

Editar:As pessoas parecem não ser mal-entendido o que eu estou pedindo.

Minha biblioteca de teste está localizado em dizer

C:\projects\myapplication\daotests\bin\Debug\daotests.dll

e eu gostaria de começar este caminho:

C:\projects\myapplication\daotests\bin\Debug\

As três sugestões até agora não me quando eu executar a partir do o mbunit Gui:

  • Environment.CurrentDirectoryc:\Program Files\o mbunit

  • System.Reflection.Assembly.GetAssembly(typeof(DaoTests)).LocationC:\Documents e Settings\george\Local Settings emp\ ....\DaoTests.dll

  • System.Reflection.Assembly.GetExecutingAssembly().Location dá o mesmo que o anterior.

Foi útil?

Solução

Eu já definida a seguinte propriedade, como nós usamos a este, muitas vezes, em testes de unidade.

public static string AssemblyDirectory
{
    get
    {
        string codeBase = Assembly.GetExecutingAssembly().CodeBase;
        UriBuilder uri = new UriBuilder(codeBase);
        string path = Uri.UnescapeDataString(uri.Path);
        return Path.GetDirectoryName(path);
    }
}

O Assembly.Location propriedade, por vezes, dá-lhe alguns engraçado resultados ao usar o NUnit (onde assembléias executado a partir de uma pasta temporária), por isso eu prefiro usar CodeBase o que dá a você o caminho em formato de URI, em seguida, UriBuild.UnescapeDataString remove o File:// no início, e GetDirectoryName alterações normais para o formato do windows.

Outras dicas

Isso ajuda?

//get the full location of the assembly with DaoTests in it
string fullPath = System.Reflection.Assembly.GetAssembly(typeof(DaoTests)).Location;

//get the folder that's in
string theDirectory = Path.GetDirectoryName( fullPath );

É tão simples como isto:

var dir = AppDomain.CurrentDomain.BaseDirectory;

Mesmo que João de resposta, mas um pouco menos detalhado do método de extensão.

public static string GetDirectoryPath(this Assembly assembly)
{
    string filePath = new Uri(assembly.CodeBase).LocalPath;
    return Path.GetDirectoryName(filePath);            
}

Agora você pode fazer:

var localDir = Assembly.GetExecutingAssembly().GetDirectoryPath();

ou se você preferir:

var localDir = typeof(DaoTests).Assembly.GetDirectoryPath();

A única solução que funcionou para mim quando usando CodeBase UNC e compartilhamentos de Rede foi:

System.IO.Path.GetDirectoryName(new System.Uri(System.Reflection.Assembly.GetExecutingAssembly().CodeBase).LocalPath);

Ele também funciona com o normal URIs também.

Isso deve funcionar, a menos que a montagem é de uma cópia de sombra:

string path = System.Reflection.Assembly.GetExecutingAssembly().Location

O que sobre isso:

System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);

Eu suspeito que o problema real aqui é que seu test runner é copiar o assembly para um local diferente.Não há nenhuma maneira em tempo de execução para dizer de onde a montagem foi copiado, mas provavelmente você pode virar um parâmetro para dizer o executor de teste para executar o assembly de onde ele é, e não para copiá-lo para uma pasta de sombra.

Tal opção é susceptível de ser diferente para cada teste corredor, claro.

Você já considerou a incorporação de dados XML como recursos dentro de seu conjunto para teste?

AppDomain.CurrentDomain.BaseDirectory

funciona com o mbunit GUI.

var assembly = System.Reflection.Assembly.GetExecutingAssembly();
var assemblyPath = assembly.GetFiles()[0].Name;
var assemblyDir = System.IO.Path.GetDirectoryName(assemblyPath);

Aqui é um VB.NET porta de João Sibly do código.O Visual Basic não é sensível a maiúsculas e minúsculas, de modo que alguns de seus nomes de variáveis chocavam com nomes de tipo.

Public Shared ReadOnly Property AssemblyDirectory() As String
    Get
        Dim codeBase As String = Assembly.GetExecutingAssembly().CodeBase
        Dim uriBuilder As New UriBuilder(codeBase)
        Dim assemblyPath As String = Uri.UnescapeDataString(uriBuilder.Path)
        Return Path.GetDirectoryName(assemblyPath)
    End Get
End Property

Como sobre isso ...

string ThisdllDirectory = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);

Em seguida, basta corte fora o que você não precisa

O diretório atual de onde você existir.

Environment.CurrentDirectory;  // This is the current directory of your application

Se você copiar o .arquivo xml com build você deve encontrá-lo.

ou

System.Reflection.Assembly assembly = System.Reflection.Assembly.GetAssembly(typeof(SomeObject));

// The location of the Assembly
assembly.Location;

Estou usando o Assembly.CodeBase em vez de Localização:

Assembly a;
a = Assembly.GetAssembly(typeof(DaoTests));
string s = a.CodeBase.ToUpper(); // file:///c:/path/name.dll
Assert.AreEqual(true, s.StartsWith("FILE://"), "CodeBase is " + s);
s = s.Substring(7, s.LastIndexOf('/') - 7); // 7 = "file://"
while (s.StartsWith("/")) {
    s = s.Substring(1, s.Length - 1);
}
s = s.Replace("/", "\\");

Ele está trabalhando, mas eu tenho mais certeza de que é 100% correto.A página em http://blogs.msdn.com/suzcook/archive/2003/06/26/assembly-codebase-vs-assembly-location.aspx diz:

"CodeBase é uma URL para o local onde foi encontrado o arquivo, enquanto o Local é o caminho para onde ele foi, na verdade, carregado.Por exemplo, se a assembleia foi baixado da internet, o seu CodeBase pode começar com "http://", mas a sua Localização pode começar com "C:\".Se o arquivo foi copiado sombra, o Local seria o caminho para a cópia do arquivo na pasta de cópia de sombra de dir.Também é bom saber que a base de código não é garantido para ser definido para assemblies no GAC.Localização será sempre definida para assemblies carregados a partir do disco, no entanto."

Você pode deseja usar CodeBase em vez de Local.

Tanto quanto eu posso dizer, a maioria das respostas tem alguns problemas.

A maneira correta de fazer isso para um baseado em disco (em oposição à web-based), não GACed assembleia é usar a execução no momento da assembleia CodeBase propriedade.

Isso retorna uma URL (file://).Em vez de andar com manipulação de seqüência de caracteres ou UnescapeDataString, este pode ser convertido com o mínimo de barulho, aproveitando a LocalPath propriedade de Uri.

var codeBaseUrl = Assembly.GetExecutingAssembly().CodeBase;
var filePathToCodeBase = new Uri(codeBaseUrl).LocalPath;
var directoryPath = Path.GetDirectoryName(filePathToCodeBase);

Em todos esses anos, ninguém tem realmente mencionado este.Um truque que aprendi com o incrível ApprovalTests projeto.O truque é que você use as informações de depuração na assembléia para encontrar o diretório original.

Isso não irá funcionar no modo de VERSÃO, nem com as otimizações habilitado, nem em uma máquina diferente da que ele foi compilado.

Mas isso vai tirar você de caminhos em relação à localização do arquivo de código-fonte que você chamá-lo de

public static class PathUtilities
{
    public static string GetAdjacentFile(string relativePath)
    {
        return GetDirectoryForCaller(1) + relativePath;
    }
    public static string GetDirectoryForCaller()
    {
        return GetDirectoryForCaller(1);
    }


    public static string GetDirectoryForCaller(int callerStackDepth)
    {
        var stackFrame = new StackTrace(true).GetFrame(callerStackDepth + 1);
        return GetDirectoryForStackFrame(stackFrame);
    }

    public static string GetDirectoryForStackFrame(StackFrame stackFrame)
    {
        return new FileInfo(stackFrame.GetFileName()).Directory.FullName + Path.DirectorySeparatorChar;
    }
}

Você pode obter o bin caminho Domínio de aplicação.CurrentDomain.RelativeSearchPath

Todas as propostas de respostas funciona quando o desenvolvedor pode alterar o código para incluir o necessário trecho, mas se você quiser fazer isso sem alterar qualquer código que você pode usar o Process Explorer.

Ele irá listar todas execução de dll no sistema, você pode precisar para determinar o processo de identificação de seu aplicativo em execução, mas que normalmente não é muito difícil.

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

em um formulário do windows app, você pode simplesmente usar Application.StartupPath

mas para DLLs e aplicações de console, o código é muito mais difícil lembrar...

string slash = Path.DirectorySeparatorChar.ToString();
string root = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);

root += slash;
string settingsIni = root + "settings.ini"
string path = Path.GetDirectoryName(typeof(DaoTests).Module.FullyQualifiedName);

Você terá de diretório incorreto se um caminho que contém o símbolo"#".Então, eu uso uma modificação do João Sibly resposta que é a combinação UriBuilder.Caminho e UriBuilder.Fragmento de:

public static string AssemblyDirectory
{
    get
    {
        string codeBase = Assembly.GetExecutingAssembly().CodeBase;
        UriBuilder uri = new UriBuilder(codeBase);
        //modification of the John Sibly answer    
        string path = Uri.UnescapeDataString(uri.Path.Replace("/", "\\") + 
          uri.Fragment.Replace("/", "\\"));
        return Path.GetDirectoryName(path);
     }
}

É isso que eu vim acima com. Entre projetos da web, testes de unidade (nunit e resharper test runner);Eu achei isso funcionou para mim.

Eu estava procurando o código para detectar qual é a configuração de compilação é, Debug/Release/CustomName.Ai, o #if DEBUG. Então, se alguém pode melhorar o que!

Sinta-se livre para editar e melhorar.

Chegando pasta app.Útil para web raízes, unittests para obter a pasta de ficheiros de teste.

public static string AppPath
{
    get
    {
        DirectoryInfo appPath = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory);

        while (appPath.FullName.Contains(@"\bin\", StringComparison.CurrentCultureIgnoreCase)
                || appPath.FullName.EndsWith(@"\bin", StringComparison.CurrentCultureIgnoreCase))
        {
            appPath = appPath.Parent;
        }
        return appPath.FullName;
    }
}

Chegando bin:Útil para executar montagens, usando reflexão.Se os arquivos são copiados existe devido a construir propriedades.

public static string BinPath
{
    get
    {
        string binPath = AppDomain.CurrentDomain.BaseDirectory;

        if (!binPath.Contains(@"\bin\", StringComparison.CurrentCultureIgnoreCase)
            && !binPath.EndsWith(@"\bin", StringComparison.CurrentCultureIgnoreCase))
        {
            binPath = Path.Combine(binPath, "bin");
            //-- Please improve this if there is a better way
            //-- Also note that apps like webapps do not have a debug or release folder. So we would just return bin.
#if DEBUG
            if (Directory.Exists(Path.Combine(binPath, "Debug"))) 
                        binPath = Path.Combine(binPath, "Debug");
#else
            if (Directory.Exists(Path.Combine(binPath, "Release"))) 
                        binPath = Path.Combine(binPath, "Release");
#endif
        }
            return binPath;
    }
}

Isso deve funcionar:

ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
Assembly asm = Assembly.GetCallingAssembly();
String path = Path.GetDirectoryName(new Uri(asm.EscapedCodeBase).LocalPath);

string strLog4NetConfigPath = System.IO.Path.Combine(path, "log4net.config");

Eu estou usando isso para implantar o arquivo DLL bibliotecas, juntamente com algum arquivo de configuração (esta é usar o log4net de dentro do arquivo DLL).

Eu encontrar a minha solução adequada para a recuperação do local.

var executingAssembly = new FileInfo((Assembly.GetExecutingAssembly().Location)).Directory.FullName;

Eu tenho o mesmo comportamento no NUnit no passado.Por padrão NUnit cópias de seu assembly no diretório temp.Você pode alterar esse comportamento no NUnit configurações:

enter image description here

Talvez TestDriven.NET e MbUnit GUI tem as mesmas configurações.

Eu uso isso para obter o caminho para o Diretório Bin:

var i = Environment.CurrentDirectory.LastIndexOf(@"\");
var path = Environment.CurrentDirectory.Substring(0,i); 

Você obter esse resultado:

"c:\users icooley\documents\visual studio 2010\Projetos\Windows_Test_Project\Windows_Test_Project\bin"

Aplicação Web?

Server.MapPath("~/MyDir/MyFile.ext")
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top