Comment obtenir le nom de l'exécutable actuel en C #?


356

Je veux obtenir le nom du programme en cours d'exécution, c'est-à-dire le nom exécutable du programme. En C / C ++, vous l'obtenez args[0].


L'exécutable est un fichier EXE (Windows Forms, applications WPF)? Un programme peut être une application de bureau (WinForms, WPF et WinRT-Windows Phone?), Une application Web, une application de service Wcf, Visual Studio Addin, Outlook-Word Addin, Unit Test in VS (MSTest) ou Silverlight Application.
Kiquenet

Réponses:


406
System.AppDomain.CurrentDomain.FriendlyName

61
Méfiez-vous des réponses acceptées. Nous avons eu des problèmes avec l'utilisation des System.AppDomain.CurrentDomain.FriendlyNameapplications déployées sous Click-Once. Pour nous, cela renvoie " DefaultDomain ", et non le nom exe d'origine.
Gaspode

40
Nous l'avons utilisé à la fin:string file = object_of_type_in_application_assembly.GetType().Assembly.Location; string app = System.IO.Path.GetFileNameWithoutExtension( file );
Gaspode

4
FriendlyName peut être défini sur n'importe quoi. Obtenir l'emplacement de l'assembly peut également ne pas être suffisant si vous avez un exe avec plusieurs DLL. De plus, si vous utilisez plusieurs AppDomain, Assembly.GetCallingAssembly () renvoie null.
user276648

2
@Gaspode: il serait plus facile de simplement dire Path.GetFileNameWithoutExtension (GetType (). Assembly.Location) - vous n'avez pas besoin de spécifier un objet d'un type dans l'assembly actuel. Vous pouvez utiliser GetType de ceci, puis vous n'avez même pas besoin de dire "ceci".
vbullinger

4
Cela peut être utile, mais ce ne devrait pas être la réponse acceptée: c'est très différent de ce qui a été demandé - ce sera par hasard la même chose dans certaines situations, mais c'est autre chose. Si vous n'avez pas écrit l'application vous-même, cela pourrait très bien retourner "J'aime les pommes de terre!" ou tout ce que votre collègue humoristique a écrit dans cette propriété lors de la création de l'application!
AnorZaken

237

System.AppDomain.CurrentDomain.FriendlyName - Renvoie le nom de fichier avec l'extension (par exemple MyApp.exe).

System.Diagnostics.Process.GetCurrentProcess().ProcessName- Renvoie le nom de fichier sans extension (par exemple MyApp).

System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName- Renvoie le chemin d'accès complet et le nom du fichier (par exemple C: \ Examples \ Processes \ MyApp.exe). Vous pouvez ensuite le passer dans System.IO.Path.GetFileName()ou System.IO.Path.GetFileNameWithoutExtension()pour obtenir les mêmes résultats que ci-dessus.


3
AppDomain peut être une application EXE, une application Web, une application de test unitaire, Addin Visual Studio et "Silverlight App" (?). Peut-être une solution complète intéressante pour tous les cas. Par exemple, pour le test unitaire VS2012 - ProcessName: vstest.executionengine.x86 MainModule.FileName: C: \ PROGRAM FILES (X86) \ MICROSOFT VISUAL STUDIO 11.0 \ COMMON7 \ IDE \ COMMONEXTENSIONS \ MICROSOFT \ TESTWINDOW \ vstest.executionengine.x86.exe MainModule.ModuleName: vstest.executionengine.x86.exe FriendlyName: UnitTestAdapter: Exécution du test ApplicationName:
Kiquenet

Un «programme» peut être une application de bureau (WinForms, WPF et WinRT-Windows Phone?), Une application Web, une application de service Wcf, Visual Studio Addin, Outlook-Word Addin, Unit Test in VS (MSTest) ou Silverlight Application . Par exemple, comment obtenir l'assembly d'hôte de service pour une application de service Wcf hébergée dans IIS, pas IISExpress ou WebDevServer?
Kiquenet

6
+1 Je vais aller avec cette réponse car elle fournit les trois variantes dont vous pourriez avoir besoin d'une manière propre et simple. L'utilisation du nom de programme nu sans chemin ni extension est très utile pour le texte d'aide dans le programme ( /?commutateur), car l'utilisation de l'extension et du chemin l'encombrent inutilement.
Synetech

2
N'oubliez pas de disposer du résultat deGetCurrentProcess()
Mahmoud Al-Qudsi

Process.GetCurrentProcess().ProcessName()renvoie MyApp.vshost pour moi.
Jonathan Wood

106

System.Diagnostics.Process.GetCurrentProcess()obtient le processus en cours d'exécution. Vous pouvez utiliser la ProcessNamepropriété pour déterminer le nom. Voici un exemple d'application console.

using System;
using System.Diagnostics;

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

36
Mieux utiliser Process.GetCurrentProcess (). MainModule.FileName
KindDragon

Process.GetCurrentProcess (). MainModule.FileName fonctionne parfaitement à partir d'un complément Excel (ExcelDNA)
earcam

10
Cette approche échouera lorsqu'elle sera utilisée sur le runtime Mono; le nom du processus pour les applications fonctionnant sur Mono sera toujours une variante de .../bin/monosur * nixes ou .../mono.exesur Windows.
cdhowie

1
Ce devrait être la réponse acceptée. Le nom actuel du domaine d'application peut ne rien avoir à voir avec le nom du processus exécutable, en particulier lorsque plusieurs domaines d'application sont présents
Ivan Krivyakov

Cette méthode peut être beaucoup plus lente que de jouer avec la classe Assembly.
Erwin Mayer

99

Cela devrait suffire:

Environment.GetCommandLineArgs()[0];

3
Hmm, cela retourne (lorsqu'il est exécuté à partir de vsnet et en utilisant la fonctionnalité d'hébergement de débogage), l'emplacement et le nom du nom de fichier.vshost.exe ... qui est en effet le fichier qui s'exécute en ce moment)
Frederik Gheysels

13
C'est la meilleure réponse pour moi car Environment.GetCommandLineArgs()c'est l'analogue C # exact argvde C / C ++.
Frederick The Fool

D'accord! meilleure réponse. J'ai besoin d'obtenir Environment.GetCommandLineArgs () [1];
Jerry Liang

1
Pour éviter le chemin complet:Path.GetFileNameWithoutExtension(Environment.GetCommandLineArgs()[0])
Nathan

1
Cela fonctionne bien lorsque vous essayez de retrouver les services WCF. Le nom du processus revient avec iisexpress dans mon cas. Mais cette commande me donne le nom réel de l'assembly du service WCF.
P.Brian.Mackey

19

Voici le code qui a fonctionné pour moi:

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

Tous les exemples ci-dessus m'ont donné le processName avec vshost ou le nom de la DLL en cours d'exécution.


4
Pour ceux qui ne le savent pas ou l'ont manqué dans d'autres réponses, l'espace de noms pour Assembly est System.Reflection et l'espace de noms pour Path est System.IO.
fusionner le

4
GetEntryAssembly retournera null si le point d'entrée de l'application est en code natif plutôt qu'en assembly.
Emdot

18

Essaye ça:

System.Reflection.Assembly.GetExecutingAssembly()

Cela vous renvoie une System.Reflection.Assemblyinstance qui contient toutes les données que vous pourriez souhaiter connaître sur l'application actuelle. Je pense que la Locationpropriété pourrait obtenir ce que vous recherchez spécifiquement.


6
Il peut être plus sûr à utiliser CodeBaseau lieu de Locationdans le cas où la fonctionnalité de cliché instantané de .NET est active. Voir blogs.msdn.com/suzcook/archive/2003/06/26/…
Dirk Vollmar

18
Méfiez-vous de GetExecutingAssembly (): si vous appelez cela à partir d'un assembly de bibliothèque, il renvoie le nom de l'assembly de bibliothèque, qui est différent du nom de l'assembly d'entrée (c'est-à-dire l'exécutable d'origine). Si vous utilisez GetEntryAssembly (), il renvoie le nom de l'exécutable réel, mais il lève une exception si le processus s'exécute sous WCF (certes, une situation rare). Pour le code le plus robuste, utilisez Process.GetCurrentProcess (). ProcessName.
Contango

@Gravitas: Certainement pas, tout exécutable qui exécute "interprété", par exemple avec / usr / bin / mono aura le mauvais nom de processus. ProcessName ne fonctionnera pas non plus avec les services Windows. Si vous l'utilisez dans une bibliothèque, utilisez GetCallingAssembly.
Stefan Steiger

1
A travaillé pour moi. La propriété Name de l'appel GetName () d'instance d'assembly retourné est ce dont vous avez besoin et n'inclut pas la partie ".exe". Également testé sur Mono / Linux avec le résultat attendu. Assembly.GetName (). Name
Hatoru Hansou

1
Hmm, notez que la chaîne retournée ne changera pas même si vous renommez le fichier exécutable à la main à l'aide de l'explorateur de fichiers. Alors que Environment.GetCommandLineArgs () [0] change avec le nom de fichier exécutable réel (bien sûr). Par coïncidence, la deuxième méthode s'est avérée meilleure pour ma situation spécifique car je veux que le dossier de données soit nommé en tant que nom de fichier exécutable réel.
Hatoru Hansou

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

vous donnera FileName de votre application comme; "MyApplication.exe"


11

Pourquoi personne n'a suggéré cela, c'est simple.

Path.GetFileName(Application.ExecutablePath)

3
Dans quel espace de noms l'application réside-t-elle?
Jeetendra

6
Ceci est utile lorsque vous
êtes

@NineBerry Vous pourriez être intéressé par Application.ExecutablePathle code source de .
Spooky

@NineBerry Voir mon message. Cela fonctionne dans les applications console si vous ajoutez une référence à System.Windows.Forms.
John


9

Si vous avez besoin du nom du programme pour configurer une règle de pare-feu, utilisez:

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

Cela garantira que le nom est correct lors du débogage dans VisualStudio et lors de l'exécution de l'application directement dans Windows.


2
Pour mes besoins (création d'un nom de fichier de journalisation), c'est la meilleure réponse. Si vous exécutez un processus hébergé (par exemple, un service ou une application Web), System.AppDomain.CurrentDomain.FriendlyName peut renvoyer un nom GUID-y laid avec des barres obliques intégrées.
Curt

8

En cas d'incertitude ou de doute, courez en rond, criez et criez.

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

Je ne peux pas prétendre avoir testé chaque option, mais cela ne fait rien de stupide comme retourner le vhost pendant les sessions de débogage.


2
+1 pour l'amusement. :-) Je n'utiliserais guère ce code, à moins que j'écrive une bibliothèque vraiment générique qui n'a aucune idée de son environnement (et alors ce ne serait probablement pas une bonne idée de maintenir quel que soit l'état global que vous alliez utiliser le nom de).
Andrey Tarantsov

@Orwellophile Un "programme" peut être une application de bureau (WinForms, WPF et WinRT-Windows Phone?), Une application Web, une application de service Wcf, Visual Studio Addin, Outlook-Word Addin, Unit Test in VS (MSTest), ou, Application Silverlight. Par exemple, comment obtenir l'assembly d'hôte de service pour une application de service Wcf hébergée dans IIS, pas IISExpress ou WebDevServer? Tout code complet valide pour A WinForms, WPF, application Web, application de service Wcf, complément Visual Studio, complément Outlook-Word, test unitaire dans les applications VS (MSTest)?
Kiquenet

8
  • System.Reflection.Assembly.GetEntryAssembly().Location renvoie l'emplacement du nom exe si l'assembly n'est pas chargé à partir de la mémoire.
  • System.Reflection.Assembly.GetEntryAssembly().CodeBase renvoie l'emplacement comme URL.

Testé, cela fonctionne à 100%, même s'il est appelé depuis une bibliothèque C #.
Contango

1
GetEntryAssembly () renvoie null si vous n'êtes pas dans l'AppDomain principal.
user276648

4

SI vous recherchez les informations de chemin complet de votre exécutable, le moyen fiable de le faire est d'utiliser les éléments suivants:

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

Cela élimine tous les problèmes avec les DLL intermédiaires, vshost, etc.


J'ai essayé votre méthode fiable dans Ubuntu Linux 15.10 C ++ en utilisant realpath suivi du remplacement de chaîne STL C ++ et cela a provoqué l'échec de Point and Click. Cela aurait-il pu être causé par un bug en mono comme notre directeur des logiciels le supposait aujourd'hui? Merci.
Frank

Je ne programme pas sur Mono, même si ça peut être amusant d'essayer
theMayer

Gasponde a écrit ci-dessus que «nous avons eu des problèmes avec System.AppDomain.CurrentDomain.FriendlyName sous les applications déployées Click-Once». Pourriez-vous deviner quels pourraient être les problèmes avec les applications déployées Click-Once dans .NET? Merci.
Frank

Renvoie C: \ Program Files \ dotnet \ dotnet.exe pour mon exemple de programme dans VS2017.
jwdonahue

3

Vous pouvez utiliser Environment.GetCommandLineArgs()pour obtenir les arguments et Environment.CommandLinepour obtenir la ligne de commande réelle telle qu'elle est entrée.

Vous pouvez également utiliser Assembly.GetEntryAssembly()ou Process.GetCurrentProcess().

Cependant, lors du débogage, vous devez être prudent car cet exemple final peut donner le nom de l'exécutable de votre débogueur (selon la façon dont vous attachez le débogueur) plutôt que votre exécutable, comme le peuvent les autres exemples.


4
Méfiez-vous de GetExecutingAssembly (): si vous appelez cela à partir d'un assembly de bibliothèque, il renvoie le nom de l'assembly de bibliothèque, qui est différent du nom de l'assembly d'entrée (c'est-à-dire l'exécutable d'origine). Si vous utilisez GetEntryAssembly (), il renvoie le nom de l'exécutable réel, mais il lève une exception si le processus s'exécute sous WCF (certes, une situation rare). Pour le code le plus robuste, utilisez Process.GetCurrentProcess (). ProcessName.
Contango

@Gravitas: bon point - wow, ça fait un moment que je n'ai pas écrit ça! : D je vais modifier en conséquence
Jeff Yates

Environment.CommandLinedonne le chemin absolu, pas la ligne de commande entrée, au moins sur Mono / Linux.
mécanique

@Mechanicalsnail: On dirait que Mono ne suit pas tout à fait la documentation. Intéressant.
Jeff Yates

1

C'est ce que tu veux:

Assembly.GetExecutingAssembly ().Location

4
Méfiez-vous de GetExecutingAssembly (): si vous appelez cela à partir d'un assembly de bibliothèque, il renvoie le nom de l'assembly de bibliothèque, qui est différent du nom de l'assembly d'entrée (c'est-à-dire l'exécutable d'origine). Si vous utilisez GetEntryAssembly (), il renvoie le nom de l'exécutable réel, mais il lève une exception si le processus s'exécute sous WCF (certes, une situation rare). Pour le code le plus robuste, utilisez Process.GetCurrentProcess (). ProcessName.
Contango

Une réponse ne devrait pas être une question. Est-ce ce que le PO voulait?
jwdonahue

1

Sur .Net Core (ou Mono), la plupart des réponses ne s'appliquent pas lorsque le binaire définissant le processus est le binaire d'exécution de Mono ou .Net Core (dotnet) et non votre application réelle qui vous intéresse. Dans ce cas , utilisez ceci:

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

1
GetEntryAssembly()peut retourner null.
user2864740

1

Pour les applications Windows (formulaires et console), j'utilise ceci:

Ajoutez une référence à System.Windows.Forms dans VS puis:

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

Cela fonctionne correctement pour moi, que j'exécute l'exécutable réel ou que je débogue dans VS.

Notez qu'il renvoie le nom de l'application sans l'extension.

John


1

Super facile, ici:

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

1
Pour .NET Core Process.GetCurrentProcess (). ProcessName renvoie "dotnet".
Evgeni Nabokov

1
Le répertoire courant est temporairement transitoire et ne peut pas être invoqué pour l'emplacement de l'assembly / exécutable.
jwdonahue

1

Cela fonctionne si vous n'avez besoin que du nom de l'application sans extension:

Path.GetFileNameWithoutExtension(AppDomain.CurrentDomain.FriendlyName);

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.