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].

Joakim
źródło
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
Steven A. Lowe
źródło
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.

Lee Grissom
źródło
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();
    }
}
Aaron Daniels
źródło
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];
James B.
źródło
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.

Tal Segal
źródło
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.

Andrew Hare
źródło
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”

Teoman Shipahi
źródło
11

Dlaczego nikt tego nie zasugerował, to proste.

Path.GetFileName(Application.ExecutablePath)
x Men
źródło
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
10

Kilka dodatkowych opcji:

  • System.Reflection.Assembly.GetExecutingAssembly().GetName().Name
  • Path.GetFileName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase
JohnB
źródło
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.

Mark Uebel
źródło
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.

Orwellophile
źródło
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.
Langpavel
źródło
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.

theMayer
źródło
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.

Jeff Yates
źródło
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
Frederik Gheysels
źródło
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);
Tobiasz
źródło
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

Jan
źródło
1

Super łatwe, tutaj:

Environment.CurrentDirectory + "\\" + Process.GetCurrentProcess().ProcessName
Urojeniowy Duch
źródło
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);
RJN
źródło
-1

Aby uzyskać ścieżkę i nazwę

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

Ewerton Dutra
źródło
To powiela tę odpowiedź i tę odpowiedź .
BACON