Meilleure façon d'obtenir le chemin du dossier d'application

515

Je vois qu'il existe des moyens d'obtenir le chemin du dossier d'application:

  1. Application.StartupPath
  2. System.IO.Path.GetDirectoryName( System.Reflection.Assembly.GetExecutingAssembly().Location)
  3. AppDomain.CurrentDomain.BaseDirectory
  4. System.IO.Directory.GetCurrentDirectory()
  5. Environment.CurrentDirectory
  6. System.IO.Path.GetDirectoryName( System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase)
  7. System.IO.Path.GetDirectory(Application.ExecutablePath)

Quelle est la meilleure façon selon la situation?

Leo Vo
la source
9
Pourquoi nous avons beaucoup de façons d'obtenir le chemin de l'application. Je pense qu'il y a une raison pour chaque chemin.
Leo Vo
1
Il y a une erreur dans # 6: doit se lire: System.Reflection.Assembly.GetExecutingAssembly (). GetName (). CodeBase), System.IO.Path.GetDirectoryName (Application.ExecutablePath)
BillW
2
hourra pour # 6, alors que je suis dans un projet web, je ne voulais pas de logique Server.MapPath dans ma bibliothèque chargée IoC qui n'est pas spécifique au web
bkwdesign
1
Nous avons maintenant le fiable IHostEnvironment.ContentRootPath, accessible via une IHostEnvironmentdépendance injectée (qui contient d'autres choses utiles).
Timo

Réponses:

519

AppDomain.CurrentDomain.BaseDirectory est probablement le plus utile pour accéder aux fichiers dont l'emplacement est relatif au répertoire d'installation de l'application.

Dans une application ASP.NET, ce sera le répertoire racine de l'application, pas le sous-dossier bin - ce qui est probablement ce que vous voulez habituellement. Dans une application cliente, ce sera le répertoire contenant l'exécutable principal.

Dans une application VSTO 2005, ce sera le répertoire contenant les assemblys gérés VSTO pour votre application, et non, disons, le chemin d'accès à l'exécutable Excel.

Les autres peuvent renvoyer des répertoires différents en fonction de votre environnement - voir par exemple la réponse de @ Vimvq1987.

CodeBaseest l'endroit où un fichier a été trouvé et peut être une URL commençant par http: //. Dans ce cas, ce Locationsera probablement le cache de téléchargement de l'assembly. CodeBase n'est pas garanti d'être défini pour les assemblys dans le GAC .

Joe
la source
2
Lors des tests dans Windows XP 32 bits, il revient là où le raccourci a commencé.
Joshua Son
1
+1 @Joe et pour le complément au niveau du document VSTO voir CECI
3
Sachez que cela renvoie un chemin avec une barre oblique inversée à la fin. Cela m'a causé des problèmes lors du formatage d'une chaîne avec le résultat à passer comme argument de processus.
avenmore
19
@avenmore - Si vous formatez une chaîne pour créer un chemin, envisagez d'utiliser à la Path.Combineplace. Cela s'occupera de la barre oblique inverse pour vous.
Joe
1
Cela renvoie le dossier bin / debug pour moi dans VS 2017, pas le répertoire racine.
SmoveBB
86
  1. Application.StartupPathet 7. System.IO.Path.GetDirectoryName(Application.ExecutablePath)- Ne fonctionnera que pour l' application Windows Forms

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

    Va vous donner quelque chose comme: "C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\Temporary ASP.NET Files\\legal-services\\e84f415e\\96c98009\\assembly\\dl3\\42aaba80\\bcf9fd83_4b63d101"c'est là que se trouve la page que vous exécutez.

  3. AppDomain.CurrentDomain.BaseDirectorypour l'application Web pourrait être utile et retournera quelque chose comme le "C:\\hg\\Services\\Services\\Services.Website\\"répertoire de base et est très utile.

  4. System.IO.Directory.GetCurrentDirectory() et 5. Environment.CurrentDirectory

vous donnera l'emplacement d'où le processus a été déclenché - donc pour une application Web exécutée en mode débogage à partir de Visual Studio, quelque chose comme "C:\\Program Files (x86)\\IIS Express"

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

vous donnera l'emplacement où .dllest exécuté le code, pour une application Web qui pourrait être"file:\\C:\\hg\\Services\\Services\\Services.Website\\bin"

Maintenant, dans le cas par exemple de l'application console, les points 2-6 seront le répertoire où se .exe trouve le fichier.

J'espère que cela vous fera gagner du temps.

Matas Vaitkevicius
la source
2
De toute façon, le fait de vouloir le "dossier actuel" n'est pertinent que pour les applications non Web de toute façon ...
Nyerguds
2
Telle est la réponse.
P.Brian.Mackey
59

Notez que toutes ces méthodes ne renverront pas la même valeur. Dans certains cas, ils peuvent renvoyer la même valeur, mais attention, leurs objectifs sont différents:

Application.StartupPath

renvoie le StartupPathparamètre (peut être défini lors de l'exécution de l'application)

System.IO.Directory.GetCurrentDirectory()

renvoie le répertoire en cours, qui peut être ou non le dossier dans lequel se trouve l'application. Il en va de même Environment.CurrentDirectory. Dans le cas où vous l'utilisez dans un fichier DLL, il renverra le chemin où le processus s'exécute (cela est particulièrement vrai dans ASP.NET).

Quan Mai
la source
7
S'il vous plaît s'il vous plaît s'il vous plaît ne pas utiliser GetCurrentDirectory(), pour l'amour de courir des choses de différents chemins! :(
kayleeFrye_onDeck
@kayleeFrye_onDeck vous n'avez pas expliqué les raisons de la question précédente.
nless
10

Pour une application Web, pour obtenir le répertoire racine de l'application Web actuelle, appelez généralement par page Web pour la demande entrante actuelle:

HttpContext.Current.Server.MapPath();

System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath;

Description du code ci-dessus

Raj kumar
la source
6

J'ai démarré un processus à partir d'un service Windows sur l'API Win32 dans la session de l'utilisateur qui est réellement connecté (dans la session 1 du Gestionnaire des tâches et non 0). Dans ce cas, nous pouvons savoir quelle variable est la meilleure.

Pour les 7 cas de la question ci-dessus, les résultats sont les suivants:

Path1: C:\Program Files (x86)\MyProgram
Path2: C:\Program Files (x86)\MyProgram
Path3: C:\Program Files (x86)\MyProgram\
Path4: C:\Windows\system32
Path5: C:\Windows\system32
Path6: file:\C:\Program Files (x86)\MyProgram
Path7: C:\Program Files (x86)\MyProgram

Il est peut-être utile pour certains d'entre vous de faire la même chose lorsque vous recherchez la meilleure variable pour votre cas.

Betterave
la source
4
Réponse très pertinente. Tant de gens oublient que "répertoire de travail"! = "Répertoire de programme".
Nyerguds
3

D'après mon expérience, la meilleure façon est une combinaison de ces éléments.

  1. System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase Vous donnera le dossier bin
  2. Directory.GetCurrentDirectory() Fonctionne bien sur .Net Core mais pas .Net et vous donnera le répertoire racine du projet
  3. System.AppContext.BaseDirectoryet AppDomain.CurrentDomain.BaseDirectory Fonctionne bien dans .Net mais pas .Net core et vous donnera le répertoire racine du projet

Dans une bibliothèque de classe qui est censée cibler le noyau .Net et .Net, je vérifie quel framework héberge la bibliothèque et je choisis l'un ou l'autre.

Ahmed Mansour
la source
2

J'ai utilisé celui-ci avec succès

System.IO.Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName)

Cela fonctionne même à l'intérieur de linqpad.

camilohe
la source
1
il manque le crochet d'ouverture de GetCurrentProcess. btw il évalue à C: \ Program Files \ dotnet dans mon projet de base .net lors du débogage dans Visual Studio car c'est là que se trouve
dotnet.exe
1

Répertoire racine:

DriveInfo cDrive = new DriveInfo(System.Environment.CurrentDirectory);
var driverPath = cDrive.RootDirectory;
Alparslan ŞEN
la source
1
Cela semble obtenir le répertoire de travail actuel, bien que cela puisse être utile parfois, il n'est certainement pas garanti qu'il s'agit du chemin EXE.
krowe2
0

Si vous savez obtenir le répertoire racine:

string rootPath = Path.GetPathRoot(Application.StartupPath)
Alparslan ŞEN
la source
0

celui-ci a System.IO.Path.GetDirectory(Application.ExecutablePath)changé enSystem.IO.Path.GetDirectoryName(Application.ExecutablePath)

nazim hatipoglu
la source