Як отримати ім’я поточного виконуваного файлу в C #?


355

Я хочу отримати ім’я поточно запущеної програми, тобто виконувану назву програми. В C / C ++ ви отримуєте його args[0].


Виконаним є файл EXE (Windows Forms, програми WPF)? Програмою може бути настільний додаток (WinForms, WPF; і WinRT-Windows Phone?), Веб-додаток, додаток до служби Wcf, Visual Studio Addin, Outlook-Word Addin, модульний тест у VS (MSTest) або додаток Silverlight.
Кікенет

Відповіді:


405
System.AppDomain.CurrentDomain.FriendlyName

61
Остерігайтеся прийнятої відповіді. У нас виникли проблеми з використанням System.AppDomain.CurrentDomain.FriendlyNameпід розгорнутим додатком Click-Once. Для нас це повернення " DefaultDomain ", а не оригінальне ім'я exe.
Gaspode

40
Ми використали це врешті-решт:string file = object_of_type_in_application_assembly.GetType().Assembly.Location; string app = System.IO.Path.GetFileNameWithoutExtension( file );
Gaspode

4
FriendlyName можна встановити на що завгодно. Також отримання місця складання може бути недостатньо, якщо у вас є exe з кількома dll. Крім того, якщо ви використовуєте кілька AppDomain, Assembly.GetCallingAssembly () повертає null.
користувач276648

2
@Gaspode: було б простіше просто сказати Path.GetFileNameWithoutExtension (GetType (). Assembly.Location) - вам не потрібно вказувати об’єкт типу в поточній збірці. Ви можете використовувати GetType цього, і тоді вам навіть не потрібно говорити "це".
vbullinger

4
Це може бути корисним, але це не повинна бути прийнятою відповіддю: Це сильно відрізняється від того, про що просили - у деяких ситуаціях випадково буде те саме , але це зовсім інше. Якщо ви не написали заявку самостійно, це може дуже добре повернутись "мені подобається картопля!" або що б там не було, ваш жартівливий колега записав у цю власність, коли вони створили додаток!
AnorZaken

237

System.AppDomain.CurrentDomain.FriendlyName - Повертає ім'я файлу з розширенням (наприклад, MyApp.exe).

System.Diagnostics.Process.GetCurrentProcess().ProcessName- Повертає ім'я файлу без розширення (наприклад, MyApp).

System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName- Повертає повний шлях та ім'я файлу (наприклад, C: \ Examples \ Proces \ MyApp.exe). Потім ви можете передати це System.IO.Path.GetFileName()або System.IO.Path.GetFileNameWithoutExtension()досягти тих же результатів, що і вище.


3
AppDomain може бути додатком EXE, веб-додатком, тестовим додатком Unit, Addin Visual Studio та "Silverlight App" (?). Можливо, цікаве повне рішення для всіх випадків. Наприклад, для Unit Test VS2012 - ProcessName: vstest.executionengine.x86 MainModule.FileName: C: \ FILES PROGRAM (X86) \ MICROSOFT VISUAL STUDIO 11.0 \ COMMON7 \ IDE \ COMMONEXTENSIONS \ MICROSOFT \ TESTWINDOW. vstestine.exestine.exe MainModule.ModuleName: vstest.executionengine.x86.exe FriendlyName: UnitTestAdapter: Запуск тесту ApplicationName:
Kiquenet

"Програмою" може бути настільний додаток (WinForms, WPF; і WinRT-Windows Phone?), Веб-додаток, додаток для сервісу Wcf, Visual Studio Addin, Outlook-Word Addin, модульний тест у VS (MSTest) або програма Silverlight . Наприклад, як отримати збірку хостів служби для сервісного додатка Wcf, розміщеного в IIS, а не IISExpress або WebDevServer?
Кікенет

6
+1 Я піду з цією відповіддю, оскільки вона містить усі три варіанти, які вам можуть знадобитися в чистому та простому вигляді. Використання оголеної назви програми без шляху чи розширення дуже корисно для текстового довідкового тексту ( /?перемикача), оскільки використання розширення та контуру просто захаращує його.
Synetech

2
Не забудьте розпорядитися результатомGetCurrentProcess()
Махмуд Аль-Кудсі

Process.GetCurrentProcess().ProcessName()повертає MyApp.vshost для мене.
Джонатан Вуд

106

System.Diagnostics.Process.GetCurrentProcess()отримує поточний запущений процес. Ви можете скористатися ProcessNameвластивістю, щоб визначити ім'я. Нижче наведено зразок консольного додатка.

using System;
using System.Diagnostics;

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

36
Краще використовувати Process.GetCurrentProcess (). MainModule.FileName
KindDragon

Process.GetCurrentProcess (). MainModule.FileName прекрасно працює в межах Excel Addin (ExcelDNA)
вушка

10
Цей підхід не вдасться при використанні в режимі Mono; назва процесу для додатків, які працюють на Mono, завжди буде певним варіантом .../bin/monoна * nixes або .../mono.exeв Windows.
cdhowie

1
Це має бути прийнятою відповіддю. Поточне ім'я AppDomain може не мати нічого спільного з назвою виконуваного процесу, особливо коли існує декілька доменів додатків
Іван Кривяков,

Цей метод може бути значно повільнішим, ніж грати з класом зборки.
Ервін Майєр

99

Цього має бути достатньо:

Environment.GetCommandLineArgs()[0];

3
Гм, це повертає (коли запускається з vs.net та використовує хостинг налагодження), місцезнаходження та ім'я filename.vshost.exe ... це справді файл, який виконується в цей час)
Frederik Gheysels

13
Це найкраща відповідь для мене, оскільки Environment.GetCommandLineArgs()це точний аналог C # argvвід C / C ++.
Фредерік Дурень

Домовились! найкраща відповідь. У мене є необхідність отримати Environment.GetCommandLineArgs () [1];
Джеррі Лян

1
Щоб уникнути повного шляху:Path.GetFileNameWithoutExtension(Environment.GetCommandLineArgs()[0])
Натан

1
Це добре працює при спробі відстежити послуги WCF. Ім'я процесу повертається з iisexpress в моєму випадку. Але ця команда дає мені фактичну назву складання служби WCF.
P.Brian.Mackey

19

Це код, який працював для мене:

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

Усі приклади, наведені вище, дали мені ім'я processName з vshost або запущеним ім'ям dll.


4
Для тих, хто не знає або не пропустив його в інших відповідях, простір імен для асамблеї - System.Reflection, а простір імен для Path - System.IO.
об'єднати

4
GetEntryAssembly поверне нульове значення, якщо точка входу додатка знаходиться в рідному коді, а не збірці.
Емдот

18

Спробуйте це:

System.Reflection.Assembly.GetExecutingAssembly()

Це повертає вам System.Reflection.Assemblyекземпляр, у якому є всі дані, які ви могли б хотіти знати про поточну програму. Я думаю, що Locationмайно може отримати те, що ви конкретно шукаєте.


6
Це може бути безпечніше використовувати CodeBaseзамість того, Locationякщо активована функція тіньової копії .NET. Дивіться blogs.msdn.com/suzcook/archive/2003/06/26/…
Дірк Волмар

18
Остерігайтеся GetExecutingAssembly (): якщо ви зателефонуєте цьому з колекції бібліотеки, воно поверне ім'я бібліотечної збірки, яке відрізняється від імені вхідної збірки (тобто оригінального виконуваного файлу). Якщо ви використовуєте GetEntryAssembly (), він повертає ім'я фактичного виконуваного файлу, але він видає виняток, якщо процес працює під WCF (правда, рідкісна ситуація). Для найбільш надійного коду використовуйте Process.GetCurrentProcess (). ProcessName.
Контанго

@Gravitas: Безумовно, що будь-який виконуваний файл, який працює "інтерпретовано", наприклад, з / usr / bin / mono, матиме неправильну назву процесу. Також ProcessName не працюватиме з службами Windows. Якщо ви використовуєте його в бібліотеці, використовуйте GetCallingAssembly.
Стефан Штайгер

1
Працювали для мене. Ім'я властивості повернутого екземпляра збірки GetName () - це те, що вам потрібно, і не включає частину ".exe". Тестується також на Mono / Linux із очікуваним результатом. Assembly.GetName (). Назва
Hatoru Hansou

1
Хм, зауважте, що повернута рядок не зміниться, навіть якщо ви перейменовуєте виконуваний файл вручну за допомогою провідника файлів. У той час як Environment.GetCommandLineArgs () [0] змінюється разом із фактичним іменем виконуваного файлу (звичайно). Випадково другий метод став кращим для моєї конкретної ситуації, оскільки я хочу, щоб папка даних була названа як власне виконуване ім'я файлу.
Hatoru Hansou

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

дасть вам ім'я файлу, як-от ваша програма; "MyApplication.exe"


11

Чому ніхто не запропонував цього, його просто.

Path.GetFileName(Application.ExecutablePath)

3
У якому просторі імен знаходиться Приклад.
Jeetendra

6
Це корисно у програмі Windows Forms, але не інакше
NineBerry

@NineBerry Ви могли б бути зацікавлені в Application.ExecutablePath«S вихідний код .
Моторошний

@NineBerry Дивіться моє повідомлення. Це працює в додатках Console, якщо ви додасте посилання на System.Windows.Forms.
Джон


9

Якщо вам потрібна назва програми для налаштування правила брандмауера, використовуйте:

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

Це забезпечить правильність імені як при налагодженні у VisualStudio, так і при запуску програми безпосередньо у Windows.


2
Для моїх цілей (створення імені файлу журналу) це найкраща відповідь. Якщо запускається розміщений процес (скажімо, служба або веб-додаток), System.AppDomain.CurrentDomain.FriendlyName може повернути потворне ім'я GUID-y із вбудованими косою рисою.
Керт

8

Коли невпевнено чи сумніваєтесь, бігайте по колах, кричіть і кричіть.

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

Я не можу претендувати на тестування кожного варіанта, але це не робить нічого дурного, як повернення vhost під час сесій налагодження.


2
+1 для розваг. :-) Я навряд чи використовував би цей код, якщо тільки я не пишу по-справжньому загальну бібліотеку, яка не має уявлення про своє оточення (і тоді, мабуть, не було б гарною ідеєю підтримувати будь-який глобальний стан, який ви збиралися використовувати назва для).
Андрій Таранцов

@Orwellophile "Програмою" може бути настільний додаток (WinForms, WPF; і WinRT-Windows Phone?), Веб-додаток, сервісна програма Wcf, Visual Studio Addin, Outlook-Word Addin, Unit Test у VS (MSTest) або, Застосування Silverlight. Наприклад, як отримати збірку хостів служби для сервісного додатка Wcf, розміщеного в IIS, а не IISExpress або WebDevServer? Будь-який повний код, дійсний для WinForms, WPF, веб-додатків, сервісного додатку Wcf, Visual Studio Addin, Outlook-Word Addin, Unit Test у програмах VS (MSTest)?
Кікенет

8
  • System.Reflection.Assembly.GetEntryAssembly().Location повертає розташування імені exe, якщо збірка не завантажена з пам'яті.
  • System.Reflection.Assembly.GetEntryAssembly().CodeBase повертає місцеположення як URL.

Протестовано, це працює на 100%, навіть якщо його викликають з бібліотеки C #.
Контанго

1
GetEntryAssembly () повертає null, якщо ви не в основному AppDomain.
користувач276648

4

ЯКЩО ви шукаєте повну інформацію про ваш виконуваний файл, надійним способом цього є використання наступного:

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

Це усуває будь-які проблеми з посередництвом dll, vshost тощо.


Я спробував ваш надійний шлях в Ubuntu Linux 15.10 C ++ за допомогою realpath з наступною заміною рядка STL C ++, і це спричинило збій пункту Point and Click. Можливо, це було викликано помилкою в моно, як сьогодні наголосив наш директор програмного забезпечення? Дякую.
Френк

Я не програмую на Mono, хоча це може бути цікаво спробувати
theMayer

Гаспонде писав вище, що "У нас виникли проблеми з використанням System.AppDomain.CurrentDomain.FriendlyName під" Розгорненими програмами Click-Once "." Не могли б ви здогадатися, які проблеми можуть бути із розгорнутими програмами Click-Once у .NET? Дякую.
Френк

Повертає C: \ Program Files \ dotnet \ dotnet.exe для моєї програми Sample в VS2017.
jwdonahue

3

Ви можете використовувати Environment.GetCommandLineArgs()для отримання аргументів іEnvironment.CommandLine отримати фактичний командний рядок, як було введено.

Також ви можете використовувати Assembly.GetEntryAssembly()абоProcess.GetCurrentProcess() .

Однак під час налагодження слід бути обережним, оскільки цей остаточний приклад може дати ім'я виконавця вашого відладчика (залежно від того, як ви приєднаєте налагоджувач), а не ваш виконуваний файл, як і інші приклади.


4
Остерігайтеся GetExecutingAssembly (): якщо ви зателефонуєте цьому з колекції бібліотеки, воно поверне ім'я бібліотечної збірки, яке відрізняється від імені вхідної збірки (тобто оригінального виконуваного файлу). Якщо ви використовуєте GetEntryAssembly (), він повертає ім'я фактичного виконуваного файлу, але він видає виняток, якщо процес працює під WCF (правда, рідкісна ситуація). Для найбільш надійного коду використовуйте Process.GetCurrentProcess (). ProcessName.
Контанго

@Gravitas: хороший момент - ух, минув час, коли я це написав! : D Я відповідно відредагую
Jeff Yates

Environment.CommandLineдає абсолютний шлях, а не введений командний рядок, принаймні у Mono / Linux.
Механічний равлик

@Mechanicalsnail: Звучить, що Mono не зовсім відповідає документації. Цікаво.
Джефф Йейтс

1

Це те, що ти хочеш:

Assembly.GetExecutingAssembly ().Location

4
Остерігайтеся GetExecutingAssembly (): якщо ви зателефонуєте цьому з колекції бібліотеки, воно поверне ім'я бібліотечної збірки, яке відрізняється від імені вхідної збірки (тобто оригінального виконуваного файлу). Якщо ви використовуєте GetEntryAssembly (), він повертає ім'я фактичного виконуваного файлу, але він видає виняток, якщо процес працює під WCF (правда, рідкісна ситуація). Для найбільш надійного коду використовуйте Process.GetCurrentProcess (). ProcessName.
Контанго

Відповідь не повинна бути питанням. Це те, чого хотів ОП?
jwdonahue

1

Що стосується .Net Core (або Mono), більшість відповідей не застосовуватиметься, коли двійковий файл, що визначає процес, є бінарним файлом виконання Mono або .Net Core (donet), а не вашим фактичним додатком, яке вас цікавить. У цьому випадку , використовуй це:

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

1
GetEntryAssembly()може повернути нуль.
користувач2864740

1

Для програм Windows (форми та консолі) я використовую це:

Потім додайте посилання на System.Windows.Forms у VS:

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

Це правильно працює для мене, чи запускаю я фактичний виконуваний файл або налагоджую в межах VS.

Зауважте, що він повертає ім'я програми без розширення.

Джон


1

Супер легко, тут:

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

1
Для .NET Core Process.GetCurrentProcess (). ProcessName повертає "dotnet".
Євген Набоков

1
Поточний каталог тимчасово тимчасовий і на нього не можна покластися як місце складання / виконуваний файл.
jwdonahue

1

Це працює, якщо вам потрібно лише ім'я програми без розширення:

Path.GetFileNameWithoutExtension(AppDomain.CurrentDomain.FriendlyName);

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.