it-swarm.com.ru

Как я могу получить путь к приложению в консольном приложении .NET?

Как найти путь к приложению в консольном приложении?

В Windows Forms я могу использовать Application.StartupPath, чтобы найти текущий путь, но он не доступен в консольном приложении.

871
JSmyth

System.Reflection.Assembly.GetExecutingAssembly() . Location1

Добавьте к этому System.IO.Path.GetDirectoryName , если вам нужен только каталог.

1 Согласно комментарию мистера Миндора:
System.Reflection.Assembly.GetExecutingAssembly().Location возвращает информацию о том, где находится исполняющая сборка, которая может быть, а может и не находиться там, где находится сборка, когда она не выполняется. В случае сборок теневого копирования вы получите путь во временный каталог. System.Reflection.Assembly.GetExecutingAssembly().CodeBase вернет "постоянный" путь сборки.

1098
Sam Axe

Вы можете использовать следующий код, чтобы получить текущий каталог приложения.

AppDomain.CurrentDomain.BaseDirectory
384
Sarathy

У вас есть два варианта поиска каталога приложения, которое вы выберете, будет зависеть от вашей цели.

// to get the location the Assembly is executing from
//(not necessarily where the it normally resides on disk)
// in the case of the using shadow copies, for instance in NUnit tests, 
// this will be in a temp directory.
string path = System.Reflection.Assembly.GetExecutingAssembly().Location;

//To get the location the Assembly normally resides on disk or the install directory
string path = System.Reflection.Assembly.GetExecutingAssembly().CodeBase;

//once you have the path you get the directory with:
var directory = System.IO.Path.GetDirectoryName(path);
147
Mr.Mindor

Возможно, немного поздно, но это стоит упомянуть:

Environment.GetCommandLineArgs()[0];

Или правильнее получить только путь к каталогу:

System.IO.Path.GetDirectoryName(Environment.GetCommandLineArgs()[0]);

Edit:

Довольно много людей отметили, что GetCommandLineArgs не гарантирует возвращение имени программы. Смотрите Первое слово в командной строке - это имя программы только по соглашению . В статье утверждается, что "Хотя очень немногие программы для Windows используют эту причуду (я сам не знаю ни о чем)". Таким образом, можно "подделать" GetCommandLineArgs, но мы говорим о консольном приложении. Консольные приложения обычно бывают быстрыми и грязными. Так что это соответствует моей философии KISS.

76
Steve Mc

Для всех, кто интересуется веб-приложениями asp.net Вот мои результаты 3 разных методов

protected void Application_Start(object sender, EventArgs e)
{
  string p1 = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
  string p2 = System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath;
  string p3 = this.Server.MapPath("");
  Console.WriteLine("p1 = " + p1);
  Console.WriteLine("p2 = " + p2);
  Console.WriteLine("p3 = " + p3);
}

результат

p1 = C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\a897dd66\ec73ff95\Assembly\dl3\ff65202d\29daade3_5e84cc01
p2 = C:\inetpub\SBSPortal_staging\
p3 = C:\inetpub\SBSPortal_staging

приложение физически запускается из "C:\inetpub\SBSPortal_staging", поэтому первое решение определенно не подходит для веб-приложений.

43
rocketsarefast

Ответ выше был на 90% от того, что мне было нужно, но вместо обычного пути я вернул Uri.

Как объясняется в сообщении на форумах MSDN: Как преобразовать путь URI в обычный путь к файлу? , я использовал следующее:

// Get normal filepath of this Assembly's permanent directory
var path = new Uri(
    System.IO.Path.GetDirectoryName(
        System.Reflection.Assembly.GetExecutingAssembly().CodeBase)
    ).LocalPath;
36
fizzled

Возможно, вы хотите сделать это:

System.IO.Path.GetDirectoryName(
    System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase)
27
PSU_Kardi

вы можете использовать это вместо этого.

System.Environment.CurrentDirectory
22
ButtShock

Для консольных приложений вы можете попробовать это:

System.IO.Directory.GetCurrentDirectory();

Вывод (на моей локальной машине):

c:\users\xxxxxxx\Documents\visual studio 2012\Проекты\ImageHandler\GetDir\bin\Debug

Или вы можете попробовать (в конце есть дополнительная обратная косая черта):

AppDomain.CurrentDomain.BaseDirectory

Результат:

c:\users\xxxxxxx\Documents\visual studio 2012\Проекты\ImageHandler\GetDir\bin\Debug \

19
F.Alves

Я использовал этот код и получил решение.

AppDomain.CurrentDomain.BaseDirectory
15
Trimantra Software Solution

Если вы ищете .NET Core совместимый способ, используйте

System.AppContext.BaseDirectory

Это было представлено в .NET Framework 4.6 и .NET Core 1.0 (и .NET Standard 1.3). Смотрите: Свойство AppContext.BaseDirectory .

Согласно эта страница ,

Это предпочтительная замена для AppDomain.CurrentDomain.BaseDirectory в .NET Core

13
Dejan

Вы можете просто добавить в свой проект ссылки System.Windows.Forms и затем использовать System.Windows.Forms.Application.StartupPath как обычно.

Таким образом, не нужно более сложных методов или использования отражения.

8
fruggiero

Я использовал

System.AppDomain.CurrentDomain.BaseDirectory

когда я хочу найти путь относительно папки приложений. Это работает как для ASP.Net, так и для приложений winform. Также не требуется никаких ссылок на сборки System.Web.

8
user2346593

Я использую это, если предполагается, что exe-файл вызывается двойным щелчком

var thisPath = System.IO.Directory.GetCurrentDirectory();
7
developer747

Я имею в виду, почему не метод p/invoke?

    using System;
    using System.IO;
    using System.Runtime.InteropServices;
    using System.Text;
    public class AppInfo
    {
            [DllImport("kernel32.dll", CharSet = CharSet.Auto, ExactSpelling = false)]
            private static extern int GetModuleFileName(HandleRef hModule, StringBuilder buffer, int length);
            private static HandleRef NullHandleRef = new HandleRef(null, IntPtr.Zero);
            public static string StartupPath
            {
                get
                {
                    StringBuilder stringBuilder = new StringBuilder(260);
                    GetModuleFileName(NullHandleRef, stringBuilder, stringBuilder.Capacity);
                    return Path.GetDirectoryName(stringBuilder.ToString());
                }
            }
    }

Вы бы использовали его так же, как Application.StartupPath:

    Console.WriteLine("The path to this executable is: " + AppInfo.StartupPath + "\\" + System.Diagnostics.Process.GetCurrentProcess().ProcessName + ".exe");
6
user3596865

Следующая строка даст вам путь к приложению:

var applicationPath = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName)

Вышеуказанное решение работает правильно в следующих ситуациях

  • простое приложение
  • в другом домене, где Assembly.GetEntryAssembly () будет возвращать ноль
  • DLL загружается из встроенных ресурсов как байтовый массив и загружается в AppDomain как Assembly.Load (byteArrayOfEmbeddedDll)
6
user2126375

в VB.net

My.Application.Info.DirectoryPath

у меня работает (Тип приложения: Библиотека классов). Не уверен насчет C # ... Возвращает путь без имени файла в виде строки

5
dba

Assembly.GetEntryAssembly().Location или Assembly.GetExecutingAssembly().Location

Используйте в сочетании с System.IO.Path.GetDirectoryName(), чтобы получить только каталог.

Пути из GetEntryAssembly() и GetExecutingAssembly() могут отличаться, даже если в большинстве случаев каталог будет одинаковым.

С GetEntryAssembly() вы должны знать, что это может вернуть null, если модуль ввода неуправляем (т.е. исполняемый файл C++ или VB6). В этих случаях можно использовать GetModuleFileName из Win32 API:

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern int GetModuleFileName(HandleRef hModule, StringBuilder buffer, int length);
5
Herman
AppDomain.CurrentDomain.BaseDirectory

Решит проблему, ссылаясь на сторонние справочные файлы с установочными пакетами.

5
Nirav Mehta

Попробуйте эту простую строку кода:

 string exePath = Path.GetDirectoryName( Application.ExecutablePath);
2
daniele3004

Ни один из этих методов не работает в особых случаях, таких как использование символической ссылки на исполняемый файл, они возвращают местоположение ссылки, а не фактический исполняемый файл.

Так что можете использовать QueryFullProcessImageName , чтобы обойти это:

using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Diagnostics;

internal static class NativeMethods
{
    [DllImport("kernel32.dll", SetLastError = true)]
    internal static extern bool QueryFullProcessImageName([In]IntPtr hProcess, [In]int dwFlags, [Out]StringBuilder lpExeName, ref int lpdwSize);

    [DllImport("kernel32.dll", SetLastError = true)]
    internal static extern IntPtr OpenProcess(
        UInt32 dwDesiredAccess,
        [MarshalAs(UnmanagedType.Bool)]
        Boolean bInheritHandle,
        Int32 dwProcessId
    );
}

public static class utils
{

    private const UInt32 PROCESS_QUERY_INFORMATION = 0x400;
    private const UInt32 PROCESS_VM_READ = 0x010;

    public static string getfolder()
    {
        Int32 pid = Process.GetCurrentProcess().Id;
        int capacity = 2000;
        StringBuilder sb = new StringBuilder(capacity);
        IntPtr proc;

        if ((proc = NativeMethods.OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, pid)) == IntPtr.Zero)
            return "";

        NativeMethods.QueryFullProcessImageName(proc, 0, sb, ref capacity);

        string fullPath = sb.ToString(0, capacity);

        return Path.GetDirectoryName(fullPath) + @"\";
    }
}
2
colin lamarre

Вы можете использовать следующий код, вы получите полный путь к приложению:

 class Program
{
    static void Main(string[] args)
    {
        string AppPath = System.Reflection.Assembly.GetExecutingAssembly().Location;
        WriteLine($"ApplicationPath ---{AppPath}");
        //OutPut// //ApplicationPath---C:\Users\TestUser\source\repos\ThreadStack\ThreadStack\bin\Debug\ThreadStack.exe
        ReadLine();
    }
}  
0
Sunil Dhappadhule

Есть много способов получить путь к исполняемому файлу, который мы должны использовать, это зависит от наших потребностей. Вот ссылка, которая обсуждает различные методы.

Различные способы получить путь к исполняемому приложению

0
Nasir Mahmood

Я не видел, чтобы кто-нибудь преобразовывал LocalPath, предоставленный отражением .Net Core, в пригодный для использования путь System.IO, так что вот моя версия.

public static string GetApplicationRoot()
{
   var exePath = new Uri(System.Reflection.
   Assembly.GetExecutingAssembly().CodeBase).LocalPath;

   return new FileInfo(exePath).DirectoryName;

}

Это вернет полный путь в формате "C:\xxx\xxx" туда, где находится ваш код.

0
mark gamache