843

콘솔 응용 프로그램에서 응용 프로그램의 경로를 찾으려면 어떻게합니까?

에서Windows Forms, 나는 사용할 수있다.Application.StartupPath현재 경로를 찾을 수 있지만 콘솔 응용 프로그램에서는 사용할 수없는 것 같습니다.


  • 대상 (클라이언트, 개발) 컴퓨터에 .NET Framework를 설치합니까? 당신의 대답이 사실이라면; 따라서 System.Windows.Forms.dll에 대한 참조를 추가하고 Application.StartupPath! 미래의 예외를 더 이상 없애고 싶다면이 방법이 가장 좋습니다! - Ehsan Mohammadi
  • AppDomain.BaseDirectory는 app 디렉토리입니다. 응용 프로그램은 VS env 및 Win env에서 다르게 동작 할 수 있습니다. 하지만 AppDomain은 application.path와 같지 않아야합니다.하지만이 것이 IIS에만 국한되지 않기를 바랍니다. - Mertuarez

26 답변


1060

System.Reflection.Assembly.GetExecutingAssembly().Location1

그것과 결합해라.System.IO.Path.GetDirectoryName원하는 모든 것이 디렉토리라면.

1Mr.Mindor의 의견에 따르면 :

System.Reflection.Assembly.GetExecutingAssembly().Location실행중인 어셈블리가 현재 위치한 위치를 반환합니다. 실행되지 않을 때 어셈블리가있는 위치 일 수도 있고 없을 수도 있습니다. 섀도 복사 어셈블리의 경우 임시 디렉터리에 경로가 생깁니다.System.Reflection.Assembly.GetExecutingAssembly().CodeBase어셈블리의 '영구적 인'경로를 반환합니다.


  • System.Reflection.Assembly.GetExecutingAssembly (). 위치는 실행중인 어셈블리가있는 위치를 반환합니다.현재이 위치는 실행하지 않을 때 어셈블리가있는 위치 일 수도 있고 없을 수도 있습니다. 섀도 복사 어셈블리의 경우 임시 디렉터리에 경로가 생깁니다. System.Reflection.Assembly.GetExecutingAssembly (). CodeBase는 & # 39;permenant& # 39; 어셈블리의 경로. - Mr.Mindor
  • @SamGoldberg : 사용 방법에 따라 달라집니다.stackoverflow.com/q/1068420/391656. 아니면 할 수 ... 새 Uri (System.Reflection.Assembly.GetExecutingAssembly (). CodeBase) .LocalPath - Mr.Mindor
  • 어떤 이유로 든, VS2013 (적어도 가지고있는 복사본)에서는 Intellisense가 System.Reflection.Assembly를 지나서 작동하지 않습니다. GetExeuctingAssembly ()가 있지만 보이지 않습니다. - PseudoToad
  • GetExecutingAssembly그 어셈블리를 반환합니다.현재 실행중인 코드가 들어 있습니다.. 이것은 반드시 콘솔이 아닐 수도 있습니다..exe어셈블리. 그것은 완전히 다른 위치에서로드 된 어셈블리 일 수 있습니다. 당신이 사용해야합니다GetEntryAssembly! 또한 유의하십시오.CodeBase어셈블리가 GAC에있을 때 설정되지 않을 수 있습니다. 더 나은 대안은AppDomain.CurrentDomain.BaseDirectory. - bitbonk
  • 복사하기 쉽도록 4 칸에 코드를 작성하십시오. - fnc12

374

다음 코드를 사용하여 현재 응용 프로그램 디렉토리를 가져올 수 있습니다.

AppDomain.CurrentDomain.BaseDirectory


  • 이것을 사용하지 마십시오. BaseDirectory는 런타임에 설정할 수 있습니다. 올바른지 보장 할 수 없습니다 (수락 된 답변과 같습니다). - usr
  • +1 이것은 쉐도우 복사를 보완하기 때문에 원하는 답변 일 가능성이 큽니다. - George Mauer
  • @usr 왜 그렇게 생각하니?BaseDirectory런타임에 설정할 수 있습니까? 그것은 단지 getter가 있습니다. - bitbonk
  • @bitbonk은 appdomain 생성시 설정할 수 있습니다. - usr
  • BaseDirectory는 * .lnk 파일의 & quot; 시작 위치 & quot;에서 변경할 수 없습니다. 들? - Alexander

133

응용 프로그램의 디렉토리를 찾는 데는 두 가지 옵션이 있습니다. 선택한 옵션은 용도에 따라 다릅니다.

// 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);


  • 단지 몇 가지 다른 선택 사항이 게시됨에 따라 2 가지 옵션 이상이 분명히 있습니다. - vapcguy
  • 해당 경로로하려는 작업이 URI 형식을 지원하지 않는 경우var localDirectory = new Uri(directory).LocalPath; - Okuma.Scott
  • 이것은 잘못된 것입니다. 실행 파일은 .NET 어셈블리가 아닙니다. 올바른 대답은 환경을 확인하고 명령 줄을 검사하는 것입니다. - mark

73

아마 조금 늦었 겠지만 이것은 언급할만한 가치가 있습니다.

Environment.GetCommandLineArgs()[0];

아니면 그냥 정확하게 디렉토리 경로를 얻으려면 :

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

편집하다:

상당수의 사람들이GetCommandLineArgs프로그램 명을 돌려주는 것이 보증되지 않습니다. 만나다명령 행의 첫 번째 단어는 규칙에 의해서만 프로그램 이름입니다. 이 기사는 "극히 소수의 Windows 프로그램이이 버크를 사용하지만 (나는 자신을 알지 못한다"). 그래서 '스푸핑'하는 것이 가능합니다.GetCommandLineArgs,하지만 우리는 콘솔 응용 프로그램에 대해 이야기하고 있습니다. 콘솔 앱은 대개 빠르고 빠릅니다. 그래서 이것은 KISS 철학에 꼭 맞습니다.


  • 그리고 아마도 this : path = Environment.GetCommandLineArgs () [0] .Substring (0, iniFilePath.LastIndexOf ( "\\") + 1); - fabspro
  • 당신이 암시하는 상황은 매우 이론적입니다. 콘솔 응용 프로그램의 컨텍스트에서는 다른 방법을 사용하는 것이 실제로 의미가 없습니다. 계속 간단하게! - Steve Mc
  • @usr mmm - taskmgr cmdline 열을 보면 내가 말한 것을 백업합니다. exe 이름 만있는 몇 가지 시스템 서비스. 신경 쓰지 마. 제가 말하고자하는 바는 콘솔 애플리케이션을 개발할 때 상황을보다 복잡하게 만들 필요가 없다는 것입니다. 특히 우리가 이미 정보를 가지고있을 때. 이제 GetCommandLineArgs를 속일 수있는 방법으로 콘솔 응용 프로그램을 실행하는 경우 이미 농구를 뛰어 넘고 있고 콘솔 응용 프로그램이 올바른 방법인지 스스로에게 물어볼 필요가 있습니다. - Steve Mc
  • 귀하의 & quot; 간단한 & quot; 솔루션에는 두 가지 메소드 호출이 포함됩니다. "복잡한" 솔루션에는 두 가지 메소드 호출이 포함됩니다. 실질적인 차이는 없지만 - "단순한" 솔루션을 사용하면 프로그램을 작성할 때 자신이 통제 할 수없는 특정 상황에서 잘못된 대답을 줄 수 있습니다. 위험을 감수하는 이유는 무엇입니까? 다른 두 개의 메소드 호출을 사용하면 프로그램이 복잡해지지는 않지만 더 안정적이게됩니다. - Chris
  • 내 시나리오에 대한 작업, 다른 솔루션 않았다, 그래서 다른 대안을 제공 주셔서 감사합니다 :-) 나는 ReSharper 테스트 러너를 사용하여 MS 단위 테스트를 실행하고 특정 .dll이 실행 디렉터리에 있어야 테스트중인 코드. ..and Assembly.GetExecutingDirectory ()는 이상하게 다른 결과를 반환합니다. - wallismark

40

누구 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"에서 실행되므로 첫 번째 솔루션은 웹 앱에 적합하지 않습니다.


35

위의 대답은 내가 필요로했던 것의 90 % 였지만, 나를위한 일반적인 경로 대신에 우리를 돌려 줬다.

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;


  • 문제의 exe가 Windows 서비스이고 현재 디렉토리가 C : \ Windows \ system32를 반환하는 경우에도 잘 작동합니다. 위의 코드는 exe의 실제 위치를 반환합니다. - DaImTo
  • 그런 다음 뭔가를하려고 할 때를 제외하고File.CreateDirectory(path)URI 경로를 허용하지 않는다는 예외가 발생합니다 ... - vapcguy
  • 불행히도 조각 식별자가 포함 된 경로에서는 작동하지 않습니다 (#캐릭터). 식별자와 그 뒤의 모든 것은 결과 경로에서 잘립니다. - Mark
  • 스왑하지 않는 이유는 무엇인가요?new UriSystem.IO.Path.GetDirectoryName? 그건 당신에게 일반적인 경로 문자열 대신Uri. - Timo
  • 나는 이것을 가장 좋은 것으로 안다. 이 같은 접근 방식은 모든 환경에서 나를 위해 안정적으로 작동했습니다. 제작, 로컬 디버깅, 유닛 테스트 ... 유닛 테스트에 포함 된 콘텐츠 파일 (& quot; 콘텐츠 - 더 새로운 경우 복사)을 열고 싶습니까? 그것이있다. - Timo

27

다음과 같이 할 수 있습니다.

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


20

대신이 것을 사용할 수 있습니다.

System.Environment.CurrentDirectory


  • 이렇게하면 실행 파일의 폴더가 생성됩니다. - Iain
  • 뭔가가 Directory.SetCurrentDirectory ()를 호출하지 않으면 ... - Matthew Watson
  • @ 매튜 왓슨 또는 심지어 간단하게, 프로그램이 다른 폴더에서 실행되었습니다 ... - Ohad Schneider

18

콘솔 응용 프로그램의 경우 다음을 시도 할 수 있습니다.

System.IO.Directory.GetCurrentDirectory();

출력 (로컬 컴퓨터) :

c : \ users \ xxxxxxx \ documents \ visual studio 2012 \ Projects \ ImageHandler \ GetDir \ bin \ Debug

또는 시도해 볼 수 있습니다 (끝에 백 슬래시가 추가로 있음).

AppDomain.CurrentDomain.BaseDirectory

산출:

c : \ users \ xxxxxxx \ documents \ visual 스튜디오 2012 \ Projects \ ImageHandler \ GetDir \ bin \ Debug \


13

이 코드를 사용하여 솔루션을 얻었습니다.

AppDomain.CurrentDomain.BaseDirectory


9

.NET Core 호환 방법을 찾고 있다면

System.AppContext.BaseDirectory

이것은 .NET Framework 4.6 및 .NET Core 1.0 (및 .NET Standard 1.3)에서 소개되었습니다. 만나다:AppContext.BaseDirectory 속성.

에 따르면이 페이지,

이것은 .NET Core의 AppDomain.CurrentDomain.BaseDirectory를 대체합니다.


7

exe를 더블 클릭하여 호출해야하는 경우이 코드를 사용합니다.

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


  • 결과에서 임의의 디렉토리를 얻을 수 있기 때문에 이것은 올바르지 않습니다. - amuliar

7

나는 사용했다.

System.AppDomain.CurrentDomain.BaseDirectory

내가 응용 프로그램 폴더에 상대적인 경로를 찾고 싶을 때. 이것은 ASP.Net 및 winform 응용 프로그램 모두에서 작동합니다. 또한 System.Web 어셈블리에 대한 참조가 필요하지 않습니다.


7

프로젝트 참조에 간단히 추가 할 수 있습니다.System.Windows.Forms그런 다음System.Windows.Forms.Application.StartupPath평소처럼

그래서, 더 복잡한 방법이나 반사를 사용하지 않아도됩니다.


  • 그걸 사용했는데 잘 작동합니다. 그러나 한 번은 단위 테스트 프로젝트에서이 방법을 사용했습니다. 물론 C : \ PROGRAM FILES (X86) \ MICROSOFT VISUAL STUDIO 14.0 \ COMMON7 \ IDE \ COMMONEXTENSIONS \ MICROSOFT \ TESTWINDOW 파일을 찾고 있기 때문에 실패했습니다. - ainasiart

6

내 말은 왜 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");


  • 왜 이렇게 많은 .NET이있을 때 p / invoke를할까요? - ProfK
  • 왜 안되니? - user3596865
  • @ user3596865 Windows에 대한 의존성이 높으며 DNX 또는 Mono와 호환되지 않기 때문에 그리고 아마도 미래의 Windows 버전에 큰 변화가있을 것입니다. 그래서 다시 : 왜 우리는 여기서 pinvoke를 사용해야합니까? - Ben

4

Assembly.GetEntryAssembly().Location또는Assembly.GetExecutingAssembly().Location

함께 사용하여System.IO.Path.GetDirectoryName()디렉토리 만 가져 오기.

에서 경로GetEntryAssembly()GetExecutingAssembly()비록 대부분의 경우 디렉토리가 동일 할지라도 다를 수 있습니다.

GetEntryAssembly()당신은 이것이 돌아올 수 있다는 것을 알고 있어야합니다.null엔트리 모듈이 관리되지 않는 경우 (즉, C ++ 또는 VB6 실행 파일). 이러한 경우에는GetModuleFileNameWin32 API에서 :

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


4

AppDomain.CurrentDomain.BaseDirectory

설치 패키지와 함께 타사 참조 파일을 참조하도록이 문제를 해결합니다.


  • 이 답변은 이미 5 년 전에 한 번 이상 제안되었습니다. - P-L

3

VB.net에서

My.Application.Info.DirectoryPath

나를 위해 작동합니다 (응용 프로그램 유형 : 클래스 라이브러리). C #에 대한 확신이 없습니다 ... 문자열없이 파일 이름이없는 경로를 반환합니다.


2

이러한 방법은 exe에 대한 심볼릭 링크를 사용하는 것과 같은 특별한 경우에는 작동하지 않으며 실제 exe가 아닌 링크의 위치를 반환합니다.

그래서 사용할 수 있습니다.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

다음과 같은 간단한 코드 행을 사용해보십시오.

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


2

다음 행은 응용 프로그램 경로를 제공합니다.

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

위의 솔루션은 다음 상황에서 제대로 작동합니다.

  • 간단한 앱
  • Assembly.GetEntryAssembly ()가 null을 반환하는 다른 도메인에서
  • DLL은 바이트 배열로 포함 리소스에서로드되고 Assembly.Load (byteArrayOfEmbeddedDll)로 AppDomain에로드됩니다.


0

나는 .NET Core reflection에서 제공하는 LocalPath를 사용 가능한 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

실행 경로를 얻는 방법은 여러 가지가 있습니다. 우리가 사용해야하는 방법은 여기에 필요한 다른 방법을 설명하는 링크입니다.

응용 프로그램 실행 경로를 가져 오는 여러 가지 방법


0

다음 코드를 사용하면 응용 프로그램의 전체 경로를 얻을 수 있습니다.

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


-1

다음은 함께 작동하는 신뢰할 수있는 솔루션입니다.32 비트64 비트응용 프로그램.

다음 참조를 추가하십시오.

System.Diagnostics를 사용하여;

using System.Management;

이 메소드를 프로젝트에 추가하십시오.

public static string GetProcessPath(int processId)
{
    string MethodResult = "";
    try
    {
        string Query = "SELECT ExecutablePath FROM Win32_Process WHERE ProcessId = " + processId;

        using (ManagementObjectSearcher mos = new ManagementObjectSearcher(Query))
        {
            using (ManagementObjectCollection moc = mos.Get())
            {
                string ExecutablePath = (from mo in moc.Cast<ManagementObject>() select mo["ExecutablePath"]).First().ToString();

                MethodResult = ExecutablePath;

            }

        }

    }
    catch //(Exception ex)
    {
        //ex.HandleException();
    }
    return MethodResult;
}

이제 다음과 같이 사용하십시오.

int RootProcessId = Process.GetCurrentProcess().Id;

GetProcessPath(RootProcessId);

프로세스의 ID를 알고있는 경우이 메서드는 해당 ExecutePath를 반환합니다.

관심있는 사람들을위한 추가 기능 :

Process.GetProcesses() 

... 현재 실행중인 모든 프로세스의 배열을 제공합니다.

Process.GetCurrentProcess()

... 귀하의 정보와 함께 현재 프로세스를 제공합니다. Id 등, 또한 제한된 제어 등을 포함한다. 죽이기 등 *


-5

솔루션 탐색기를 사용하여 프로젝트 내에서 리소스로 폴더 이름을 생성 한 다음 리소스 내에 파일을 붙여 넣을 수 있습니다.

private void Form1_Load(object sender, EventArgs e) {
    string appName = Environment.CurrentDirectory;
    int l = appName.Length;
    int h = appName.LastIndexOf("bin");
    string ll = appName.Remove(h);                
    string g = ll + "Resources\\sample.txt";
    System.Diagnostics.Process.Start(g);
}


  • Environment.CurrentDirectory를 사용하는 것은 매우 잘못되었으므로 이것을 사용하지 마십시오! 이 경로는 런타임에 변경 될 수 있습니다. 시작시에도 비 결정적입니다. - usr

연결된 질문


관련된 질문

최근 질문