Bagaimana cara mendapatkan nama yang dapat dieksekusi saat ini di C #?


355

Saya ingin mendapatkan nama program yang sedang berjalan, yaitu nama program yang dapat dieksekusi. Di C / C ++ Anda mendapatkannya dariargs[0] .


Yang dapat dieksekusi adalah file EXE (Formulir Windows, aplikasi WPF)? Suatu program dapat berupa Aplikasi Desktop (WinForms, WPF; dan WinRT-Windows Phone?), Aplikasi Web, Aplikasi Layanan Wcf, Visual Studio Addin, Outlook-Word Addin, Unit Test dalam VS (MSTest), atau, Aplikasi Silverlight.
Kiquenet

Jawaban:


405
System.AppDomain.CurrentDomain.FriendlyName

61
Waspadalah terhadap jawaban yang diterima. Kami memiliki masalah dengan penggunaan di System.AppDomain.CurrentDomain.FriendlyNamebawah aplikasi yang dikerahkan Klik-Sekali. Bagi kami, ini mengembalikan " DefaultDomain ", dan bukan nama exe asli.
Gaspode

40
Kami menggunakan ini pada akhirnya:string file = object_of_type_in_application_assembly.GetType().Assembly.Location; string app = System.IO.Path.GetFileNameWithoutExtension( file );
Gaspode

4
FriendlyName dapat diatur ke apa saja. Juga mendapatkan lokasi perakitan mungkin tidak cukup jika Anda memiliki exe dengan beberapa dll. Selanjutnya jika Anda menggunakan beberapa AppDomain, Assembly.GetCallingAssembly () mengembalikan nol.
user276648

2
@ Gaspode: akan lebih mudah hanya dengan mengatakan Path.GetFileNameWithoutExtension (GetType (). Assembly.Location) - Anda tidak perlu menentukan objek dari jenis dalam perakitan saat ini. Anda dapat menggunakan GetType dari ini, dan kemudian Anda bahkan tidak perlu mengatakan "ini."
vbullinger

4
Ini bisa berguna, tetapi seharusnya tidak menjadi jawaban yang diterima: Ini sangat berbeda dari apa yang diminta - itu akan secara kebetulan menjadi hal yang sama dalam beberapa situasi, tetapi ini adalah sesuatu yang sama sekali berbeda. Jika Anda tidak menulis sendiri aplikasi itu bisa sangat baik mengembalikan "Saya suka kentang!" atau apa pun yang ditulis kolega lucu Anda di properti ini ketika mereka membuat aplikasi!
AnorZaken

237

System.AppDomain.CurrentDomain.FriendlyName - Mengembalikan nama file dengan ekstensi (mis. MyApp.exe).

System.Diagnostics.Process.GetCurrentProcess().ProcessName- Mengembalikan nama file tanpa ekstensi (mis. MyApp).

System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName- Mengembalikan path lengkap dan nama file (mis. C: \ Contoh \ Proses \ MyApp.exe). Anda kemudian dapat meneruskan ini ke System.IO.Path.GetFileName()atau System.IO.Path.GetFileNameWithoutExtension()untuk mencapai hasil yang sama seperti di atas.


3
AppDomain dapat berupa aplikasi EXE, aplikasi Web, aplikasi uji Unit, Addin Visual Studio, dan "Aplikasi Silverlight" (?). Mungkin solusi lengkap yang menarik untuk semua kasus. Misalnya, untuk Tes Unit VS2012 - ProcessName: vstest.executionengine.x86 MainModule.FileName: C: \ PROGRAM FILES (X86) \ MICROSOFT VISUAL STUDIO 11.0 \ COMMON7 \ IDE \ COMMONEXTENSIONS \ MICROSOFT \ TESTWINDOW \ vstest.executionengeksekusi. MainModule.ModuleName: vstest.executionengine.x86.exe FriendlyName: UnitTestAdapter: Running test ApplicationName:
Kiquenet

"Program" dapat berupa Aplikasi Desktop (WinForms, WPF; dan WinRT-Windows Phone?), Aplikasi Web, Aplikasi Layanan Wcf, Visual Studio Addin, Outlook-Word Addin, Unit Test dalam VS (MSTest), atau, Aplikasi Silverlight . Misalnya, bagaimana mendapatkan perakitan Host layanan untuk Aplikasi Layanan Wcf yang di-host di IIS, bukan IISExpress atau WebDevServer?
Kiquenet

6
+1 Saya akan menjawab pertanyaan ini karena memberikan ketiga variasi yang mungkin Anda perlukan dengan cara yang bersih dan sederhana. Menggunakan nama program kosong tanpa jalur atau ekstensi sangat berguna untuk teks bantuan dalam-program ( /?beralih), karena menggunakan ekstensi dan jalur hanya mengacaukannya secara tidak perlu.
Synetech

2
Ingatlah untuk membuang hasilGetCurrentProcess()
Mahmoud Al-Qudsi

Process.GetCurrentProcess().ProcessName()mengembalikan MyApp.vshost untuk saya.
Jonathan Wood

106

System.Diagnostics.Process.GetCurrentProcess()mendapat proses yang sedang berjalan. Anda dapat menggunakan ProcessNameproperti untuk mengetahui namanya. Di bawah ini adalah contoh aplikasi konsol.

using System;
using System.Diagnostics;

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

36
Lebih baik gunakan Process.GetCurrentProcess (). MainModule.FileName
KindDragon

Process.GetCurrentProcess (). MainModule.FileName berfungsi dengan sempurna dari dalam Excel Addin (ExcelDNA)
earcam

10
Pendekatan ini akan gagal ketika digunakan pada runtime Mono; nama proses untuk aplikasi yang berjalan pada Mono akan selalu menjadi beberapa varian .../bin/monopada * nixes atau .../mono.exepada Windows.
cdhowie

1
Ini harus menjadi jawaban yang diterima. Nama AppDomain saat ini mungkin tidak ada hubungannya dengan nama proses yang dapat dieksekusi, terutama ketika beberapa domain aplikasi hadir
Ivan Krivyakov

Metode ini bisa jauh lebih lambat daripada bermain dengan kelas Assembly.
Erwin Mayer

99

Ini sudah cukup:

Environment.GetCommandLineArgs()[0];

3
Hmm, ini kembali (ketika dijalankan dari vs.net dan menggunakan hal debug hosting), lokasi dan nama filename.vshost.exe ... yang memang file yang sedang dieksekusi saat ini)
Frederik Gheysels

13
Ini jawaban terbaik bagi saya karena Environment.GetCommandLineArgs()merupakan analog C # yang tepat argvdari C / C ++.
Frederick The Fool

Sepakat! jawaban Terbaik. Saya memiliki kebutuhan untuk mendapatkan Environment.GetCommandLineArgs () [1];
Jerry Liang

1
Untuk menghindari path lengkap:Path.GetFileNameWithoutExtension(Environment.GetCommandLineArgs()[0])
Nathan

1
Ini bekerja dengan baik ketika mencoba melacak layanan WCF. Nama proses kembali dengan iisexpress dalam kasus saya. Tapi perintah ini memberi saya nama perakitan layanan WCF yang sebenarnya.
P.Brian.Mackey

19

Ini adalah kode yang berfungsi untuk saya:

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

Semua contoh di atas memberi saya processName dengan vshost atau nama dll yang berjalan.


4
Bagi mereka yang tidak tahu, atau melewatkannya di jawaban lain, namespace untuk Assembly adalah System.Refleksi, dan namespace untuk Path adalah System.IO.
amalgamate

4
GetEntryAssembly akan mengembalikan nol jika titik masuk aplikasi dalam kode asli dan bukan rakitan.
Emdot

18

Coba ini:

System.Reflection.Assembly.GetExecutingAssembly()

Ini mengembalikan Anda sebuah System.Reflection.Assemblyinstance yang memiliki semua data yang Anda ingin tahu tentang aplikasi saat ini. Saya pikir Locationproperti itu mungkin mendapatkan apa yang Anda cari secara spesifik.


6
Mungkin lebih aman untuk digunakan CodeBasedaripada Locationdalam kasus. Fitur salinan bayangan NET aktif. Lihat blogs.msdn.com/suzcook/archive/2003/06/26/…
Dirk Vollmar

18
Waspadalah terhadap GetExecutingAssembly (): jika Anda memanggil ini dari rakitan perpustakaan, ia mengembalikan nama rakitan perpustakaan, yang berbeda dari nama rakitan entri (yaitu yang dapat dieksekusi asli). Jika Anda menggunakan GetEntryAssembly (), itu mengembalikan nama executable yang sebenarnya, tetapi itu melempar pengecualian jika proses berjalan di bawah WCF (memang situasi yang jarang terjadi). Untuk kode yang paling kuat, gunakan Process.GetCurrentProcess (). ProcessName.
Contango

@ Gravitas: Tentu saja tidak, semua executable yang menjalankan "interpreted", mis. Dengan / usr / bin / mono akan memiliki nama proses yang salah. Juga ProcessName tidak akan berfungsi dengan layanan windows. Jika Anda menggunakannya di perpustakaan, gunakan GetCallingAssembly.
Stefan Steiger

1
Bekerja untukku. Nama properti panggilan instance GetName () yang dikembalikan adalah apa yang Anda butuhkan, dan tidak menyertakan bagian ".exe". Juga diuji pada Mono / Linux dengan hasil yang diharapkan. Assembly.GetName (). Nama
Hatoru Hansou

1
Hmm, perhatikan bahwa string yang dikembalikan tidak akan berubah bahkan jika Anda mengganti nama file yang dapat dieksekusi dengan tangan menggunakan file explorer. Sementara Environment.GetCommandLineArgs () [0] berubah bersama dengan nama file aktual yang dapat dieksekusi (tentu saja). Secara kebetulan, metode kedua menghasilkan lebih baik untuk situasi spesifik saya karena saya ingin folder data dinamai sebagai nama file aktual yang dapat dieksekusi.
Hatoru Hansou

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

akan memberi Anda FileName dari aplikasi Anda seperti; "MyApplication.exe"


11

Mengapa tidak ada yang menyarankan ini, itu sederhana.

Path.GetFileName(Application.ExecutablePath)

3
Namespace yang ditempati Aplikasi.
Jeetendra

6
Ini berguna ketika di dalam aplikasi Windows Forms, tetapi tidak sebaliknya
NineBerry

@NineBerry Anda mungkin tertarik Application.ExecutablePath's kode sumber .
Spooky

@NineBerry Lihat posting saya. Ini berfungsi dalam aplikasi Konsol jika Anda menambahkan referensi ke System.Windows.Forms.
John


9

Jika Anda memerlukan nama Program untuk mengatur aturan firewall, gunakan:

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

Ini akan memastikan bahwa nama tersebut benar ketika melakukan debugging di VisualStudio dan ketika menjalankan aplikasi langsung di windows.


2
Untuk tujuan saya (membuat nama file logging), ini adalah jawaban terbaik. Jika menjalankan proses yang dihosting (katakanlah, layanan, atau aplikasi web), System.AppDomain.CurrentDomain.FriendlyName dapat mengembalikan nama GUID-y yang jelek dengan slash yang disematkan.
Curt

8

Ketika tidak pasti atau ragu-ragu, berlari dalam lingkaran, menjerit dan berteriak.

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

Saya tidak dapat mengklaim telah menguji setiap opsi, tetapi tidak melakukan hal bodoh seperti mengembalikan vhost selama sesi debugging.


2
+1 untuk hiburan. :-) Saya hampir tidak akan menggunakan kode ini, kecuali saya sedang menulis perpustakaan yang benar-benar generik yang tidak tahu tentang lingkungannya (dan mungkin itu bukan ide yang baik untuk mempertahankan keadaan global apa pun yang akan Anda gunakan nama untuk).
Andrey Tarantsov

@Orwellophile A "program" dapat berupa Aplikasi Desktop (WinForms, WPF; dan WinRT-Windows Phone?), Aplikasi Web, Aplikasi Layanan Wcf, Visual Studio Addin, Outlook-Word Addin, Uji Unit dalam VS (MSTest), atau, Aplikasi Silverlight. Misalnya, bagaimana mendapatkan perakitan Host layanan untuk Aplikasi Layanan Wcf yang di-host di IIS, bukan IISExpress atau WebDevServer? Adakah kode lengkap yang valid untuk A WinForms, WPF, Aplikasi Web, Aplikasi Layanan Wcf, Visual Studio Addin, Outlook-Word Addin, Uji Unit dalam aplikasi VS (MSTest)?
Kiquenet

8
  • System.Reflection.Assembly.GetEntryAssembly().Location mengembalikan lokasi nama exe jika perakitan tidak dimuat dari memori.
  • System.Reflection.Assembly.GetEntryAssembly().CodeBase mengembalikan lokasi sebagai URL.

Diuji, ini berfungsi 100%, bahkan jika dipanggil dari dalam pustaka C #.
Contango

1
GetEntryAssembly () mengembalikan nol jika Anda tidak berada di AppDomain utama.
user276648

4

JIKA Anda mencari informasi path lengkap dari executable Anda, cara yang dapat diandalkan untuk melakukannya adalah dengan menggunakan yang berikut:

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

Ini menghilangkan masalah dengan perantara dll, vshost, dll.


Saya mencoba cara Anda dapat diandalkan di Ubuntu Linux 15,10 C ++ menggunakan realpath diikuti oleh STL C ++ string replace dan itu menyebabkan Point dan Click gagal. Mungkinkah itu disebabkan oleh bug di mono sebagai direktur perangkat lunak kami menduga hari ini? Terima kasih.
Frank

Saya tidak memprogram Mono, meskipun mungkin akan menyenangkan untuk mencoba
May

Gasponde menulis di atas bahwa "Kami memiliki masalah dengan menggunakan System.AppDomain.CurrentDomain.FriendlyName di bawah aplikasi yang dikerahkan Click-Once." Bisakah Anda membuat tebakan tentang masalah apa yang mungkin terjadi dengan aplikasi yang dikerahkan Click-Once di .NET? Terima kasih.
Frank

Mengembalikan C: \ Program Files \ dotnet \ dotnet.exe untuk program Sampel saya di VS2017.
jwdonahue

3

Anda dapat menggunakan Environment.GetCommandLineArgs()untuk mendapatkan argumen danEnvironment.CommandLine untuk mendapatkan baris perintah yang sebenarnya seperti yang dimasukkan.

Anda juga dapat menggunakan Assembly.GetEntryAssembly()atauProcess.GetCurrentProcess() .

Namun, ketika debugging, Anda harus berhati-hati karena contoh terakhir ini dapat memberikan nama yang dapat dieksekusi debugger Anda (tergantung pada bagaimana Anda melampirkan debugger) daripada Anda yang dapat dieksekusi, seperti contoh lainnya.


4
Waspadalah terhadap GetExecutingAssembly (): jika Anda memanggil ini dari rakitan perpustakaan, ia mengembalikan nama rakitan perpustakaan, yang berbeda dari nama rakitan entri (yaitu yang dapat dieksekusi asli). Jika Anda menggunakan GetEntryAssembly (), ia mengembalikan nama executable yang sebenarnya, tetapi ia melempar pengecualian jika prosesnya berjalan di bawah WCF (memang situasi yang jarang terjadi). Untuk kode yang paling kuat, gunakan Process.GetCurrentProcess (). ProcessName.
Contango

@ Gravitas: poin bagus - wow, sudah lama sejak saya menulis ini! : D Saya akan mengeditnya
Jeff Yates

Environment.CommandLinememberikan jalur absolut, bukan baris perintah yang dimasukkan, setidaknya di Mono / Linux.
Siput mekanik

@Mechanicalsnail: Kedengarannya seperti Mono tidak cukup mengikuti dokumentasi. Menarik.
Jeff Yates

1

Apa ini yang kau inginkan:

Assembly.GetExecutingAssembly ().Location

4
Waspadalah terhadap GetExecutingAssembly (): jika Anda memanggil ini dari rakitan perpustakaan, ia mengembalikan nama rakitan perpustakaan, yang berbeda dari nama rakitan entri (yaitu yang dapat dieksekusi asli). Jika Anda menggunakan GetEntryAssembly (), itu mengembalikan nama executable yang sebenarnya, tetapi itu melempar pengecualian jika proses berjalan di bawah WCF (memang situasi yang jarang terjadi). Untuk kode yang paling kuat, gunakan Process.GetCurrentProcess (). ProcessName.
Contango

Jawaban seharusnya tidak menjadi pertanyaan. Itukah yang diinginkan OP?
jwdonahue

1

Pada .Net Core (atau Mono), sebagian besar jawaban tidak akan berlaku ketika biner yang mendefinisikan prosesnya adalah biner runtime dari Mono atau .Net Core (dotnet) dan bukan aplikasi aktual yang Anda minati. Dalam hal ini , Gunakan ini:

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

1
GetEntryAssembly()dapat mengembalikan nol.
user2864740

1

Untuk aplikasi windows (formulir dan konsol) saya menggunakan ini:

Tambahkan referensi ke System.Windows.Forms di VS lalu:

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

Ini berfungsi dengan baik untuk saya apakah saya menjalankan executable aktual atau debugging dalam VS.

Perhatikan bahwa ia mengembalikan nama aplikasi tanpa ekstensi.

John


1

Sangat mudah, di sini:

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

1
Untuk .NET Core Process.GetCurrentProcess (). ProcessName mengembalikan "dotnet".
Evgeni Nabokov

1
Direktori saat ini sementara sementara dan tidak dapat diandalkan untuk menjadi lokasi majelis / dieksekusi.
jwdonahue

1

Ini berfungsi jika Anda hanya perlu nama aplikasi tanpa ekstensi:

Path.GetFileNameWithoutExtension(AppDomain.CurrentDomain.FriendlyName);

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.