865 votes

Comment puis-je obtenir le chemin de l'assemblage dans lequel se trouve le code ?

Existe-t-il un moyen d'obtenir le chemin de l'assemblage dans lequel réside le code actuel ? Je ne veux pas le chemin de l'assemblage appelant, seulement celui qui contient le code.

En fait, mon test unitaire doit lire des fichiers de test xml qui sont situés relativement à la dll. Je veux que le chemin soit toujours résolu correctement, que la dll de test soit exécutée à partir de TestDriven.NET, de l'interface graphique MbUnit ou d'un autre outil.

Modifier : Les gens semblent mal comprendre ce que je demande.

Ma bibliothèque de test est située dans say

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

et je voudrais obtenir ce chemin :

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

Les trois suggestions faites jusqu'à présent me font échouer lorsque j'exécute le programme à partir de la Gui MbUnit :

  • Environment.CurrentDirectory donne c : \Program Fichiers \MbUnit

  • System.Reflection.Assembly.GetAssembly(typeof(DaoTests)).Location donne C:\Documents et Paramètres \george\Local Paramètres \Temp\ .... \DaoTests.dll

  • System.Reflection.Assembly.GetExecutingAssembly().Location donne la même chose que le précédent.

118 votes

Voici votre solution : var dir = AppDomain.CurrentDomain.BaseDirectory ;

7 votes

Cela devrait être la solution acceptée. AppDomain.CurrentDomain.BaseDirectory est l'approche correcte.

0 votes

1126voto

John Sibly Points 9805

J'ai défini la propriété suivante car nous l'utilisons souvent dans les tests unitaires.

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

Le site Assembly.Location donne parfois de drôles de résultats lorsqu'on utilise NUnit (où les assemblages sont exécutés à partir d'un dossier temporaire), je préfère donc utiliser la propriété CodeBase qui vous donne le chemin au format URI, puis UriBuild.UnescapeDataString supprime le File:// au début, et GetDirectoryName le transforme en format normal de Windows.

33 votes

Il y a un problème que j'ai rencontré, si le nom de votre répertoire est : c : \My %20Directory alors Uri.UnescapeDataString retournera : c : \My Directory Cela signifie que File.Exists("c : \My Annuaire \MyFile.txt ") retournera faux car le chemin correct est en fait "c : \My %20Directory \MyFile.txt " Je suis tombé sur ce problème car nos chemins SVN contiennent des espaces et lorsque nous les vérifions, ils encodent les espaces.

2 votes

Bon sang, ça ne marche toujours pas pour moi :0( Maintenant, au lieu de me donner le chemin de MSBuild, je reçois le chemin de TeamCity. C:\TeamCity\buildAgent\temp\buildTmp\SYSTEM_SVR1 2010-08-24 17_34_23 \Out mais encore une autre façon d'obtenir un chemin :-)

1 votes

John Sibly : renvoie le chemin de l'assemblage en cours d'exécution - pas l'assemblage (comme dans une .dll) qui est chargé par l'exécutable appelant. J'ai besoin du .dll pour pouvoir définir un répertoire de travail. +Merci pour cette réponse utile et ce bon point de départ.

342voto

Keith Points 46288

Cela vous aide-t-il ?

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

0 votes

Voir mon édition, il ne le fait pas, est-ce quelque chose d'étrange dans la façon dont MbUnit fait les choses ?

0 votes

Comment cela se fait-il ? Le chemin complet serait " C:\projects\myapplication\daotests\bin\Debug\daotests.dll "le Répertoire serait " C:\projects\myapplication\daotests\bin\Debug " N'est-ce pas ce que vous voulez ?

0 votes

Ahh, non je vous comprends. MSTest fait la même chose - tout est copié dans un nouveau répertoire temporaire à chaque fois.

336voto

Jalal El-Shaer Points 6027

C'est aussi simple que ça :

var dir = AppDomain.CurrentDomain.BaseDirectory;

11 votes

Ceci devrait être la solution acceptée. AppDomain.CurrentDomain.BaseDirectory est l'approche correcte.

6 votes

Merci d'avoir attiré mon attention sur ce point. Je ne suis pas sûr qu'il était disponible au moment où j'ai posé la question, mais il l'est maintenant.

131 votes

Non, c'est faux. Cela renvoie le chemin du POINT D'ENTRÉE ORIGINAL et non le code en cours d'exécution. Si vous avez chargé manuellement un assemblage à partir d'un chemin différent, ou s'il a été chargé à partir du GAC, le résultat sera erroné. Cette réponse est correcte : stackoverflow.com/a/283917/243557 Plus rapide encore est Path.GetDirectoryName(Assembly.GetExecutingAssembly().Locati‌​on) .

70voto

Sneal Points 1088

Même réponse que celle de John, mais une méthode d'extension légèrement moins verbeuse.

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

Maintenant vous pouvez le faire :

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

ou si vous préférez :

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

6 votes

Vous vouliez dire assembly au lieu de Assembly.GetExecutingAssembly() ?

3 votes

Comme le souligne Dude, vous avez transmis un argument et n'avez pas réussi à l'utiliser.

4 votes

Cette réponse est tout simplement fausse par rapport à la question posée. Une version modifiée de cette réponse pourrait vous donner le chemin d'un assemblage donné. Cependant, ici, nous recherchons spécifiquement l'assemblage en cours d'exécution, et donc passer dans un assemblage n'a aucun sens. Une méthode d'extension est le mauvais outil pour ce travail.

49voto

SoMoS Points 7082

La seule solution qui a fonctionné pour moi lorsque j'ai utilisé CodeBase et des partages réseau UNC était la suivante :

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

Il fonctionne également avec les URI normaux.

5 votes

Cela devrait être la réponse acceptée. C'est vraiment ennuyeux que la base de code par défaut ne gère pas correctement les partages UNC.

0 votes

Cela s'effondre lorsque le dossier contient des espaces et Dieu sait quels autres caractères...

1 votes

Je l'ai beaucoup utilisé et j'ai trouvé un scénario où il échoue : si cette ligne de code fait elle-même partie d'un paquet NuGet qui est ensuite utilisé par une application ! Nous pouvons également prendre en charge ce scénario en remplaçant GetExecutingAssembly() par GetCallingAssembly() .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X