web-dev-qa-db-fra.com

Comment puis-je obtenir le chemin de l'application dans une application console .NET?

Comment trouver le chemin de l'application dans une application console?

Dans Windows Forms , je peux utiliser Application.StartupPath pour trouver le chemin actuel, mais cela ne semble pas être disponible dans une application console.

882
JSmyth

System.Reflection.Assembly.GetExecutingAssembly() . Location1

Combinez cela avec System.IO.Path.GetDirectoryName si tout ce que vous voulez, c'est le répertoire.

1 Selon le commentaire de Mr.Mindor:
System.Reflection.Assembly.GetExecutingAssembly().Location renvoie l'emplacement où se trouve actuellement l'assemblage d'exécution, qui peut ou non être celui où se trouve l'assembly lorsqu'il n'est pas en cours d'exécution. Dans le cas d'assemblages avec clichés instantanés, vous obtiendrez un chemin dans un répertoire temporaire. System.Reflection.Assembly.GetExecutingAssembly().CodeBase renverra le chemin "permanent" de l'Assemblée.

1117
Sam Axe

Vous pouvez utiliser le code suivant pour obtenir le répertoire de l'application en cours.

AppDomain.CurrentDomain.BaseDirectory
390
Sarathy

Vous avez le choix entre deux options pour trouver le répertoire de l'application. Votre choix dépendra de votre objectif.

// to get the location the Assembly is executing from
//(not necessarily where the it normally resides on disk)
// in the case of the using shadow copies, for instance in NUnit tests, 
// this will be in a temp directory.
string path = System.Reflection.Assembly.GetExecutingAssembly().Location;

//To get the location the Assembly normally resides on disk or the install directory
string path = System.Reflection.Assembly.GetExecutingAssembly().CodeBase;

//once you have the path you get the directory with:
var directory = System.IO.Path.GetDirectoryName(path);
152
Mr.Mindor

Probablement un peu tard, mais cela mérite une mention:

Environment.GetCommandLineArgs()[0];

Ou plus correctement pour obtenir uniquement le chemin du répertoire:

System.IO.Path.GetDirectoryName(Environment.GetCommandLineArgs()[0]);

Modifier:

Quelques personnes ont fait remarquer qu'il n'est pas garanti que GetCommandLineArgs renvoie le nom du programme. Voir Le premier mot sur la ligne de commande est le nom du programme uniquement par convention . L'article indique que "Bien que très peu de programmes Windows utilisent cette bizarrerie (je n'en connais aucun moi-même)". Il est donc possible de "spoofer" GetCommandLineArgs, mais nous parlons d'une application console. Les applications de la console sont généralement rapides et sales. Cela correspond donc à ma philosophie KISS.

77
Steve Mc

Pour toute personne intéressée par les applications web asp.net. Voici mes résultats de 3 méthodes différentes

protected void Application_Start(object sender, EventArgs e)
{
  string p1 = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
  string p2 = System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath;
  string p3 = this.Server.MapPath("");
  Console.WriteLine("p1 = " + p1);
  Console.WriteLine("p2 = " + p2);
  Console.WriteLine("p3 = " + p3);
}

résultat

p1 = C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\a897dd66\ec73ff95\Assembly\dl3\ff65202d\29daade3_5e84cc01
p2 = C:\inetpub\SBSPortal_staging\
p3 = C:\inetpub\SBSPortal_staging

l'application fonctionne physiquement à partir de "C:\inetpub\SBSPortal_staging", de sorte que la première solution n'est certainement pas appropriée pour les applications Web.

43
rocketsarefast

La réponse ci-dessus était 90% de ce dont j'avais besoin, mais m'a renvoyé un Uri au lieu d'un chemin normal.

Comme expliqué dans le message MSDN sur les forums, Comment convertir le chemin URI en chemin de fichier normal? , j’ai utilisé les éléments suivants:

// Get normal filepath of this Assembly's permanent directory
var path = new Uri(
    System.IO.Path.GetDirectoryName(
        System.Reflection.Assembly.GetExecutingAssembly().CodeBase)
    ).LocalPath;
36
fizzled

Vous voulez peut-être faire ceci:

System.IO.Path.GetDirectoryName(
    System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase)
27
PSU_Kardi

vous pouvez utiliser celui-ci à la place.

System.Environment.CurrentDirectory
23
ButtShock

Pour les applications console, vous pouvez essayer ceci:

System.IO.Directory.GetCurrentDirectory();

Sortie (sur ma machine locale):

c:\utilisateurs\xxxxxxx\documents\visual studio 2012\Projets\ImageHandler\GetDir\bin\Debug

Ou vous pouvez essayer (il y a une barre oblique inverse à la fin):

AppDomain.CurrentDomain.BaseDirectory

Sortie:

c:\utilisateurs\xxxxxxx\documents\visual studio 2012\Projets\ImageHandler\GetDir\bin\Debug \

19
F.Alves

J'ai utilisé ce code et obtenir la solution.

AppDomain.CurrentDomain.BaseDirectory

Si vous recherchez une méthode compatible avec .NET Core, utilisez

System.AppContext.BaseDirectory

Cela a été introduit dans .NET Framework 4.6 et .NET Core 1.0 (et .NET Standard 1.3). Voir: Propriété AppContext.BaseDirectory .

Selon cette page ,

Ceci est le remplacement préféré pour AppDomain.CurrentDomain.BaseDirectory dans .NET Core

14
Dejan

Vous pouvez simplement ajouter à vos références de projet System.Windows.Forms puis utiliser le System.Windows.Forms.Application.StartupPath comme d'habitude.

Donc, pas besoin de méthodes plus compliquées ou en utilisant la réflexion.

8
fruggiero

J'ai utilisé

System.AppDomain.CurrentDomain.BaseDirectory

quand je veux trouver un chemin relatif à un dossier d'applications. Cela fonctionne pour les applications ASP.Net et Winform. De plus, il ne nécessite aucune référence aux assemblys System.Web.

8
user2346593

J'utilise ceci si l'exe est censé s'appeler en double cliquant dessus

var thisPath = System.IO.Directory.GetCurrentDirectory();
7
developer747

Je veux dire, pourquoi pas une méthode p/invoke?

    using System;
    using System.IO;
    using System.Runtime.InteropServices;
    using System.Text;
    public class AppInfo
    {
            [DllImport("kernel32.dll", CharSet = CharSet.Auto, ExactSpelling = false)]
            private static extern int GetModuleFileName(HandleRef hModule, StringBuilder buffer, int length);
            private static HandleRef NullHandleRef = new HandleRef(null, IntPtr.Zero);
            public static string StartupPath
            {
                get
                {
                    StringBuilder stringBuilder = new StringBuilder(260);
                    GetModuleFileName(NullHandleRef, stringBuilder, stringBuilder.Capacity);
                    return Path.GetDirectoryName(stringBuilder.ToString());
                }
            }
    }

Vous l'utiliseriez exactement comme Application.StartupPath:

    Console.WriteLine("The path to this executable is: " + AppInfo.StartupPath + "\\" + System.Diagnostics.Process.GetCurrentProcess().ProcessName + ".exe");
6
user3596865

La ligne suivante vous donnera un chemin d’application:

var applicationPath = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName)

La solution ci-dessus fonctionne correctement dans les situations suivantes:

  • application simple
  • dans un autre domaine où Assembly.GetEntryAssembly () renvoie null
  • La DLL est chargée à partir de ressources incorporées sous forme de tableau d'octets et chargée dans AppDomain en tant qu'Assembly.Load (byteArrayOfEmbeddedDll).
  • avec les bundles mkbundle de Mono (aucune autre méthode ne fonctionne)
6
user2126375

dans VB.net

My.Application.Info.DirectoryPath

travaille pour moi (Type d'application: Bibliothèque de classes). Pas sûr de C # ... Renvoie le chemin sans nom de fichier sous forme de chaîne

5
dba

Assembly.GetEntryAssembly().Location ou Assembly.GetExecutingAssembly().Location

Utiliser en combinaison avec System.IO.Path.GetDirectoryName() pour obtenir uniquement le répertoire.

Les chemins de GetEntryAssembly() et GetExecutingAssembly() peuvent être différents, même si dans la plupart des cas, le répertoire sera le même.

Avec GetEntryAssembly(), vous devez savoir que cela peut renvoyer null si le module d’entrée est non géré (c-à-d un exécutable C++ ou VB6). Dans ces cas, il est possible d'utiliser GetModuleFileName à partir de l'API Win32:

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern int GetModuleFileName(HandleRef hModule, StringBuilder buffer, int length);
5
Herman
AppDomain.CurrentDomain.BaseDirectory

Résoudre le problème en faisant référence aux fichiers de référence tiers avec les packages d'installation.

5
Nirav Mehta

Essayez cette simple ligne de code:

 string exePath = Path.GetDirectoryName( Application.ExecutablePath);
2
daniele3004

Aucune de ces méthodes ne fonctionne dans des cas particuliers, comme l'utilisation d'un lien symbolique vers l'exe, elles renverront l'emplacement du lien et non l'exe.

Donc peut utiliser QueryFullProcessImageName pour contourner cela:

using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Diagnostics;

internal static class NativeMethods
{
    [DllImport("kernel32.dll", SetLastError = true)]
    internal static extern bool QueryFullProcessImageName([In]IntPtr hProcess, [In]int dwFlags, [Out]StringBuilder lpExeName, ref int lpdwSize);

    [DllImport("kernel32.dll", SetLastError = true)]
    internal static extern IntPtr OpenProcess(
        UInt32 dwDesiredAccess,
        [MarshalAs(UnmanagedType.Bool)]
        Boolean bInheritHandle,
        Int32 dwProcessId
    );
}

public static class utils
{

    private const UInt32 PROCESS_QUERY_INFORMATION = 0x400;
    private const UInt32 PROCESS_VM_READ = 0x010;

    public static string getfolder()
    {
        Int32 pid = Process.GetCurrentProcess().Id;
        int capacity = 2000;
        StringBuilder sb = new StringBuilder(capacity);
        IntPtr proc;

        if ((proc = NativeMethods.OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, pid)) == IntPtr.Zero)
            return "";

        NativeMethods.QueryFullProcessImageName(proc, 0, sb, ref capacity);

        string fullPath = sb.ToString(0, capacity);

        return Path.GetDirectoryName(fullPath) + @"\";
    }
}
2
colin lamarre

Une autre solution consiste à utiliser des chemins relatifs pointant vers le chemin actuel:

Path.GetFullPath(".")
1
blenderfreaky

Vous pouvez utiliser le code suivant, vous obtiendrez le chemin complet de l'application:

 class Program
{
    static void Main(string[] args)
    {
        string AppPath = System.Reflection.Assembly.GetExecutingAssembly().Location;
        WriteLine($"ApplicationPath ---{AppPath}");
        //OutPut// //ApplicationPath---C:\Users\TestUser\source\repos\ThreadStack\ThreadStack\bin\Debug\ThreadStack.exe
        ReadLine();
    }
}  
0
Sunil Dhappadhule

Il existe de nombreuses façons d’obtenir un chemin d’exécutable, celui que nous devrions utiliser dépend de nos besoins. Voici un lien qui décrit différentes méthodes.

Différentes façons d'obtenir le chemin de l'exécutable de l'application

0
Nasir Mahmood

Je n'ai vu personne convertir le chemin LocalPath fourni par .Net Core reflection en un chemin System.IO utilisable. Voici donc ma version.

public static string GetApplicationRoot()
{
   var exePath = new Uri(System.Reflection.
   Assembly.GetExecutingAssembly().CodeBase).LocalPath;

   return new FileInfo(exePath).DirectoryName;

}

Cela renverra le chemin complet formaté "C:\xxx\xxx" à l'endroit où se trouve votre code.

0
mark gamache