see - documentation c# visual studio




Comment obtenir le chemin de l'assemblage dans lequel se trouve le code? (18)

Est-il possible d'obtenir le chemin d'accès à l'assembly dans lequel réside le code actuel? Je ne veux pas le chemin de l'assembly appelant, juste celui contenant le code.

Fondamentalement, mon test d'unité doit lire certains fichiers de test XML qui sont situés par rapport à la DLL. Je veux que le chemin soit toujours résolu correctement, que la DLL de test soit exécutée depuis TestDriven.NET, l'interface graphique MbUnit ou autre chose.

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

Ma bibliothèque de test est située à dire

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

et je voudrais obtenir ce chemin:

C: \ projects \ monapplication \ daotests \ bin \ Debug \

Les trois suggestions jusqu'ici me manquent quand je cours du MbUnit Gui:

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

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

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


Application Web?

Server.MapPath("~/MyDir/MyFile.ext")

Autant que je sache, la plupart des autres réponses ont quelques problèmes.

La méthode correcte pour effectuer cela pour un assembly non-GACed sur disque (par opposition à Web) est d'utiliser la propriété CodeBase l'assembly en cours d' CodeBase .

Cela renvoie une URL ( file:// ). Au lieu de jouer avec la manipulation de chaînes ou UnescapeDataString , cela peut être converti avec un minimum de bruit en tirant parti de la propriété LocalPath d' Uri .

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

C'est ce que j'ai trouvé. Entre les projets web, tests unitaires (testeur nunit et resharper) ; J'ai trouvé cela a fonctionné pour moi.

J'ai cherché du code pour détecter la configuration dans laquelle se trouve la construction, Debug/Release/CustomName . Hélas, le #if DEBUG . Donc, si quelqu'un peut améliorer cela !

N'hésitez pas à modifier et améliorer.

Obtenir le dossier de l'application Utile pour les racines web, unittests pour obtenir le dossier des fichiers de test.

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

Obtenir le dossier bin : Utile pour exécuter des assemblages en utilisant la réflexion. Si les fichiers y sont copiés en raison des propriétés de construction.

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

Cela devrait fonctionner, sauf si l'assemblage est copié dans l'ombre :

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

Dans toutes ces années, personne n'a vraiment mentionné celui-ci. Un truc que j'ai appris du super projet ApprovalTests . L'astuce consiste à utiliser les informations de débogage dans l'assembly pour trouver le répertoire d'origine.

Cela ne fonctionnera pas en mode RELEASE, ni avec les optimisations activées, ni sur une machine différente de celle sur laquelle elle a été compilée.

Mais cela vous donnera des chemins relatifs à l'emplacement du fichier de code source à partir duquel vous l'appelez

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

Et ça:

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

J'ai eu le même comportement dans le NUnit dans le passé. Par défaut, NUnit copie votre assembly dans le répertoire temp. Vous pouvez modifier ce comportement dans les paramètres NUnit :

Peut-être que TestDriven.NET et MbUnit GUI ont les mêmes paramètres.


J'ai utilisé Assembly.CodeBase au lieu de Location:

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("/", "\\");

Cela a fonctionné, mais je ne suis plus sûr que c'est 100% correct. La page http://blogs.msdn.com/suzcook/archive/2003/06/26/assembly-codebase-vs-assembly-location.aspx dit:

"La CodeBase est une URL de l'endroit où le fichier a été trouvé, tandis que l'emplacement est le chemin où il a été réellement chargé.Par exemple, si l'assembly a été téléchargé à partir d'Internet, son CodeBase peut commencer par" http: // " , mais son emplacement peut commencer par "C: \" .Si le fichier a été copié par l'ombre, l'emplacement sera le chemin d'accès à la copie du fichier dans le répertoire de copie d'ombre. Il est également bon de savoir que CodeBase n'est pas garanti à définir pour les assemblages dans le GAC, mais l'emplacement sera toujours défini pour les assemblys chargés à partir du disque. "

Vous souhaiterez peut -être utiliser CodeBase au lieu de Location.


Je soupçonne que le vrai problème ici est que votre coureur d'essai copie votre assemblée à un endroit différent. Au moment de l'exécution, il est impossible de dire d'où l'assemblage a été copié, mais vous pouvez probablement basculer un commutateur pour indiquer au coureur de test d'exécuter l'assembly à partir de l'emplacement et de ne pas le copier dans un répertoire d'ombre.

Un tel changement est susceptible d'être différent pour chaque coureur d'essai, bien sûr.

Avez-vous envisagé d'intégrer vos données XML en tant que ressources dans votre assemblage de test?


Je trouve ma solution adéquate pour la récupération de l'emplacement.

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

Le répertoire actuel où vous existez.

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

Si vous copiez le fichier .xml avec build, vous devriez le trouver.

ou

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

// The location of the Assembly
assembly.Location;

Même chose que la réponse 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 faire:

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

ou si vous préférez:

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

Toutes les réponses proposées fonctionnent lorsque le développeur peut modifier le code pour inclure l'extrait requis, mais si vous souhaitez le faire sans modifier de code, vous pouvez utiliser l'explorateur de processus.

Il listera toutes les DLLs d'exécution sur le système, vous devrez peut-être déterminer l'ID de processus de votre application en cours d'exécution, mais ce n'est généralement pas trop difficile.

J'ai écrit une description complète de comment le faire pour une DLL à l'intérieur II - http://nodogmablog.bryanhogan.net/2016/09/locating-and-checking-an-executing-dll-on-a-running-web-server/


Voici un port VB.NET du code de John Sibly. Visual Basic n'est pas sensible à la casse, donc un couple de ses noms de variables étaient en collision avec les noms de type.

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

dans une application de formulaire Windows, vous pouvez simplement utiliser Application.StartupPath

mais pour les DLL et les applications console, le code est beaucoup plus difficile à retenir ...

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

root += slash;
string settingsIni = root + "settings.ini"

est-ce que cela aide?

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

string path = Path.GetDirectoryName(typeof(DaoTests).Module.FullyQualifiedName);

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






reflection