Jak uzyskać nazwę bieżącego pliku wykonywalnego w języku C #?


355

Chcę uzyskać nazwę aktualnie uruchomionego programu, czyli nazwę pliku wykonywalnego programu. W C / C ++ możesz to pobrać z args[0].


Plik wykonywalny to plik EXE (formularze Windows, aplikacje WPF)? Programem może być aplikacja komputerowa (WinForms, WPF; i WinRT-Windows Phone?), Aplikacja internetowa, aplikacja serwisowa Wcf, dodatek Visual Studio, dodatek Outlook-Word, test jednostkowy w VS (MSTest) lub aplikacja Silverlight.
Kiquenet

Odpowiedzi:


405
System.AppDomain.CurrentDomain.FriendlyName

61
Uważaj na zaakceptowaną odpowiedź. Wystąpiły problemy z używaniem aplikacji w System.AppDomain.CurrentDomain.FriendlyNameramach Click-Once. Dla nas jest to zwrot „ DefaultDomain ”, a nie oryginalna nazwa exe.
Gaspode,

40
Wykorzystaliśmy to w końcu:string file = object_of_type_in_application_assembly.GetType().Assembly.Location; string app = System.IO.Path.GetFileNameWithoutExtension( file );
Gaspode

4
FriendlyName można ustawić na dowolną wartość. Również uzyskanie miejsca montażu może nie wystarczyć, jeśli masz plik exe z kilkoma bibliotekami DLL. Ponadto, jeśli używasz kilku AppDomain, Assembly.GetCallingAssembly () zwraca null.
user276648

2
@Gaspode: łatwiej byłoby po prostu powiedzieć Path.GetFileNameWithoutExtension (GetType (). Assembly.Location) - nie trzeba określać obiektu typu w bieżącym zestawie. Możesz użyć GetType tego, a wtedy nawet nie musisz mówić „to”.
vbullinger

4
Może to być przydatne, ale to powinno nie być zaakceptowane odpowiedź: Jest znacznie różni się od tego, co został poproszony - będzie to przypadkiem być samo w niektórych sytuacjach, ale to jest coś zupełnie innego. Jeśli nie napisałeś aplikacji samodzielnie, może równie dobrze zwrócić „Lubię ziemniaki!” lub cokolwiek innego, co Twój humorystyczny kolega napisał w tej nieruchomości, gdy tworzył aplikację!
AnorZaken

237

System.AppDomain.CurrentDomain.FriendlyName - Zwraca nazwę pliku z rozszerzeniem (np. MyApp.exe).

System.Diagnostics.Process.GetCurrentProcess().ProcessName- Zwraca nazwę pliku bez rozszerzenia (np. MyApp).

System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName- Zwraca pełną ścieżkę i nazwę pliku (np. C: \ Examples \ Processes \ MyApp.exe). Następnie możesz przekazać to do System.IO.Path.GetFileName()lub System.IO.Path.GetFileNameWithoutExtension()osiągnąć takie same wyniki jak powyżej.


3
AppDomain może być aplikacją EXE, aplikacją internetową, aplikacją do testów jednostkowych, Addin Visual Studio i „Silverlight App” (?). Może interesujące pełne rozwiązanie dla wszystkich przypadków. Na przykład dla testu jednostkowego VS2012 - nazwa procesu: vstest.executionengine.x86 MainModule.FileName: C: \ PROGRAM FILES (X86) \ MICROSOFT VISUAL STUDIO 11.0 \ COMMON7 \ IDE \ COMMONEXTENSIONS \ MICROSOFT \ TESTWINDOW \ vstest.executionengine.x86 MainModule.ModuleName: vstest.executionengine.x86.exe FriendlyName: UnitTestAdapter: Uruchamianie testu
Nazwa

„Program” może być aplikacją komputerową (WinForms, WPF; i WinRT-Windows Phone?), Aplikacją internetową, aplikacją serwisową Wcf, dodatkiem Visual Studio, dodatkiem Outlook-Word, testem jednostkowym w VS (MSTest) lub aplikacją Silverlight . Na przykład, w jaki sposób uzyskać zestaw hosta usługi dla aplikacji usługi Wcf hostowanej w usługach IIS, a nie IISExpress lub WebDevServer?
Kiquenet

6
+1 Idę z tą odpowiedzią, ponieważ zawiera wszystkie trzy warianty, których możesz potrzebować w czysty i prosty sposób. Używanie nagiej nazwy programu bez ścieżki lub rozszerzenia jest bardzo przydatne w tekście pomocy w programie ( /?przełącznik), ponieważ użycie rozszerzenia i ścieżki po prostu niepotrzebnie go zaśmieca.
Synetech,

2
Pamiętaj, aby zutylizować wynikGetCurrentProcess()
Mahmouda Al-Qudsi

Process.GetCurrentProcess().ProcessName()zwraca MyApp.vshost dla mnie.
Jonathan Wood

106

System.Diagnostics.Process.GetCurrentProcess()pobiera aktualnie uruchomiony proces. Możesz użyć ProcessNamewłaściwości, aby ustalić nazwę. Poniżej znajduje się przykładowa aplikacja na konsolę.

using System;
using System.Diagnostics;

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

36
Lepsze wykorzystanie Process.GetCurrentProcess (). MainModule.FileName
KindDragon

Process.GetCurrentProcess (). MainModule.FileName działa idealnie z poziomu dodatku Excel (ExcelDNA)
kamera douszna

10
To podejście zawiedzie, gdy zostanie użyte w środowisku wykonawczym Mono; nazwa procesu dla aplikacji działających na Mono będzie zawsze odmianą .../bin/mono* nixes lub .../mono.exeWindows.
cdhowie

1
To powinna być zaakceptowana odpowiedź. Obecna nazwa domeny aplikacji może nie mieć nic wspólnego z nazwą wykonywalnego procesu, zwłaszcza gdy istnieje wiele domen aplikacji
Ivan Krivyakov

Ta metoda może być znacznie wolniejsza niż zabawa z klasą asemblera.
Erwin Mayer,

99

To powinno wystarczyć:

Environment.GetCommandLineArgs()[0];

3
Hmm, to zwraca (po uruchomieniu z vs.net i przy użyciu hostingu debugowania) lokalizację i nazwę pliku nazwa_pliku.vshost.exe ... to rzeczywiście plik, który jest obecnie wykonywany)
Frederik Gheysels

13
To najlepsza odpowiedź dla mnie, ponieważ Environment.GetCommandLineArgs()jest to dokładny analog C # argvz C / C ++.
Frederick The Fool

Zgoda! najlepsza odpowiedź. Mam potrzebę uzyskania Environment.GetCommandLineArgs () [1];
Jerry Liang

1
Aby uniknąć pełnej ścieżki:Path.GetFileNameWithoutExtension(Environment.GetCommandLineArgs()[0])
Nathan

1
Działa to dobrze, gdy próbujesz wyśledzić usługi WCF. W moim przypadku nazwa procesu wraca z iisexpress. Ale to polecenie podaje mi rzeczywistą nazwę zestawu usługi WCF.
P.Brian.Mackey

19

Oto kod, który działał dla mnie:

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

Wszystkie powyższe przykłady dały mi procesName z vshost lub działającą nazwą dll.


4
Dla tych, którzy nie znają go lub pomijali w innych odpowiedziach, przestrzenią nazw dla zestawu jest System.Reflection, a przestrzenią nazw ścieżki jest System.IO.
amalgamat

4
GetEntryAssembly zwróci null, jeśli punkt wejścia aplikacji znajduje się w kodzie natywnym, a nie w asemblerze.
Emdot,

18

Spróbuj tego:

System.Reflection.Assembly.GetExecutingAssembly()

Zwraca to System.Reflection.Assemblyinstancję, która zawiera wszystkie dane, które możesz chcieć wiedzieć o bieżącej aplikacji. Myślę, że Locationnieruchomość może dostać to, czego szukasz.


6
Korzystanie CodeBasez Locationfunkcji kopiowania w tle .NET może być bezpieczniejsze niż w przypadku. Zobacz blogs.msdn.com/suzcook/archive/2003/06/26/…
Dirk Vollmar

18
Uwaga na GetExecutingAssembly (): jeśli wywołasz to z zestawu bibliotecznego, zwróci on nazwę zestawu bibliotecznego, który różni się od nazwy zestawu wejściowego (tj. Oryginalnego pliku wykonywalnego). Jeśli użyjesz GetEntryAssembly (), zwróci nazwę rzeczywistego pliku wykonywalnego, ale zgłasza wyjątek, jeśli proces działa w WCF (co prawda rzadka sytuacja). Aby uzyskać najbardziej niezawodny kod, użyj Process.GetCurrentProcess (). ProcessName.
Contango,

@Gravitas: Z pewnością nie, każdy plik wykonywalny, który działa „zinterpretowany”, np. Z / usr / bin / mono, będzie miał niepoprawną nazwę procesu. ProcessName również nie będzie działać z usługami Windows. Jeśli używasz go w bibliotece, użyj GetCallingAssembly.
Stefan Steiger

1
Pracował dla mnie. Właściwość Nazwa zwróconego wywołania GetName () instancji zestawu jest tym, czego potrzebujesz i nie zawiera części „.exe”. Testowany również na Mono / Linux z oczekiwanym rezultatem. Assembly.GetName (). Name
Hatoru Hansou

1
Hmm, zauważ, że zwrócony ciąg nie zmieni się, nawet jeśli ręcznie zmienisz nazwę pliku wykonywalnego za pomocą eksploratora plików. Podczas gdy Environment.GetCommandLineArgs () [0] zmienia się wraz z rzeczywistym plikiem wykonywalnym (oczywiście). Przypadkowo druga metoda okazała się lepsza w mojej konkretnej sytuacji, ponieważ chcę, aby folder danych został nazwany rzeczywistą nazwą pliku wykonywalnego.
Hatoru Hansou

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

da ci FileName twojej aplikacji jak; „MyApplication.exe”


11

Dlaczego nikt tego nie zasugerował, to proste.

Path.GetFileName(Application.ExecutablePath)

3
Która przestrzeń nazw znajduje się w aplikacji?
Jeetendra,

6
Jest to przydatne, gdy znajduje się w aplikacji Windows Forms, ale nie inaczej
NineBerry 20.01.2016

@NineBerry Możesz być zainteresowany Application.ExecutablePath„s kodu źródłowego .
Spooky

@NineBerry Zobacz mój post. Działa to w aplikacjach konsoli, jeśli dodasz odwołanie do System.Windows.Forms.
John


9

Jeśli potrzebujesz nazwy programu do skonfigurowania reguły zapory, użyj:

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

Dzięki temu nazwa będzie poprawna zarówno podczas debugowania w VisualStudio, jak i podczas uruchamiania aplikacji bezpośrednio w systemie Windows.


2
Dla moich celów (tworzenie nazwy pliku dziennika) jest to najlepsza odpowiedź. Jeśli uruchomiony jest proces hostowany (np. Usługa lub aplikacja internetowa), System.AppDomain.CurrentDomain.FriendlyName może zwrócić brzydką nazwę GUID-y z osadzonymi ukośnikami.
Curt

8

W razie wątpliwości lub wątpliwości biegaj w kółko, krzycz i krzycz.

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

Nie mogę twierdzić, że przetestowałem każdą opcję, ale nie robi nic głupiego, jak zwracanie vhosta podczas sesji debugowania.


2
+1 za rozrywkę. :-) Jednak z trudem użyłbym tego kodu, chyba że piszę naprawdę ogólną bibliotekę, która nie ma pojęcia o swoim środowisku (a wtedy prawdopodobnie nie byłoby dobrym pomysłem utrzymanie dowolnego globalnego stanu, którego będziesz używać) nazwa).
Andriej Tarantow

@Orwellophile „Programem” może być aplikacja komputerowa (WinForms, WPF; i WinRT-Windows Phone?), Aplikacja internetowa, aplikacja serwisowa Wcf, dodatek Visual Studio, dodatek do programu Outlook-Word, test jednostkowy w VS (MSTest) lub Aplikacja Silverlight. Na przykład, w jaki sposób uzyskać zestaw hosta usługi dla aplikacji usługi Wcf hostowanej w usługach IIS, a nie IISExpress lub WebDevServer? Jakiś pełny kod ważny dla A WinForms, WPF, aplikacji sieci Web, aplikacji usługi Wcf, dodatku Visual Studio, dodatku Outlook-Word, testu jednostkowego w aplikacjach VS (MSTest)?
Kiquenet

8
  • System.Reflection.Assembly.GetEntryAssembly().Location zwraca lokalizację nazwy exe, jeśli zestaw nie jest ładowany z pamięci.
  • System.Reflection.Assembly.GetEntryAssembly().CodeBase zwraca lokalizację jako adres URL.

Testowane, działa to w 100%, nawet jeśli jest wywoływane z biblioteki C #.
Contango,

1
GetEntryAssembly () zwraca null, jeśli nie jesteś w głównej AppDomain.
user276648

4

JEŻELI szukasz pełnej informacji o ścieżce pliku wykonywalnego, niezawodnym sposobem na to jest skorzystanie z następujących opcji:

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

Eliminuje to wszelkie problemy z bibliotekami pośredniczącymi, vshost itp.


Wypróbowałem swój niezawodny sposób w Ubuntu Linux 15.10 C ++ przy użyciu realpath, a następnie zastąpiono ciąg znaków STL C ++, co spowodowało błąd Point and Click. Czy mogło to być spowodowane błędem w mono, jak dziś przypuszczał nasz dyrektor oprogramowania? Dzięki.
Frank

Nie programuję w Mono, choć może warto spróbować
May

Gasponde napisał powyżej, że „Mieliśmy problemy z używaniem System.AppDomain.CurrentDomain.FriendlyName w aplikacjach Click-Once”. Czy możesz zgadnąć, jakie mogą być problemy z aplikacjami Click-Once wdrożonymi w .NET? Dzięki.
Frank

Zwraca C: \ Program Files \ dotnet \ dotnet.exe dla mojego programu przykładowego w VS2017.
jwdonahue

3

Możesz użyć, Environment.GetCommandLineArgs()aby uzyskać argumenty i Environment.CommandLineuzyskać rzeczywistą linię poleceń, jak wprowadzono.

Możesz także użyć Assembly.GetEntryAssembly()lub Process.GetCurrentProcess().

Jednak podczas debugowania należy zachować ostrożność, ponieważ ten ostatni przykład może podawać nazwę pliku wykonywalnego debuggera (w zależności od sposobu podłączenia debugera) zamiast pliku wykonywalnego, podobnie jak inne przykłady.


4
Uwaga na GetExecutingAssembly (): jeśli wywołasz to z zestawu bibliotecznego, zwróci on nazwę zestawu bibliotecznego, który różni się od nazwy zestawu wejściowego (tj. Oryginalnego pliku wykonywalnego). Jeśli użyjesz GetEntryAssembly (), zwróci nazwę rzeczywistego pliku wykonywalnego, ale zgłasza wyjątek, jeśli proces działa w WCF (co prawda rzadka sytuacja). Aby uzyskać najbardziej niezawodny kod, użyj Process.GetCurrentProcess (). ProcessName.
Contango,

@Gravitas: dobra uwaga - wow, minęło trochę czasu odkąd to napisałem! : D Zmienię odpowiednio
Jeff Yates

Environment.CommandLinepodaje bezwzględną ścieżkę, a nie wprowadzony wiersz poleceń, przynajmniej w Mono / Linux.
Mechaniczny ślimak,

@Mechanicalsnail: Brzmi jak Mono niezupełnie zgodne z dokumentacją. Ciekawy.
Jeff Yates,

1

Czy to jest to, czego chcesz:

Assembly.GetExecutingAssembly ().Location

4
Uwaga na GetExecutingAssembly (): jeśli wywołasz to z zestawu bibliotecznego, zwróci on nazwę zestawu bibliotecznego, który różni się od nazwy zestawu wejściowego (tj. Oryginalnego pliku wykonywalnego). Jeśli użyjesz GetEntryAssembly (), zwróci nazwę rzeczywistego pliku wykonywalnego, ale zgłasza wyjątek, jeśli proces działa w WCF (co prawda rzadka sytuacja). Aby uzyskać najbardziej niezawodny kod, użyj Process.GetCurrentProcess (). ProcessName.
Contango,

Odpowiedź nie powinna być pytaniem. Czy tego właśnie chciał PO?
jwdonahue

1

W .Net Core (lub Mono) większość odpowiedzi nie będzie miała zastosowania, gdy plik binarny definiujący proces jest plikiem binarnym Mono lub .Net Core (dotnet), a nie rzeczywistą aplikacją, którą jesteś zainteresowany. W takim przypadku , Użyj tego:

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

1
GetEntryAssembly()może zwrócić null.
user2864740

1

W przypadku aplikacji Windows (formularze i konsola) używam tego:

Dodaj odwołanie do System.Windows.Forms w VS, a następnie:

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

Działa to dla mnie poprawnie, niezależnie od tego, czy uruchamiam plik wykonywalny, czy debuguję w VS.

Pamiętaj, że zwraca nazwę aplikacji bez rozszerzenia.

Jan


1

Super łatwe, tutaj:

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

1
Dla .NET Core Process.GetCurrentProcess (). ProcessName zwraca „dotnet”.
Evgeni Nabokov,

1
Bieżący katalog jest tymczasowo przejściowy i nie można na nim polegać jako lokalizacji zestawu / pliku wykonywalnego.
jwdonahue

1

Działa to, jeśli potrzebujesz tylko nazwy aplikacji bez rozszerzenia:

Path.GetFileNameWithoutExtension(AppDomain.CurrentDomain.FriendlyName);

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.