Question

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.

Était-ce utile?

La solution

System.Reflection.Assembly.GetExecutingAssembly () . Emplacement 1

Combinez cela avec System.IO. Path.GetDirectoryName si vous ne voulez que le répertoire.

  

1 Selon le commentaire de M.Mindor:
   System.Reflection.Assembly.GetExecutingAssembly (). Location renvoie l'emplacement où se trouve actuellement l'assembly en cours d'exécution, qui peut être ou non l'emplacement où se trouve l'assembly lorsqu'il n'est pas exécuté. 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'assembly.

Autres conseils

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

AppDomain.CurrentDomain.BaseDirectory

Vous avez le choix entre deux options pour trouver le répertoire de l'application. Elles dépendent 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);

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:

Un bon nombre de personnes ont fait remarquer qu'il n'était pas garanti que GetCommandLineArgs renvoie le nom du programme. Voir Le premier mot de 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 ne le connais pas 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.

Pour les personnes intéressées 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.

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’utilisais 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;

Vous souhaitez peut-être faire ceci:

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

vous pouvez utiliser celui-ci à la place.

System.Environment.CurrentDirectory

Pour les applications console, vous pouvez essayer ceci:

System.IO.Directory.GetCurrentDirectory();

Sortie (sur mon ordinateur local):

  

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 \

J'ai utilisé ce code et récupéré la solution.

AppDomain.CurrentDomain.BaseDirectory

Si vous recherchez une solution 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

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.

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 ni d’utiliser la réflexion.

J'utilise ceci si le fichier EXE est censé être appelé en double cliquant dessus

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

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

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 () renverrait 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)

Assembly.GetEntryAssembly (). Emplacement ou Assembly.GetExecutingAssembly (). Emplacement

À 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'est-à-dire 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);
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.

dans VB.net

My.Application.Info.DirectoryPath

fonctionne 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

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 réel.

Vous pouvez donc 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) + @"\";
    }
}

Essayez cette simple ligne de code:

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

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

Path.GetFullPath(".")

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;

}

Ceci renverra l'intégralité du " C: \ xxx \ xxx " chemin formaté à l'endroit où se trouve votre code.

Il existe de nombreuses manières d’obtenir un chemin d’exécutable, celui que nous devrions utiliser dépend de nos besoins. Voici un lien qui présente différentes méthodes.

Différentes manières d'obtenir le chemin exécutable de l'application

Voici une solution fiable fonctionnant avec les applications 32 bits et 64 bits .

Ajoutez ces références:

  

utilisant System.Diagnostics;

     

using System.Management;

Ajoutez cette méthode à votre projet:

public static string GetProcessPath(int processId)
{
    string MethodResult = "";
    try
    {
        string Query = "SELECT ExecutablePath FROM Win32_Process WHERE ProcessId = " + processId;

        using (ManagementObjectSearcher mos = new ManagementObjectSearcher(Query))
        {
            using (ManagementObjectCollection moc = mos.Get())
            {
                string ExecutablePath = (from mo in moc.Cast<ManagementObject>() select mo["ExecutablePath"]).First().ToString();

                MethodResult = ExecutablePath;

            }

        }

    }
    catch //(Exception ex)
    {
        //ex.HandleException();
    }
    return MethodResult;
}

Maintenant, utilisez-le comme suit:

int RootProcessId = Process.GetCurrentProcess().Id;

GetProcessPath(RootProcessId);

Notez que si vous connaissez l'id du processus, cette méthode renverra le chemin ExecutePath correspondant.

Extra, pour ceux que cela intéresse:

Process.GetProcesses() 

... vous donnera un tableau de tous les processus en cours d'exécution, et ...

Process.GetCurrentProcess()

... vous donnera le processus en cours, ainsi que leurs informations, par exemple. Id, etc., ainsi qu'un contrôle limité, par ex. Tuer, etc. *

Vous pouvez créer un nom de dossier en tant que ressources dans le projet à l'aide de l'Explorateur de solutions, puis coller un fichier dans les ressources.

private void Form1_Load(object sender, EventArgs e) {
    string appName = Environment.CurrentDirectory;
    int l = appName.Length;
    int h = appName.LastIndexOf("bin");
    string ll = appName.Remove(h);                
    string g = ll + "Resources\\sample.txt";
    System.Diagnostics.Process.Start(g);
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top