Domanda

Come trovo il percorso dell'applicazione in un'applicazione console?

In Windows Forms , posso usare Application.StartupPath per trova il percorso corrente, ma questo non sembra essere disponibile in un'applicazione console.

È stato utile?

Soluzione

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

Combinalo con System.IO. Path.GetDirectoryName se tutto ciò che desideri è la directory.

  

1 Secondo il commento di Mr.Mindor:
   System.Reflection.Assembly.GetExecutingAssembly (). Location restituisce la posizione in cui si trova l'assembly in esecuzione, che può essere o meno dove si trova l'assembly quando non è in esecuzione. Nel caso di assiemi di copie shadow, si otterrà un percorso in una directory temporanea. System.Reflection.Assembly.GetExecutingAssembly (). CodeBase restituirà il percorso "permanente" dell'assembly.

Altri suggerimenti

È possibile utilizzare il seguente codice per ottenere la directory dell'applicazione corrente.

AppDomain.CurrentDomain.BaseDirectory

Hai due opzioni per trovare la directory dell'applicazione, che hai scelto dipenderà dal tuo scopo.

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

Probabilmente un po 'in ritardo, ma vale la pena menzionare:

Environment.GetCommandLineArgs()[0];

O più correttamente per ottenere solo il percorso della directory:

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

Modifica

Molte persone hanno sottolineato che GetCommandLineArgs non è garantito per restituire il nome del programma. Vedi La prima parola sulla riga di comando è il nome del programma solo per convenzione . L'articolo afferma che "Sebbene pochissimi programmi Windows utilizzino questa stranezza (non ne sono a conoscenza)". Quindi è possibile 'spoofare' GetCommandLineArgs , ma stiamo parlando di un'applicazione console. Le app della console sono in genere veloci e sporche. Quindi questo si adatta alla mia filosofia KISS.

Per chiunque sia interessato alle app web asp.net. Ecco i miei risultati di 3 metodi diversi

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

risultato

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'app sta funzionando fisicamente da " C: \ inetpub \ SBSPortal_staging " ;, quindi la prima soluzione non è assolutamente adatta per le app web.

La risposta sopra era il 90% di ciò di cui avevo bisogno, ma mi ha restituito un Uri anziché un percorso normale.

Come spiegato nel post del forum MSDN, Come convertire il percorso URI in un normale percorso file? , ho usato quanto segue:

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

Forse stai cercando di farlo:

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

puoi invece usare questo.

System.Environment.CurrentDirectory

Per le applicazioni console, puoi provare questo:

System.IO.Directory.GetCurrentDirectory();

Output (sul mio computer locale):

  

c: \ utenti \ xxxxxxx \ documenti \ visual studio 2012 \ Progetti \ ImageHandler \ GetDir \ bin \ Debug

Oppure puoi provare (c'è una barra rovesciata aggiuntiva alla fine):

AppDomain.CurrentDomain.BaseDirectory

Output:

  

c: \ utenti \ xxxxxxx \ documenti \ visual studio 2012 \ Progetti \ ImageHandler \ GetDir \ bin \ Debug \

Ho usato questo codice e ho ottenuto la soluzione.

AppDomain.CurrentDomain.BaseDirectory

Se stai cercando un modo compatibile con .NET Core, usa

System.AppContext.BaseDirectory

Questo è stato introdotto in .NET Framework 4.6 e .NET Core 1.0 (e .NET Standard 1.3). Vedi: Proprietà AppContext.BaseDirectory .

Secondo questa pagina ,

  

Questa è la sostituzione preferita per AppDomain.CurrentDomain.BaseDirectory in .NET Core

Ho usato

System.AppDomain.CurrentDomain.BaseDirectory

quando voglio trovare un percorso relativo a una cartella di applicazioni. Funziona sia con ASP.Net che con applicazioni winform. Inoltre non richiede alcun riferimento agli assembly System.Web.

Puoi semplicemente aggiungere ai riferimenti del tuo progetto System.Windows.Forms e quindi utilizzare System.Windows.Forms.Application.StartupPath come al solito.

Quindi, non è necessario per metodi più complicati o usando la riflessione.

Lo uso se si suppone che exe venga chiamato facendo doppio clic su di esso

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

Voglio dire, perché non un metodo 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());
                }
            }
    }

Lo useresti proprio come Application.StartupPath:

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

La riga seguente ti fornirà un percorso per l'applicazione:

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

La soluzione precedente funziona correttamente nelle seguenti situazioni:

  • app semplice
  • in un altro dominio in cui Assembly.GetEntryAssembly () restituirebbe null
  • La DLL viene caricata dalle risorse integrate come array di byte e caricata in AppDomain come Assembly.Load (byteArrayOfEmbeddedDll)

Assembly.GetEntryAssembly (). Posizione o Assembly.GetExecutingAssembly().Location

Utilizzare in combinazione con System.IO.Path.GetDirectoryName () per ottenere solo la directory.

I percorsi da GetEntryAssembly () e GetExecutingAssembly () possono essere diversi, anche se nella maggior parte dei casi la directory sarà la stessa.

Con GetEntryAssembly () devi essere consapevole che questo può restituire null se il modulo di ingresso non è gestito (es. eseguibile C ++ o VB6). In questi casi è possibile utilizzare GetModuleFileName dall'API Win32:

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

Risolverà il problema per fare riferimento ai file di riferimento di terze parti con i pacchetti di installazione.

in VB.net

My.Application.Info.DirectoryPath

funziona per me (Tipo di applicazione: Libreria di classi). Non sono sicuro di C # ... Restituisce il percorso senza nome file come stringa

Nessuno di questi metodi funziona in casi speciali come l'uso di un collegamento simbolico all'exe, restituiranno la posizione del collegamento non l'exe effettivo.

Quindi puoi usare QueryFullProcessImageName per aggirare ciò:

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

Prova questa semplice riga di codice:

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

Un'altra soluzione sta usando percorsi relativi che puntano al percorso corrente:

Path.GetFullPath(".")

Non ho visto nessuno convertire il LocalPath fornito da .Net Core reflection in un percorso System.IO utilizzabile, quindi ecco la mia versione.

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

   return new FileInfo(exePath).DirectoryName;

}

Questo restituirà l'intero " C: \ xxx \ xxx " percorso formattato per dove si trova il tuo codice.

Esistono molti modi per ottenere il percorso eseguibile, quello che dovremmo usare dipende dalle nostre esigenze qui è un link che discute metodi diversi.

Diversi modi per ottenere il percorso eseguibile dell'applicazione

Ecco una soluzione affidabile che funziona con le applicazioni 32 bit e 64 bit .

Aggiungi questi riferimenti:

  

utilizzando System.Diagnostics;

     

utilizzando System.Management;

Aggiungi questo metodo al tuo progetto:

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

Ora usalo così:

int RootProcessId = Process.GetCurrentProcess().Id;

GetProcessPath(RootProcessId);

Nota che se conosci l'id del processo, questo metodo restituirà il corrispondente ExecutePath.

Extra, per chi è interessato:

Process.GetProcesses() 

... ti darà un array di tutti i processi attualmente in esecuzione, e ...

Process.GetCurrentProcess()

... ti fornirà il processo corrente, insieme alle loro informazioni, ad es. Id, ecc. E anche controllo limitato, ad es. Uccidi, ecc. *

Puoi creare un nome di cartella come Risorse all'interno del progetto usando Esplora soluzioni, quindi puoi incollare un file all'interno delle Risorse.

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);
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top