Wie erhalte ich den Namen der aktuellen ausführbaren Datei in C #?

355

Ich möchte den Namen des aktuell ausgeführten Programms erhalten, dh den ausführbaren Namen des Programms. In C / C ++ erhalten Sie es von args[0].

Joakim
quelle
Ausführbar ist EXE-Datei (Windows Forms, WPF-Anwendungen)? Ein Programm kann eine Desktop-App (WinForms, WPF und WinRT-Windows Phone?), Eine Webanwendung, eine Wcf-Dienstanwendung, ein Visual Studio-Add-In, ein Outlook-Word-Add-In, ein Komponententest in VS (MSTest) oder eine Silverlight-Anwendung sein.
Kiquenet

Antworten:

405
System.AppDomain.CurrentDomain.FriendlyName
Steven A. Lowe
quelle
61
Hüten Sie sich vor akzeptierten Antworten. Wir hatten Probleme bei der Verwendung von System.AppDomain.CurrentDomain.FriendlyNameunter Click-Once bereitgestellten Anwendungen. Für uns gibt dies " DefaultDomain " zurück und nicht den ursprünglichen Exe-Namen.
Gaspode
40
Wir haben dies am Ende verwendet:string file = object_of_type_in_application_assembly.GetType().Assembly.Location; string app = System.IO.Path.GetFileNameWithoutExtension( file );
Gaspode
4
FriendlyName kann auf alles gesetzt werden. Auch das Abrufen des Assembly-Speicherorts reicht möglicherweise nicht aus, wenn Sie eine Exe mit mehreren DLLs haben. Wenn Sie mehrere AppDomain verwenden, gibt Assembly.GetCallingAssembly () außerdem null zurück.
user276648
2
@Gaspode: Es wäre einfacher, nur Path.GetFileNameWithoutExtension (GetType (). Assembly.Location) zu sagen - Sie müssen in der aktuellen Assembly kein Objekt eines Typs angeben. Sie können GetType verwenden, und dann müssen Sie nicht einmal "dies" sagen.
Vbullinger
4
Dies kann nützlich sein, sollte aber nicht die akzeptierte Antwort sein: Es unterscheidet sich stark von dem, wonach gefragt wurde - es wird in einigen Situationen zufällig dasselbe sein , aber dies ist etwas ganz anderes. Wenn Sie die Bewerbung nicht selbst geschrieben haben, könnte sie sehr gut "Ich mag Kartoffeln!" Zurückgeben. oder was auch immer Ihr humorvoller Kollege in diese Eigenschaft geschrieben hat, als er die Anwendung erstellt hat!
AnorZaken
237

System.AppDomain.CurrentDomain.FriendlyName - Gibt den Dateinamen mit der Erweiterung zurück (z. B. MyApp.exe).

System.Diagnostics.Process.GetCurrentProcess().ProcessName- Gibt den Dateinamen ohne Erweiterung zurück (z. B. MyApp).

System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName- Gibt den vollständigen Pfad und den Dateinamen zurück (z. B. C: \ Examples \ Processes \ MyApp.exe). Sie können dies dann an System.IO.Path.GetFileName()oder weitergeben System.IO.Path.GetFileNameWithoutExtension(), um die gleichen Ergebnisse wie oben zu erzielen.

Lee Grissom
quelle
3
AppDomain kann eine EXE-Anwendung, eine Webanwendung, eine Unit-Test-Anwendung, Addin Visual Studio und "Silverlight App" (?) Sein. Vielleicht interessante Volllösung für alle Fälle. Beispiel: Für Unit Test VS2012 - ProcessName: vstest.executionengine.x86 MainModule.FileName: C: \ PROGRAMMDATEIEN (X86) \ MICROSOFT VISUAL STUDIO 11.0 \ COMMON7 \ IDE \ COMMONEXTENSIONS \ MICROSOFT \ TESTWIND MainModule.ModuleName: vstest.executionengine.x86.exe FriendlyName: UnitTestAdapter: Test
ausführen
Ein "Programm" kann eine Desktop-App (WinForms, WPF; und WinRT-Windows Phone?), Eine Webanwendung, eine Wcf-Dienstanwendung, ein Visual Studio-Add-In, ein Outlook-Word-Add-In, ein Komponententest in VS (MSTest) oder eine Silverlight-Anwendung sein . Wie wird beispielsweise die Service-Host-Assembly für eine in IIS gehostete Wcf-Service-Anwendung abgerufen, nicht für IISExpress oder WebDevServer?
Kiquenet
6
+1 Ich werde mit dieser Antwort fortfahren, da sie alle drei Variationen enthält, die Sie möglicherweise auf saubere und einfache Weise benötigen. Die Verwendung des bloßen Programmnamens ohne Pfad oder Erweiterung ist sehr nützlich für programminternen Hilfetext ( /?Schalter), da die Verwendung der Erweiterung und des Pfads ihn nur unnötig überladen.
Synetech
2
Denken Sie daran, das Ergebnis vonGetCurrentProcess()
Mahmoud Al-Qudsi
Process.GetCurrentProcess().ProcessName()gibt MyApp.vshost für mich zurück.
Jonathan Wood
106

System.Diagnostics.Process.GetCurrentProcess()Ruft den aktuell ausgeführten Prozess ab. Sie können die ProcessNameEigenschaft verwenden, um den Namen herauszufinden. Unten finden Sie eine Beispiel-Konsolen-App.

using System;
using System.Diagnostics;

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(Process.GetCurrentProcess().ProcessName);
        Console.ReadLine();
    }
}
Aaron Daniels
quelle
36
Verwenden Sie besser Process.GetCurrentProcess (). MainModule.FileName
KindDragon
Process.GetCurrentProcess (). MainModule.FileName funktioniert perfekt in einem Excel Addin (ExcelDNA)
earcam
10
Dieser Ansatz schlägt fehl, wenn er zur Mono-Laufzeit verwendet wird. Der Prozessname für Anwendungen, die unter Mono ausgeführt werden, ist immer eine Variante von .../bin/monoon * nixes oder .../mono.exeWindows.
CDhowie
1
Dies sollte die akzeptierte Antwort sein. Der aktuelle AppDomain-Name hat möglicherweise nichts mit dem Namen des ausführbaren Prozesses zu tun, insbesondere wenn mehrere App-Domänen vorhanden sind
Ivan Krivyakov
Diese Methode kann wesentlich langsamer sein als das Spielen mit der Assembly-Klasse.
Erwin Mayer
99

Dies sollte ausreichen:

Environment.GetCommandLineArgs()[0];
James B.
quelle
3
Hmm, dies gibt (wenn es von vs.net ausgeführt wird und das Debug-Hosting-Ding verwendet) den Speicherort und den Namen der Dateiname.vshost.exe zurück ... das ist tatsächlich die Datei, die zu diesem Zeitpunkt ausgeführt wird)
Frederik Gheysels
13
Dies ist die beste Antwort für mich, da Environment.GetCommandLineArgs()es sich um das genaue C # -Analogon argvvon C / C ++ handelt.
Frederick The Fool
Einverstanden! beste Antwort. Ich muss Environment.GetCommandLineArgs () [1] abrufen.
Jerry Liang
1
Um den vollen Weg zu vermeiden:Path.GetFileNameWithoutExtension(Environment.GetCommandLineArgs()[0])
Nathan
1
Dies funktioniert gut, wenn versucht wird, WCF-Dienste aufzuspüren. Der Prozessname kommt in meinem Fall mit iisexpress zurück. Dieser Befehl gibt mir jedoch den tatsächlichen Namen der WCF-Dienstassembly.
P.Brian.Mackey
19

Dies ist der Code, der für mich funktioniert hat:

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

Alle obigen Beispiele gaben mir den Prozessnamen mit vshost oder den Namen der laufenden DLL.

Tal Segal
quelle
4
Für diejenigen, die es nicht wissen oder in anderen Antworten verpasst haben, lautet der Namespace für Assembly System.Reflection und der Namespace für Path System.IO.
Amalgamat
4
GetEntryAssembly gibt null zurück, wenn sich der Anwendungseinstiegspunkt im nativen Code und nicht in einer Assembly befindet.
Emdot
18

Versuche dies:

System.Reflection.Assembly.GetExecutingAssembly()

Dadurch erhalten Sie eine System.Reflection.AssemblyInstanz mit allen Daten, die Sie jemals über die aktuelle Anwendung wissen möchten. Ich denke, dass die LocationImmobilie genau das bekommen könnte, wonach Sie suchen.

Andrew Hare
quelle
6
Die Verwendung ist möglicherweise sicherer als für den Fall, dass die Schattenkopierfunktion CodeBasevon Location.NET aktiv ist. Siehe blogs.msdn.com/suzcook/archive/2003/06/26/…
Dirk Vollmar
18
Vorsicht vor GetExecutingAssembly (): Wenn Sie dies von einer Bibliotheksassembly aus aufrufen, wird der Name der Bibliotheksassembly zurückgegeben, der sich vom Namen der Eintragsassembly (dh der ursprünglichen ausführbaren Datei) unterscheidet. Wenn Sie GetEntryAssembly () verwenden, wird der Name der tatsächlich ausführbaren Datei zurückgegeben, es wird jedoch eine Ausnahme ausgelöst, wenn der Prozess unter WCF ausgeführt wird (zugegebenermaßen eine seltene Situation). Verwenden Sie für den robustesten Code Process.GetCurrentProcess (). ProcessName.
Contango
@Gravitas: Sicherlich nicht, jede ausführbare Datei, die "interpretiert" ausgeführt wird, z. B. mit / usr / bin / mono, hat den falschen Prozessnamen. Auch ProcessName funktioniert nicht mit Windows-Diensten. Wenn Sie es in einer Bibliothek verwenden, verwenden Sie GetCallingAssembly.
Stefan Steiger
1
Hat für mich gearbeitet. Die Eigenschaft Name des zurückgegebenen GetName () -Aufrufs der Assembly-Instanz ist genau das, was Sie benötigen, und enthält nicht den Teil ".exe". Auch unter Mono / Linux mit erwartetem Ergebnis getestet. Assembly.GetName (). Name
Hatoru Hansou
1
Hmm, beachten Sie, dass sich die zurückgegebene Zeichenfolge auch dann nicht ändert, wenn Sie die ausführbare Datei mit dem Datei-Explorer manuell umbenennen. Während sich Environment.GetCommandLineArgs () [0] zusammen mit dem tatsächlichen ausführbaren Dateinamen ändert (natürlich). Zufälligerweise war die zweite Methode für meine spezielle Situation besser geeignet, da der Datenordner als tatsächlicher ausführbarer Dateiname benannt werden soll.
Hatoru Hansou
11
System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name;

gibt Ihnen den Dateinamen Ihrer App wie; "MyApplication.exe"

Teoman Shipahi
quelle
11

Warum niemand dies vorgeschlagen hat, ist einfach.

Path.GetFileName(Application.ExecutablePath)
xmen
quelle
3
In welchem ​​Namespace befindet sich die Anwendung?
Jeetendra
6
Dies ist nützlich, wenn Sie sich in einer Windows Forms-App befinden, aber nicht anders
NineBerry
@NineBerry Sie könnte dich interessieren Application.ExecutablePath‚s - Quellcode .
Spooky
@ NineBerry Siehe meinen Beitrag. Dies funktioniert in Konsolen-Apps, wenn Sie einen Verweis auf System.Windows.Forms hinzufügen.
John
10

Paar mehr Optionen:

  • System.Reflection.Assembly.GetExecutingAssembly().GetName().Name
  • Path.GetFileName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase
JohnB
quelle
9

Wenn Sie den Programmnamen zum Einrichten einer Firewall-Regel benötigen, verwenden Sie:

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

Dadurch wird sichergestellt, dass der Name sowohl beim Debuggen in VisualStudio als auch beim direkten Ausführen der App in Windows korrekt ist.

Mark Uebel
quelle
2
Für meine Zwecke (Erstellen eines Protokolldateinamens) ist dies die beste Antwort. Wenn ein gehosteter Prozess (z. B. ein Dienst oder eine Webanwendung) ausgeführt wird, kann System.AppDomain.CurrentDomain.FriendlyName einen hässlichen GUID-y-Namen mit eingebetteten Schrägstrichen zurückgeben.
Curt
8

Wenn Sie unsicher sind oder Zweifel haben, laufen Sie im Kreis, schreien und schreien Sie.

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

Ich kann nicht behaupten, jede Option getestet zu haben, aber es macht nichts Dummes, als den vhost während der Debugging-Sitzungen zurückzugeben.

Orwellophil
quelle
2
+1 zur Unterhaltung. :-) Ich würde diesen Code jedoch kaum verwenden, es sei denn, ich schreibe eine wirklich generische Bibliothek, die keine Ahnung von ihrer Umgebung hat (und dann wäre es wahrscheinlich keine gute Idee, den globalen Status beizubehalten, den Sie verwenden würden der Name für).
Andrey Tarantsov
@Orwellophile Ein "Programm" kann eine Desktop-App (WinForms, WPF; und WinRT-Windows Phone?), Eine Webanwendung, eine Wcf-Dienstanwendung, ein Visual Studio-Add-In, ein Outlook-Word-Add-In, ein Komponententest in VS (MSTest) oder Silverlight-Anwendung. Wie wird beispielsweise die Service-Host-Assembly für eine in IIS gehostete Wcf-Service-Anwendung abgerufen, nicht für IISExpress oder WebDevServer? Gibt es einen vollständigen Code, der für A WinForms, WPF, Webanwendung, Wcf-Dienstanwendung, Visual Studio-Add-In, Outlook-Word-Add-In und Unit-Test in VS-Anwendungen (MSTest) gültig ist?
Kiquenet
8
  • System.Reflection.Assembly.GetEntryAssembly().Location Gibt den Speicherort des Exe-Namens zurück, wenn die Assembly nicht aus dem Speicher geladen wurde.
  • System.Reflection.Assembly.GetEntryAssembly().CodeBase Gibt den Speicherort als URL zurück.
langpavel
quelle
Getestet funktioniert dies zu 100%, auch wenn es aus einer C # -Bibliothek heraus aufgerufen wird.
Contango
1
GetEntryAssembly () gibt null zurück, wenn Sie sich nicht in der Haupt-AppDomain befinden.
user276648
4

Wenn Sie nach den vollständigen Pfadinformationen Ihrer ausführbaren Datei suchen, können Sie dies wie folgt zuverlässig tun:

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

Dadurch werden Probleme mit zwischengeschalteten DLLs, vshost usw. beseitigt.

theMayer
quelle
Ich habe Ihren zuverlässigen Weg in Ubuntu Linux 15.10 C ++ mit realpath gefolgt von STL C ++ - String-Ersetzung ausprobiert und es hat dazu geführt, dass Point and Click fehlgeschlagen ist. Könnte dies durch einen Fehler in Mono verursacht worden sein, wie unser Software-Direktor heute vermutete? Vielen Dank.
Frank
Ich programmiere nicht auf Mono, obwohl es vielleicht Spaß macht, es zu versuchen
theMayer
Gasponde schrieb oben: "Wir hatten Probleme mit der Verwendung von System.AppDomain.CurrentDomain.FriendlyName unter Click-Once-bereitgestellten Anwendungen." Können Sie sich vorstellen, welche Probleme mit Click-Once-Anwendungen in .NET auftreten können? Vielen Dank.
Frank
Gibt C: \ Programme \ dotnet \ dotnet.exe für mein Beispielprogramm in VS2017 zurück.
Jwdonahue
3

Sie können verwenden Environment.GetCommandLineArgs(), um die Argumente abzurufen und Environment.CommandLinedie tatsächliche Befehlszeile wie eingegeben abzurufen.

Sie können auch Assembly.GetEntryAssembly()oder verwenden Process.GetCurrentProcess().

Beim Debuggen sollten Sie jedoch vorsichtig sein, da dieses letzte Beispiel möglicherweise den Namen der ausführbaren Datei Ihres Debuggers (abhängig davon, wie Sie den Debugger anhängen) anstelle Ihrer ausführbaren Datei angibt, wie auch die anderen Beispiele.

Jeff Yates
quelle
4
Vorsicht vor GetExecutingAssembly (): Wenn Sie dies von einer Bibliotheksassembly aus aufrufen, wird der Name der Bibliotheksassembly zurückgegeben, der sich vom Namen der Eintragsassembly (dh der ursprünglichen ausführbaren Datei) unterscheidet. Wenn Sie GetEntryAssembly () verwenden, wird der Name der tatsächlich ausführbaren Datei zurückgegeben, es wird jedoch eine Ausnahme ausgelöst, wenn der Prozess unter WCF ausgeführt wird (zugegebenermaßen eine seltene Situation). Verwenden Sie für den robustesten Code Process.GetCurrentProcess (). ProcessName.
Contango
@ Gravitas: Guter Punkt - wow, es ist schon eine Weile her, seit ich das geschrieben habe! : D Ich werde entsprechend bearbeiten
Jeff Yates
Environment.CommandLinegibt den absoluten Pfad an, nicht die eingegebene Befehlszeile, zumindest unter Mono / Linux.
Mechanische Schnecke
@Mechanicalsnail: Klingt so, als ob Mono der Dokumentation nicht ganz folgt. Interessant.
Jeff Yates
1

Ist das was du willst:

Assembly.GetExecutingAssembly ().Location
Frederik Gheysels
quelle
4
Vorsicht vor GetExecutingAssembly (): Wenn Sie dies von einer Bibliotheksassembly aus aufrufen, wird der Name der Bibliotheksassembly zurückgegeben, der sich vom Namen der Eintragsassembly (dh der ursprünglichen ausführbaren Datei) unterscheidet. Wenn Sie GetEntryAssembly () verwenden, wird der Name der tatsächlich ausführbaren Datei zurückgegeben, es wird jedoch eine Ausnahme ausgelöst, wenn der Prozess unter WCF ausgeführt wird (zugegebenermaßen eine seltene Situation). Verwenden Sie für den robustesten Code Process.GetCurrentProcess (). ProcessName.
Contango
Eine Antwort sollte keine Frage sein. Wollte das OP das?
Jwdonahue
1

In .Net Core (oder Mono) gelten die meisten Antworten nicht, wenn die den Prozess definierende Binärdatei die Laufzeitbinärdatei von Mono oder .Net Core (Dotnet) ist und nicht Ihre eigentliche Anwendung, an der Sie interessiert sind. In diesem Fall , benutze das:

var myName = Path.GetFileNameWithoutExtension(System.Reflection.Assembly.GetEntryAssembly().Location);
Tobias
quelle
1
GetEntryAssembly()kann null zurückgeben.
user2864740
1

Für Windows-Apps (Formulare und Konsole) verwende ich Folgendes:

Fügen Sie dann einen Verweis auf System.Windows.Forms in VS hinzu:

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

Dies funktioniert für mich korrekt, unabhängig davon, ob ich die eigentliche ausführbare Datei ausführe oder in VS debugge.

Beachten Sie, dass der Anwendungsname ohne die Erweiterung zurückgegeben wird.

John

John
quelle
1

Super einfach hier:

Environment.CurrentDirectory + "\\" + Process.GetCurrentProcess().ProcessName
Wahnhafter Geist
quelle
1
Für .NET Core Process.GetCurrentProcess (). ProcessName gibt "dotnet" zurück.
Evgeni Nabokov
1
Das aktuelle Verzeichnis ist zeitlich vorübergehend und kann nicht als Speicherort der Assembly / ausführbaren Datei verwendet werden.
Jwdonahue
1

Dies funktioniert, wenn Sie nur den Anwendungsnamen ohne Erweiterung benötigen:

Path.GetFileNameWithoutExtension(AppDomain.CurrentDomain.FriendlyName);
RJN
quelle
-1

Um den Pfad und den Namen zu erhalten

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

Ewerton Dutra
quelle
Dies dupliziert diese Antwort und diese Antwort .
Speck