Come posso ottenere il nome dell'eseguibile corrente in C #?


355

Voglio ottenere il nome del programma attualmente in esecuzione, ovvero il nome eseguibile del programma. In C / C ++ lo ottieni da args[0].


Eseguibile è un file EXE (Windows Form, applicazioni WPF)? Un programma può essere un'app desktop (WinForms, WPF e WinRT-Windows Phone?), Un'applicazione Web, un'applicazione di servizio Wcf, un componente aggiuntivo di Visual Studio, un componente aggiuntivo di Outlook-Word, un test unitario in VS (MSTest) o un'applicazione Silverlight.
Kiquenet,

Risposte:


405
System.AppDomain.CurrentDomain.FriendlyName

61
Attenzione alla risposta accettata. Abbiamo riscontrato problemi con l'utilizzo delle System.AppDomain.CurrentDomain.FriendlyNameapplicazioni distribuite Click-Once. Per noi, questo restituisce " DefaultDomain " e non il nome exe originale.
Gaspode

40
string file = object_of_type_in_application_assembly.GetType().Assembly.Location; string app = System.IO.Path.GetFileNameWithoutExtension( file );
Gaspode,

4
FriendlyName può essere impostato su qualsiasi cosa. Anche ottenere la posizione dell'assemblaggio potrebbe non essere sufficiente se si dispone di un exe con diverse DLL. Inoltre, se si utilizzano diversi AppDomain, Assembly.GetCallingAssembly () restituisce null.
user276648

2
@Gaspode: sarebbe più semplice dire Path.GetFileNameWithoutExtension (GetType (). Assembly.Location) - non è necessario specificare un oggetto di un tipo nell'assembly corrente. È possibile utilizzare GetType di questo e quindi non è nemmeno necessario dire "questo".
Vbullinger,

4
Questo può essere utile, ma dovrebbe non essere la risposta accettata: E 'molto diverso da quello che è stato chiesto - sarà per coincidenza la stessa cosa in alcune situazioni, ma questo è qualcosa di completamente diverso. Se non hai scritto l'applicazione da solo, potresti benissimo restituire "Mi piacciono le patate!" o qualsiasi altra cosa il tuo collega umoristico abbia scritto in questa proprietà quando ha creato l'applicazione!
AnorZaken,

237

System.AppDomain.CurrentDomain.FriendlyName - Restituisce il nome file con estensione (ad esempio MyApp.exe).

System.Diagnostics.Process.GetCurrentProcess().ProcessName- Restituisce il nome file senza estensione (ad es. MyApp).

System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName- Restituisce il percorso completo e il nome file (ad es. C: \ Esempi \ Processi \ MyApp.exe). È quindi possibile passare a questo System.IO.Path.GetFileName()o System.IO.Path.GetFileNameWithoutExtension()per ottenere gli stessi risultati di cui sopra.


3
AppDomain può essere un'applicazione EXE, un'applicazione Web, un'applicazione di test unità, Addin Visual Studio e "Silverlight App" (?). Forse interessante soluzione completa per tutti i casi. Ad esempio, per Unit Test VS2012 - Nome processo: vstest.executionengine.x86 MainModule.FileName: C: \ PROGRAM FILES (X86) \ MICROSOFT VISUAL STUDIO 11.0 \ COMMON7 \ IDE \ COMMONEXTENSIONS \ MICROSOFT \ TESTWINDOW \ vstest.executionxine.exe MainModule.ModuleName: vstest.executionengine.x86.exe FriendlyName: UnitTestAdapter: Running test
Nome

Un "programma" può essere un'app desktop (WinForms, WPF; e WinRT-Windows Phone?), Applicazione Web, applicazione di servizio Wcf, componente aggiuntivo di Visual Studio, componente aggiuntivo di Outlook-Word, test unit in VS (MSTest) o applicazione Silverlight . Ad esempio, come ottenere l'assemblaggio dell'host di servizio per un'applicazione di servizio Wcf ospitata in IIS, non IISExpress o WebDevServer?
Kiquenet,

6
+1 Vado con questa risposta perché fornisce tutte e tre le varianti di cui potresti aver bisogno in modo pulito e semplice. L'uso del nome del programma nudo senza percorso o estensione è molto utile per il testo di aiuto ( /?switch) all'interno del programma , poiché l'uso dell'estensione e del percorso lo ingombra inutilmente.
Synetech,

2
Ricorda di eliminare il risultato diGetCurrentProcess()
Mahmoud Al-Qudsi il

Process.GetCurrentProcess().ProcessName()restituisce MyApp.vshost per me.
Jonathan Wood,

106

System.Diagnostics.Process.GetCurrentProcess()ottiene il processo attualmente in esecuzione. Puoi usare la ProcessNameproprietà per capire il nome. Di seguito è un'app console di esempio.

using System;
using System.Diagnostics;

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(Process.GetCurrentProcess().ProcessName);
        Console.ReadLine();
    }
}

36
Meglio usare Process.GetCurrentProcess (). MainModule.FileName
KindDragon

Process.GetCurrentProcess (). MainModule.FileName funziona perfettamente da un componente aggiuntivo Excel (ExcelDNA)
earcam

10
Questo approccio fallirà quando utilizzato sul runtime Mono; il nome del processo per le applicazioni in esecuzione su Mono sarà sempre una variante di .../bin/mono* nix o .../mono.exesu Windows.
cdhowie,

1
Questa dovrebbe essere la risposta accettata. Il nome corrente di AppDomain potrebbe non avere nulla a che fare con il nome del processo eseguibile, specialmente quando sono presenti più domini di app
Ivan Krivyakov,

Questo metodo può essere sostanzialmente più lento rispetto a giocare con la classe Assembly.
Erwin Mayer,

99

Questo dovrebbe bastare:

Environment.GetCommandLineArgs()[0];

3
Hmm, questo restituisce (quando eseguito da vs.net e usando la cosa di hosting di debug), la posizione e il nome del nome file.vshost.exe ... che è davvero il file che è in esecuzione in questo momento)
Frederik Gheysels

13
Questa è la risposta migliore per me perché Environment.GetCommandLineArgs()è l'esatto analogo C # di argvda C / C ++.
Frederick The Fool,

Concordato! migliore risposta. Ho bisogno di ottenere Environment.GetCommandLineArgs () [1];
Jerry Liang

1
Per evitare il percorso completo:Path.GetFileNameWithoutExtension(Environment.GetCommandLineArgs()[0])
Nathan

1
Funziona bene quando si cerca di rintracciare i servizi WCF. Il nome del processo ritorna con iisexpress nel mio caso. Ma questo comando mi dà l'attuale nome dell'assembly del servizio WCF.
P.Brian.Mackey

19

Questo è il codice che ha funzionato per me:

string fullName = Assembly.GetEntryAssembly().Location;
string myName = Path.GetFileNameWithoutExtension(fullName);

Tutti gli esempi sopra mi hanno dato processName con vshost o il nome dll in esecuzione.


4
Per coloro che non lo conoscono o lo hanno perso in altre risposte, lo spazio dei nomi per Assembly è System.Reflection e lo spazio dei nomi per Path è System.IO.
riuniscono il

4
GetEntryAssembly restituirà null se il punto di ingresso dell'applicazione è nel codice nativo anziché in un assembly.
Emdot,

18

Prova questo:

System.Reflection.Assembly.GetExecutingAssembly()

Questo ti restituisce System.Reflection.Assemblyun'istanza che contiene tutti i dati che potresti voler sapere sull'applicazione corrente. Penso che la Locationproprietà potrebbe ottenere ciò che stai cercando specificamente.


6
Potrebbe essere più sicuro da usare CodeBaseinvece che Locationnel caso in cui la funzione di copia shadow di .NET sia attiva. Vedi blogs.msdn.com/suzcook/archive/2003/06/26/…
Dirk Vollmar,

18
Attenzione a GetExecutingAssembly (): se lo si chiama da un assembly della libreria, restituisce il nome dell'assembly della libreria, che è diverso dal nome dell'assembly della voce (ovvero l'eseguibile originale). Se si utilizza GetEntryAssembly (), restituisce il nome dell'eseguibile effettivo, ma genera un'eccezione se il processo è in esecuzione in WCF (è vero che una situazione rara). Per il codice più affidabile, utilizzare Process.GetCurrentProcess (). ProcessName.
Contango,

@Gravitas: Certamente no, qualsiasi eseguibile che esegue "interpretato", ad esempio con / usr / bin / mono, avrà un nome di processo errato. Inoltre ProcessName non funzionerà con i servizi di Windows. Se lo usi in una libreria, usa GetCallingAssembly.
Stefan Steiger,

1
Ha funzionato per me. La proprietà Nome della chiamata GetName () restituita dall'istanza di Assembly è ciò di cui hai bisogno e non include la parte ".exe". Testato anche su Mono / Linux con il risultato atteso. Assembly.GetName (). Nome
Hatoru Hansou,

1
Hmm, nota che la stringa restituita non cambierà anche se rinomini manualmente il file eseguibile usando Esplora file. Mentre Environment.GetCommandLineArgs () [0] cambia insieme al nome del file eseguibile effettivo (ovviamente). Per coincidenza, il secondo metodo è risultato migliore per la mia situazione specifica in quanto desidero che la cartella dei dati sia denominata come nome file eseguibile effettivo.
Hatoru Hansou,

11
System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name;

ti darà FileName della tua app come; "MyApplication.exe"


11

Perché nessuno ha suggerito questo, è semplice.

Path.GetFileName(Application.ExecutablePath)

3
Quale spazio dei nomi risiede l'applicazione.
Jeetendra,

6
Ciò è utile quando si utilizza un'app di Windows Form, ma non diversamente
NineBerry

@NineBerry Potreste essere interessati a Application.ExecutablePath's codice sorgente .
Spettrale il

@NineBerry Vedi il mio post. Funziona con le app della console se aggiungi un riferimento a System.Windows.Forms.
Giovanni,


9

Se è necessario il nome del programma per impostare una regola firewall, utilizzare:

System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName

Ciò garantirà che il nome sia corretto sia durante il debug in VisualStudio sia quando si esegue l'app direttamente in Windows.


2
Per i miei scopi (creazione di un nome file di registrazione), questa è la risposta migliore. Se si esegue un processo ospitato (ad esempio un servizio o un'applicazione Web), System.AppDomain.CurrentDomain.FriendlyName può restituire un brutto nome GUID-y con barre incorporate.
Curt

8

In caso di incertezza o dubbio, corri in cerchio, grida e grida.

class Ourself
{
    public static string OurFileName() {
        System.Reflection.Assembly _objParentAssembly;

        if (System.Reflection.Assembly.GetEntryAssembly() == null)
            _objParentAssembly = System.Reflection.Assembly.GetCallingAssembly();
        else
            _objParentAssembly = System.Reflection.Assembly.GetEntryAssembly();

        if (_objParentAssembly.CodeBase.StartsWith("http://"))
            throw new System.IO.IOException("Deployed from URL");

        if (System.IO.File.Exists(_objParentAssembly.Location))
            return _objParentAssembly.Location;
        if (System.IO.File.Exists(System.AppDomain.CurrentDomain.BaseDirectory + System.AppDomain.CurrentDomain.FriendlyName))
            return System.AppDomain.CurrentDomain.BaseDirectory + System.AppDomain.CurrentDomain.FriendlyName;
        if (System.IO.File.Exists(System.Reflection.Assembly.GetExecutingAssembly().Location))
            return System.Reflection.Assembly.GetExecutingAssembly().Location;

        throw new System.IO.IOException("Assembly not found");
    }
}

Non posso affermare di aver testato ciascuna opzione, ma non fa nulla di stupido come restituire il vhost durante le sessioni di debug.


2
+1 per divertimento. :-) Difficilmente userei questo codice, a meno che non stia scrivendo una libreria davvero generica che non ha idea del suo ambiente (e quindi probabilmente non sarebbe una buona idea mantenere lo stato globale che avresti usato il nome per).
Andrey Tarantsov,

@Orwellophile Un "programma" può essere un'app desktop (WinForms, WPF; e WinRT-Windows Phone?), Applicazione Web, applicazione di servizio Wcf, componente aggiuntivo di Visual Studio, componente aggiuntivo di Outlook-Word, test unit in VS (MSTest), oppure, Applicazione Silverlight. Ad esempio, come ottenere l'assemblaggio dell'host di servizio per un'applicazione di servizio Wcf ospitata in IIS, non IISExpress o WebDevServer? Qualche codice completo valido per A WinForms, WPF, applicazione Web, applicazione di servizio Wcf, componente aggiuntivo di Visual Studio, componente aggiuntivo di Outlook-Word, test unitario in applicazioni VS (MSTest)?
Kiquenet,

8
  • System.Reflection.Assembly.GetEntryAssembly().Location restituisce la posizione del nome exe se assembly non è caricato dalla memoria.
  • System.Reflection.Assembly.GetEntryAssembly().CodeBase restituisce la posizione come URL.

Testato, funziona al 100%, anche se viene chiamato da una libreria C #.
Contango,

1
GetEntryAssembly () restituisce null se non ci si trova nell'AppDomain principale.
user276648

4

SE stai cercando le informazioni complete sul percorso del tuo eseguibile, il modo affidabile per farlo è usare quanto segue:

   var executable = System.Diagnostics.Process.GetCurrentProcess().MainModule
                       .FileName.Replace(".vshost", "");

Questo elimina qualsiasi problema con dll intermedie, vshost, ecc.


Ho provato il tuo modo affidabile in Ubuntu Linux 15.10 C ++ usando realpath seguito dalla sostituzione della stringa C ++ STL e ha causato il fallimento di Point and Click. Potrebbe essere stato causato da un bug in mono come il nostro direttore del software ha ipotizzato oggi? Grazie.
Frank,

Non programma su Mono, anche se potrebbe essere divertente provarlo
the May

Gasponde ha scritto sopra che "Abbiamo avuto problemi con l'utilizzo di System.AppDomain.CurrentDomain.FriendlyName nelle applicazioni distribuite Click-Once". Potresti indovinare quali potrebbero essere i problemi con le applicazioni distribuite Click-Once in .NET? Grazie.
Frank,

Restituisce C: \ Programmi \ dotnet \ dotnet.exe per il mio programma di esempio in VS2017.
jwdonahue,

3

È possibile utilizzare Environment.GetCommandLineArgs()per ottenere gli argomenti e Environment.CommandLineper ottenere la riga di comando effettiva immessa.

Inoltre, puoi usare Assembly.GetEntryAssembly()o Process.GetCurrentProcess().

Tuttavia, durante il debug, è necessario fare attenzione poiché questo esempio finale può dare il nome dell'eseguibile del debugger (a seconda di come si collega il debugger) anziché l'eseguibile, come gli altri esempi.


4
Attenzione a GetExecutingAssembly (): se lo si chiama da un assembly della libreria, restituisce il nome dell'assembly della libreria, che è diverso dal nome dell'assembly della voce (ovvero l'eseguibile originale). Se si utilizza GetEntryAssembly (), restituisce il nome dell'eseguibile effettivo, ma genera un'eccezione se il processo è in esecuzione in WCF (è vero che una situazione rara). Per il codice più affidabile, utilizzare Process.GetCurrentProcess (). ProcessName.
Contango,

@Gravitas: buon punto - wow, è passato un po 'di tempo da quando ho scritto questo! : D Modificherò di conseguenza
Jeff Yates,

Environment.CommandLinefornisce il percorso assoluto, non la riga di comando inserita, almeno su Mono / Linux.
Lumaca meccanica il

@Mechanicalsnail: sembra che Mono non segua abbastanza la documentazione. Interessante.
Jeff Yates,

1

È questo che vuoi:

Assembly.GetExecutingAssembly ().Location

4
Attenzione a GetExecutingAssembly (): se lo si chiama da un assembly della libreria, restituisce il nome dell'assembly della libreria, che è diverso dal nome dell'assembly della voce (ovvero l'eseguibile originale). Se si utilizza GetEntryAssembly (), restituisce il nome dell'eseguibile effettivo, ma genera un'eccezione se il processo è in esecuzione in WCF (è vero che una situazione rara). Per il codice più affidabile, utilizzare Process.GetCurrentProcess (). ProcessName.
Contango,

Una risposta non dovrebbe essere una domanda. È quello che voleva l'OP?
jwdonahue,

1

Su .Net Core (o Mono), la maggior parte delle risposte non si applicherà quando il binario che definisce il processo è il binario di runtime di Mono o .Net Core (dotnet) e non la tua vera applicazione. In quel caso , Usa questo:

var myName = Path.GetFileNameWithoutExtension(System.Reflection.Assembly.GetEntryAssembly().Location);

1
GetEntryAssembly()può restituire null.
user2864740

1

Per le app di Windows (moduli e console) uso questo:

Aggiungi un riferimento a System.Windows.Forms in VS quindi:

using System.Windows.Forms;
namespace whatever
{
    class Program
    {
        static string ApplicationName = Application.ProductName.ToString();
        static void Main(string[] args)
        {
            ........
        }
    }
}

Questo funziona correttamente per me se sto eseguendo il vero eseguibile o il debug all'interno di VS.

Si noti che restituisce il nome dell'applicazione senza l'estensione.

John


1

Super facile, qui:

Environment.CurrentDirectory + "\\" + Process.GetCurrentProcess().ProcessName

1
Per .NET Core Process.GetCurrentProcess (). ProcessName restituisce "dotnet".
Evgeni Nabokov,

1
La directory corrente è temporanea e non può essere considerata la posizione dell'assembly / eseguibile.
jwdonahue,

1

Funziona se hai bisogno solo del nome dell'applicazione senza estensione:

Path.GetFileNameWithoutExtension(AppDomain.CurrentDomain.FriendlyName);

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.