C # 'daki geçerli yürütülebilir dosyanın adını nasıl alabilirim?


356

Şu anda çalışan programın adını almak istiyorum, bu programın yürütülebilir adıdır. C / C ++ 'da bunu alırsınız args[0].


Yürütülebilir EXE dosyası mı (Windows Forms, WPF uygulamaları)? Bir program bir Masaüstü Uygulaması (WinForms, WPF; ve WinRT-Windows Phone?), Web Uygulaması, Wcf Hizmeti Uygulaması, Visual Studio Eklentisi, Outlook-Word Eklentisi, VS'de Birim Testi (MSTest) veya Silverlight Uygulaması olabilir.
Mart'ta Kiquenet

Yanıtlar:


406
System.AppDomain.CurrentDomain.FriendlyName

61
Kabul edilen cevaba dikkat edin. System.AppDomain.CurrentDomain.FriendlyNameClick-Once tarafından dağıtılan uygulamaları kullanmayla ilgili sorun yaşadık . Bizim için bu, orijinal exe adını değil, " DefaultDomain " döndürüyor .
Gaspode

40
Sonunda bunu kullandık:string file = object_of_type_in_application_assembly.GetType().Assembly.Location; string app = System.IO.Path.GetFileNameWithoutExtension( file );
Gaspode

4
FriendlyName her şeye ayarlanabilir. Ayrıca birkaç dll ile bir exe varsa montaj yeri almak yeterli olmayabilir. Ayrıca, birden fazla AppDomain kullanıyorsanız, Assembly.GetCallingAssembly () işlevi null değerini döndürür.
user276648

2
@Gaspode: Path.GetFileNameWithoutExtension (GetType (). Assembly.Location) - geçerli derlemede türden bir nesne belirtmeniz gerekmez. Bunun GetType'ını kullanabilirsiniz ve sonra "bunu" söylemenize bile gerek yoktur.
vbullinger

4
Bu yararlı olabilir, ancak gerektiği değil kabul cevap: O istedi ne büyük ölçüde farklıdır - bu tesadüfen aynı şey olacak bazı durumlarda, ancak bu tamamen başka bir şeydir. Uygulamayı kendiniz yazmadıysanız çok iyi "Patates gibi!" ya da mizahi meslektaşınız uygulamayı inşa ettiklerinde bu mülke ne yazmış olursa olsun!
AnorZaken

237

System.AppDomain.CurrentDomain.FriendlyName - Uzantılı dosya adını döndürür (örn. MyApp.exe).

System.Diagnostics.Process.GetCurrentProcess().ProcessName- dosya adı döndürür olmadan uzantısı (örneğin Uygulamam).

System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName- Tam yolu ve dosya adını döndürür (örn. C: \ Örnekler \ İşlemler \ Uygulamam.exe). Daha sonra bunuSystem.IO.Path.GetFileName()System.IO.Path.GetFileNameWithoutExtension() yukarıdaki sonuçlarla aynı sonuçları elde etmek için veya .


3
AppDomain bir EXE uygulaması, Web uygulaması, Birim sınama uygulaması, Addin Visual Studio ve "Silverlight Uygulaması" (?) Olabilir. Belki tüm durumlar için ilginç tam çözüm. Örneğin, Birim Testi VS2012 için - İşlemAdı: vstest.executionengine.x86 MainModule.FileName: C: \ PROGRAM FILES (X86) \ MICROSOFT VISUAL STUDIO 11.0 \ COMMON7 \ IDE \ COMMONEXTENSIONS \ MICROSOFT \ TESTWINDOW \ vstine.exec..exe MainModule.ModuleName: vstest.executionengine.x86.exe FriendlyName: UnitTestAdapter: Çalışan test ApplicationName:
Kiquenet 26:14

"Program" bir Masaüstü Uygulaması (WinForms, WPF; ve WinRT-Windows Phone?), Web Uygulaması, Wcf Hizmet Uygulaması, Visual Studio Eklentisi, Outlook-Word Eklentisi, VS'de Birim Testi (MSTest) veya Silverlight Uygulaması olabilir . Örneğin, IISExpress veya WebDevServer'da değil, IIS'de barındırılan bir Wcf Hizmet Uygulaması için hizmet Ana Bilgisayar derlemesi nasıl alınır?
Mart'ta Kiquenet

6
+1 Bu cevapla devam edeceğim çünkü ihtiyacınız olabilecek her üç varyasyonu da temiz ve basit bir şekilde sağlıyor. Çıplak program adını yol veya uzantı olmadan kullanmak, program içi yardım metni ( /?anahtar) için çok yararlıdır , çünkü uzantı ve yolu kullanmak gereksiz yere dağınıktır.
Synetech

2
GetCurrentProcess()
Sonucu atmayı

Process.GetCurrentProcess().ProcessName()MyApp.vshost benim için döner .
Jonathan Wood

106

System.Diagnostics.Process.GetCurrentProcess()çalışmakta olan işlemi alır. Sen kullanabilirsiniz ProcessNameadını anlamaya özelliği. Aşağıda örnek bir konsol uygulaması bulunmaktadır.

using System;
using System.Diagnostics;

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

36
Daha iyi kullanın Process.GetCurrentProcess (). MainModule.FileName
KindDragon

Process.GetCurrentProcess (). MainModule.FileName bir Excel Eklentisi (ExcelDNA) içinden mükemmel çalışır
earcam

10
Mono çalışma zamanında kullanıldığında bu yaklaşım başarısız olacaktır; Mono üzerinde çalışan uygulamalar için işlem adı her zaman .../bin/monoon * nixes veya .../mono.exeWindows üzerinde bir çeşit olacaktır .
cdhowie

1
Bu kabul edilen cevap olmalı. Geçerli AppDomain adının, özellikle birden çok uygulama etki alanı olduğunda yürütülebilir işlem adıyla ilgisi olmayabilir
Ivan Krivyakov

Bu yöntem, Assembly sınıfıyla oynamaktan önemli ölçüde daha yavaş olabilir.
Erwin Mayer

99

Bu yeterli olmalıdır:

Environment.GetCommandLineArgs()[0];

3
Hmm, bu döndürür (vs.net'ten çalıştırıldığında ve hata ayıklama barındırma özelliğini kullanarak), dosya
adı.vshost.exe

13
Bu benim için en iyi cevap çünkü C / C ++ 'dan Environment.GetCommandLineArgs()tam C # analogu argv.
Frederick The Fool

Kabul! en iyi cevap. Environment.GetCommandLineArgs () [1];
Jerry Liang

1
Tam yolu önlemek için:Path.GetFileNameWithoutExtension(Environment.GetCommandLineArgs()[0])
Nathan

1
Bu, WCF hizmetlerini izlemeye çalışırken iyi çalışır. İşlem adı benim durumumda iisexpress ile geri geliyor. Ancak bu komut bana gerçek WCF hizmeti derleme adını verir.
P.Brian.Mackey

19

Bu benim için çalışan kod:

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

Yukarıdaki tüm örnekler bana vshost veya çalışan dll adı ile processName verdi.


4
Bilmeyenler ya da diğer cevaplarda kaçırmış olanlar için Assembly ad alanı System.Reflection ve Path ad alanı System.IO'dur.
amalgamate

4
Uygulama giriş noktası bir derleme yerine yerel koddaysa GetEntryAssembly null değerini döndürür.
Emdot

18

Bunu dene:

System.Reflection.Assembly.GetExecutingAssembly()

Bu size System.Reflection.Assemblygeçerli uygulama hakkında bilmek isteyebileceğiniz tüm verileri içeren bir örnek döndürür . LocationÖzellik sonra özellikle ne olduğunu alabilirsiniz düşünüyorum .


6
.NET'in gölge kopya özelliğinin etkin olması CodeBaseyerine kullanılması daha güvenli olabilir Location. Bkz. Blogs.msdn.com/suzcook/archive/2003/06/26/…
Dirk Vollmar

18
GetExecutingAssembly () öğesine dikkat edin: bunu bir kütüphane derlemesinden çağırırsanız, kütüphane derlemesinin adını, derleme derlemesinin adından farklı olarak döndürür (yani özgün yürütülebilir dosya). GetEntryAssembly () kullanırsanız, gerçek yürütülebilir dosyanın adını döndürür, ancak işlem WCF (kuşkusuz nadir bir durum) altında çalışıyorsa bir istisna atar. En sağlam kod için Process.GetCurrentProcess () yöntemini kullanın.
Contango

@Gravitas: Kesinlikle hayır, "yorumlanan" çalıştıran herhangi bir yürütülebilir dosya, örneğin / usr / bin / mono ile yanlış işlem adı olacaktır. Ayrıca ProcessName, Windows hizmetleriyle çalışmaz. Bir kitaplıkta kullanıyorsanız, GetCallingAssembly kullanın.
Stefan Steiger

1
Benim için çalıştı. Döndürülen Assembly örneği GetName () çağrısının adı, ihtiyacınız olan şeydir ve ".exe" bölümünü içermez. Ayrıca beklenen sonuç ile Mono / Linux üzerinde de test edildi. Assembly.GetName (). İsim
Hatoru Hansou

1
Hmm, yürütülebilir dosyayı el ile dosya gezgini kullanarak yeniden adlandırsanız bile, döndürülen dizenin değişmeyeceğini unutmayın. Environment.GetCommandLineArgs () [0], gerçek yürütülebilir dosya adıyla birlikte değişir (elbette). Tesadüfen, ikinci yöntem, veri klasörünün gerçek yürütülebilir dosya adı olarak adlandırılmasını istediğim için özel durumum için daha iyi sonuç verdi.
Hatoru Hansou

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

uygulamanızın DosyaAdı gibi; "MyApplication.exe"


11

Neden kimse bunu önermedi, bu basit.

Path.GetFileName(Application.ExecutablePath)

3
Uygulama hangi ad alanında bulunur?
Jeetendra

6
Bu, bir Windows Forms uygulaması içindeyken yararlıdır, ancak başka şekilde değil
NineBerry

Sen ilgilenen olabilir @NineBerry Application.ExecutablePathbireyin kaynak kodu .
Ürkütücü

@NineBerry Yazımı gör. System.Windows.Forms'a bir başvuru eklerseniz Konsol uygulamalarında çalışır.
John


9

Güvenlik duvarı kuralı ayarlamak için Program adına ihtiyacınız varsa, şunu kullanın:

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

Bu, adın hem VisualStudio'da hata ayıklarken hem de uygulamayı doğrudan pencerelerde çalıştırırken doğru olmasını sağlayacaktır.


2
Benim amacım için (bir günlük dosyası adı oluşturmak), bu en iyi cevaptır. Barındırılan bir işlem (örneğin, bir hizmet veya bir web uygulaması) çalıştırıyorsanız, System.AppDomain.CurrentDomain.FriendlyName katıştırılmış eğik çizgilerle çirkin bir GUID-y adı döndürebilir.
Curt

8

Belirsiz veya şüphe duyduğunuzda daireler çizin, çığlık atın ve bağırın.

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

Her seçeneği test ettiğimi iddia edemem, ancak hata ayıklama oturumları sırasında vhost'u döndürmek gibi aptalca bir şey yapmaz.


2
Eğlence için +1. :-) Çevresi hakkında hiçbir fikri olmayan gerçekten genel bir kütüphane yazmadıkça, bu kodu neredeyse hiç kullanmam. adı).
Andrey Tarantsov

@Orwellophile Bir "program" bir Masaüstü Uygulaması (WinForms, WPF; ve WinRT-Windows Phone?), Web Uygulaması, Wcf Hizmet Uygulaması, Visual Studio Eklentisi, Outlook-Word Eklentisi, VS'de Birim Testi (MSTest) veya, Silverlight Uygulaması. Örneğin, IISExpress veya WebDevServer'da değil, IIS'de barındırılan bir Wcf Hizmet Uygulaması için hizmet Ana Bilgisayar derlemesi nasıl alınır? Herhangi bir tam kod A WinForms, WPF, Web Uygulaması, Wcf Hizmet Uygulaması, Visual Studio Eklentisi, Outlook-Word Eklentisi, VS (MSTest) uygulamalarında Birim Testi için geçerli mi?
Mart'ta Kiquenet

8
  • System.Reflection.Assembly.GetEntryAssembly().Location derleme bellekten yüklenmemişse exe adının konumunu döndürür.
  • System.Reflection.Assembly.GetEntryAssembly().CodeBase konumu URL olarak döndürür.

Test edildi, bu bir C # kitaplığından çağrılsa bile% 100 çalışıyor.
Contango

1
Ana AppDomain'de değilseniz GetEntryAssembly () yöntemi null değerini döndürür.
user276648

4

Yürütülebilir dosyalarınızın tam yol bilgilerini arıyorsanız, bunu yapmanın güvenilir yolu aşağıdakileri kullanmaktır:

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

Bu aracı dll, vshost, vb ile ilgili sorunları ortadan kaldırır.


Ubuntu Linux 15.10 C ++ 'da realpath kullanarak STL C ++ string değiştirmeyi kullanarak güvenilir bir şekilde denedim ve Point and Click'un başarısız olmasına neden oldu. Bugün yazılım yönetmenimiz olarak mono'daki bir hatadan kaynaklanıyor olabilir mi? Teşekkürler.
Frank


Gasponde, "Click-Once konuşlandırılan uygulamalar altında System.AppDomain.CurrentDomain.FriendlyName kullanmayla ilgili sorun yaşadık." .NET'te Click-Once konuşlandırılan uygulamalarla ilgili sorunların ne olabileceğini tahmin edebilir misiniz? Teşekkürler.
Frank

VS2017'deki Örnek programım için C: \ Program Files \ dotnet \ dotnet.exe dosyasını döndürür.
jwdonahue

3

Environment.GetCommandLineArgs()Bağımsız değişkenleri Environment.CommandLineelde etmek ve girildiği gibi gerçek komut satırını elde etmek için kullanabilirsiniz .

Ayrıca, Assembly.GetEntryAssembly()veya kullanabilirsiniz Process.GetCurrentProcess().

Ancak, hata ayıklarken dikkatli olmalısınız, çünkü bu son örnek diğer örneklerde olduğu gibi yürütülebilir dosya yerine hata ayıklayıcının yürütülebilir adını (hata ayıklayıcıyı nasıl eklediğinize bağlı olarak) verebilir.


4
GetExecutingAssembly () öğesine dikkat edin: bunu bir kütüphane derlemesinden çağırırsanız, kütüphane derlemesinin adını, derleme derlemesinin adından farklı olarak döndürür (yani özgün yürütülebilir dosya). GetEntryAssembly () kullanırsanız, gerçek yürütülebilir dosyanın adını döndürür, ancak işlem WCF (kuşkusuz nadir bir durum) altında çalışıyorsa bir istisna atar. En sağlam kod için Process.GetCurrentProcess () yöntemini kullanın.
Contango

@Gravitas: iyi bir nokta - vay, bunu yazdığımdan beri bir süre oldu! : D Buna göre düzenleyeceğim
Jeff Yates

Environment.CommandLineen azından Mono / Linux'ta girilen komut satırını değil mutlak yolu verir.
Mekanik salyangoz

@Mechanicalsnail: Mono gibi geliyor belgeleri tam olarak takip etmiyor. İlginç.
Jeff Yates

1

İstediğiniz bu mu:

Assembly.GetExecutingAssembly ().Location

4
GetExecutingAssembly () öğesine dikkat edin: bunu bir kütüphane derlemesinden çağırırsanız, kütüphane derlemesinin adını, derleme derlemesinin adından farklı olarak döndürür (yani özgün yürütülebilir dosya). GetEntryAssembly () kullanırsanız, gerçek yürütülebilir dosyanın adını döndürür, ancak işlem WCF (kuşkusuz nadir bir durum) altında çalışıyorsa bir istisna atar. En sağlam kod için Process.GetCurrentProcess () yöntemini kullanın.
Contango

Bir cevap bir soru olmamalı. OP'nin istediği bu mu?
jwdonahue

1

.Net Core (veya Mono) üzerinde, işlemi tanımlayan ikili, ilgilendiğiniz gerçek uygulamanız değil Mono veya .Net Core'un (dotnet) çalışma zamanı ikili dosyası olduğunda, yanıtların çoğu geçerli olmaz. , bunu kullan:

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

1
GetEntryAssembly()boş dönebilir.
user2864740

1

Windows uygulamaları (formlar ve konsol) için bunu kullanıyorum:

VS'de System.Windows.Forms'a bir başvuru ekleyin ve ardından:

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

Bu gerçek çalıştırılabilir veya VS içinde hata ayıklama çalışıyorum benim için doğru çalışır.

Uzantı olmadan uygulama adını döndürdüğünü unutmayın.

John


1

Süper kolay, burada:

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

1
.NET Core Process.GetCurrentProcess () için ProcessName "dotnet" döndürür.
Evgeni Nabokov

1
Geçerli dizin geçici olarak geçicidir ve derlemenin / yürütülebilir dosyanın konumu olarak kullanılamaz.
jwdonahue

1

Yalnızca uzantısız uygulama adına ihtiyacınız varsa çalışır:

Path.GetFileNameWithoutExtension(AppDomain.CurrentDomain.FriendlyName);

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.