사용자 지정 MSBuild 작업을 만들 때 C # 코드에서 현재 프로젝트 디렉토리를 얻는 방법은 무엇입니까?


133

경로가 하드 코딩 된 외부 프로그램을 실행하는 대신 현재 Project Dir을 얻고 싶습니다. 사용자 지정 작업의 프로세스를 사용하여 외부 프로그램을 호출하고 있습니다.

어떻게해야합니까? AppDomain.CurrentDomain.BaseDirectory는 VS 2008의 위치를 ​​알려줍니다.

답변:


112

이 두 가지 방법 중 하나를 시도 할 수 있습니다.

string startupPath = System.IO.Directory.GetCurrentDirectory();

string startupPath = Environment.CurrentDirectory;

말해봐, 어느 쪽이 더 나아 보인다


85
위의이 두 가지는 bin 디렉토리를 가리 키므로, 예를 들어 전체 솔루션에 대해 하나의 bin 디렉토리를 가지고 있다면 프로젝트 디렉토리 (또는 프로젝트 디렉토리 아래의 두 레벨)를
가리 키지 않습니다.

16
테스트 탐색기를 사용할 때 두 솔루션 모두 예상대로 작동하지 않습니다.
Gucu112

264
using System;
using System.IO;

// This will get the current WORKING directory (i.e. \bin\Debug)
string workingDirectory = Environment.CurrentDirectory;
// or: Directory.GetCurrentDirectory() gives the same result

// This will get the current PROJECT directory
string projectDirectory = Directory.GetParent(workingDirectory).Parent.FullName;

25
Directory.GetParent () +1이므로 \ bin \ Debug 디렉토리를 얻지
못합니다

5
사용자 정의 대상 CPU를 사용하면 어떻게됩니까? 예를 들어 빌드를 x64를 대상으로 설정하면 그 사이에 다른 폴더가 만들어집니다.
사미르 아귀 아르

3
이것이 정답입니다. 허용 된 답변은 프로젝트 디렉토리가 아닌 bin 디렉토리의 경로를 리턴합니다.
pookie

@ pookie의 대답은 내 경우에 재귀 적으로 잘못되었습니다. 이것은 * / {project} / bin 폴더를 제공하므로 .parent를 연결해야합니다.
Prinny 선장

1
잘 작동하고이 허용 대답해야한다
아 쇼크 쿠마르 Ganesan

42

프로젝트가 IIS Express에서 실행중인 경우 프로젝트가 Environment.CurrentDirectory있는 위치가 아니라 IIS Express가있는 위치 (기본 경로는 C : \ Program Files (x86) \ IIS Express )를 가리킬 수 있습니다.


이것은 아마도 다양한 종류의 프로젝트에 가장 적합한 디렉토리 경로 일 것입니다.

AppDomain.CurrentDomain.BaseDirectory

이것이 MSDN 정의입니다.

어셈블리 확인자가 어셈블리를 검사하는 데 사용하는 기본 디렉터리를 가져옵니다.


21
9 년 후 누군가가 실제로 답을 얻습니다.
Jeff Davis

.NET Core에는 AppDomain이 없습니다. 이런 식으로해야합니다. System.Runtime.Loader.AssemblyLoadContext.Default.Unloading + = context => InvokeBatchProcessors ();
대기 시간

그 외에도 Visual Studio SDK를 사용하고 DTE2를 사용하여 솔루션 구성 레이아웃에서 위치를 가져올 수 있습니다.
대기 시간

2
@Latency .net 핵심 3 WPF 프로젝트
Alexander

예, 사양을 읽었습니다. 3,0과 같은 것은 확실하지 않습니다. 그 이후로 사용하고 있습니다. 매우 기쁜. 이 3.0 이전 버전을 게시 했으므로 명확하게 해 주셔서 감사합니다.
대기 시간

18

또한 현재 실행중인 디렉토리에서 두 레벨을 탐색하여 프로젝트 디렉토리를 제공합니다 (모든 빌드에 대해 프로젝트 디렉토리를 반환하지는 않지만 가장 일반적입니다).

System.IO.Path.GetFullPath(@"..\..\")

물론 이것을 일종의 유효성 검사 / 오류 처리 논리 안에 포함하고 싶을 것입니다.


IMO는 가장 유연한 방법입니다. 단위 테스트 및 통합 테스트에서 이것을 사용하고 있습니다. 실제로 어느 경로가 하나의 폴더보다 깊습니다.
Soleil-Mathieu Prévot

이것은 어떤 이유로 든 루트 드라이브를 제공합니다.
Prinny 선장

10

솔루션이있는 디렉토리가 무엇인지 아는 경우 다음을 수행해야합니다.

 var parent = Directory.GetParent(Directory.GetCurrentDirectory()).Parent;
            if (parent != null)
            {
                var directoryInfo = parent.Parent;
                string startDirectory = null;
                if (directoryInfo != null)
                {
                    startDirectory = directoryInfo.FullName;
                }
                if (startDirectory != null)
                { /*Do whatever you want "startDirectory" variable*/}
            }

GetCurrrentDirectory()method 만 사용 하면 디버깅 또는 릴리스 여부에 관계없이 빌드 폴더가 생성됩니다. 도움이 되었기를 바랍니다. 유효성 검사를 잊어 버린 경우 다음과 같습니다.

var startDirectory = Directory.GetParent(Directory.GetCurrentDirectory()).Parent.Parent.FullName;

5

나도 이것을 찾고 있었다. HWC를 실행하는 프로젝트가 있는데 웹 사이트를 앱 트리 외부에 유지하고 싶지만 디버그 (또는 릴리스) 디렉토리에 유지하고 싶지 않습니다. FWIW에서 허용되는 솔루션 (및이 솔루션도)은 실행 파일이 실행중인 디렉토리 만 식별합니다.

그 디렉토리를 찾기 위해

string startupPath = System.IO.Path.GetFullPath(".\\").

5

Gucu112의 답변을 기반으로 하지만 .NET Core Console / Window 응용 프로그램의 경우 다음과 같아야합니다.

string projectDir = 
    Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"..\..\.."));

xUnit 프로젝트에서 .NET Core Window Application을 사용하고 있습니다.


4

이 작업을 수행하는 다른 방법

string startupPath = System.IO.Directory.GetParent(@"./").FullName;

bin 폴더의 경로를 얻으려면

string startupPath = System.IO.Directory.GetParent(@"../").FullName;

아마도 더 좋은 방법이있을 것입니다 =)


4

또 다른 불완전한 해결책 (그러나 아마도 다른 것보다 약간 더 완벽에 가깝습니다) :

    protected static string GetSolutionFSPath() {
        return System.IO.Directory.GetParent(System.IO.Directory.GetCurrentDirectory()).Parent.Parent.FullName;
    }
    protected static string GetProjectFSPath() {
        return String.Format("{0}\\{1}", GetSolutionFSPath(), System.Reflection.Assembly.GetExecutingAssembly().GetName().Name);
    }

이 버전은 현재 프로젝트가 솔루션 용이 아닌 경우에도 현재 프로젝트의 폴더를 반환합니다 Startup Project.

이것의 첫 번째 결함은 모든 오류 검사를 건너 뛰었다는 것입니다. 그것은 쉽게 고칠 수 있지만 드라이브의 루트 디렉토리에 프로젝트를 저장하거나 경로의 접합을 사용하고 (이 접합은 솔루션 폴더의 후손) 문제가 될 수 있으므로이 시나리오는 거의 없습니다 . 어쨌든 Visual Studio가 이러한 설정 중 하나를 처리 할 수 ​​있는지 확실하지 않습니다.

발생할 수있는 또 다른 문제는 프로젝트 이름 의 폴더 이름과 일치 프로젝트를 찾을 수 있다는 것입니다.

또 다른 문제는 프로젝트가 솔루션 폴더 안에 있어야한다는 것입니다. 이것은 일반적으로 문제가되지 않지만 Add Existing Project to Solution옵션을 사용 하여 프로젝트를 솔루션에 추가 한 경우 솔루션 구성 방식이 아닐 수 있습니다.

마지막으로, 응용 프로그램에서 작업 디렉토리를 수정하는 경우이 값은 현재 작업 디렉토리를 기준으로 결정되므로이 값을 저장하기 전에 저장해야합니다.

물론 이것은 프로젝트 속성 대화 상자에서 프로젝트 Build-> Output path또는 Debug-> Working directory옵션 의 기본값을 변경해서는 안된다는 것을 의미합니다 .


4

이 간단한 시도

HttpContext.Current.Server.MapPath("~/FolderName/");

4

이 솔루션은 C #을 통해 ASP.NET MVC5가있는 Develop 및 TEST 및 PROD 서버에서 나에게 효과적입니다 .

var projectDir = Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory);

프로젝트 구성 파일에 프로젝트 디렉토리 가 필요한 경우 다음을 사용하십시오.

$(ProjectDir)

3

대답을 도출하기 위해 공개 문자열의 미국에 관한 첫 번째 대답을 마무리 한 후에는 원하는 결과를 얻기 위해 레지스트리에서 값을 읽을 수 있다고 생각했습니다. 결과적으로 그 경로는 더 짧았습니다.

먼저 레지스트리 작업을 수행 할 수 있도록 Microsoft.Win32 네임 스페이스를 포함해야합니다.

using Microsoft.Win32;    // required for reading and / or writing the registry

주요 코드는 다음과 같습니다.

RegistryKey Projects_Key = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\VisualStudio\9.0", false);
string DirProject = (string)Projects_Key.GetValue(@"DefaultNewProjectLocation");

이 답변에 대한 참고 사항 :

Visual Studio 2008 Professional Edition을 사용하고 있습니다. 다른 버전 (예 : 2003, 2005, 2010 등)을 사용하는 경우 하위 키 문자열의 '버전'부분 (예 : 8.0, 7.0 등)을 수정하지 않아도됩니다.

내 대답 중 하나를 사용하고 너무 많이 묻지 않으면 사용 한 방법과 이유를 알고 싶습니다. 행운을 빕니다.

  • dm

3

나는 비슷한 상황을 겪었고 과일이없는 Googles 후에 프로젝트 경로를 얻기 위해 디버그 / 릴리스 경로의 문자열 값을 수정하는 공개 문자열을 선언했습니다. 이 방법을 사용하면 이점은 현재 프로젝트 디렉토리를 사용하므로 디버그 디렉토리 또는 릴리스 디렉토리에서 작업하는 경우에는 중요하지 않습니다.

public string DirProject()
{
    string DirDebug = System.IO.Directory.GetCurrentDirectory();
    string DirProject = DirDebug;

    for (int counter_slash = 0; counter_slash < 4; counter_slash++)
    {
        DirProject = DirProject.Substring(0, DirProject.LastIndexOf(@"\"));
    }

    return DirProject;
}

그러면 한 줄만 사용하여 원할 때마다 전화를 걸 수 있습니다.

string MyProjectDir = DirProject();

대부분의 경우 작동 합니다.


3

이것을 사용하여 Project 디렉토리를 얻으십시오 (나를 위해 일함).

string projectPath = 
    Directory.GetParent(Directory.GetCurrentDirectory()).Parent.FullName;

3
using System;
using System.IO;

// Get the current directory and make it a DirectoryInfo object.
// Do not use Environment.CurrentDirectory, vistual studio 
// and visual studio code will return different result:
// Visual studio will return @"projectDir\bin\Release\netcoreapp2.0\", yet 
// vs code will return @"projectDir\"
var currentDirectory = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory);

// On windows, the current directory is the compiled binary sits,
// so string like @"bin\Release\netcoreapp2.0\" will follow the project directory. 
// Hense, the project directory is the great grand-father of the current directory.
string projectDirectory = currentDirectory.Parent.Parent.Parent.FullName;

2

작업을 수행하기 위해 다음 솔루션을 사용했습니다.

string projectDir =
    Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"..\.."));

2

시험:

var pathRegex = new Regex(@"\\bin(\\x86|\\x64)?\\(Debug|Release)$", RegexOptions.Compiled);
var directory = pathRegex.Replace(Directory.GetCurrentDirectory(), String.Empty);

이것은 가능한 x86 또는 x64 빌드를 고려하는 다른 솔루션과 다른 솔루션입니다.


이 솔루션은 TargetFramework가 경로에 포함 된 새 csproj 파일에도 거의 있습니다.
Glenn Watson

1
새로운 .netcore 스타일 형식의 경우 새로운 Regex (@ "\\ bin (\\ x86 | \\ x64)? \ (Debug | Release) (\ [a-zA-Z0-9.] *)? $" , RegexOptions.Compiled)
Glenn Watson

1

최고의 솔루션

string PjFolder1 =
    Directory.GetParent(AppDomain.CurrentDomain.BaseDirectory).
        Parent.Parent.FullName;

다른 솔루션

string pjFolder2 = Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(
                System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase)));

그것을 테스트하십시오 .AppDomain.CurrentDomain.BaseDirectory는 과거 프로젝트에서 나를 위해 일했습니다. 이제 디버그 폴더를 얻습니다 .... 선택한 GOOD 답변은 작동하지 않습니다!.

//Project DEBUG folder, but STILL PROJECT FOLDER
string pjDebugFolder = AppDomain.CurrentDomain.BaseDirectory;

//Visual studio folder, NOT PROJECT FOLDER
//This solutions just not work
string vsFolder = Directory.GetCurrentDirectory();
string vsFolder2 = Environment.CurrentDirectory;
string vsFolder3 = Path.GetFullPath(".\\");   

//Current PROJECT FOLDER
string ProjectFolder = 
    //Get Debug Folder object from BaseDirectory ( the same with end slash)
    Directory.GetParent(pjDebugFolder).
    Parent.//Bin Folder object
    Parent. //Project Folder object
    FullName;//Project Folder complete path

0

bin 출력 경로가 무엇이든 관계없이 소스 프로젝트 디렉토리를 얻으려면 다음을 수행하십시오.

  1. 사전 빌드 이벤트 명령 행 추가 (Visual Studio : 프로젝트 특성-> 빌드 이벤트) :

    echo $(MSBuildProjectDirectory) > $(MSBuildProjectDirectory)\Resources\ProjectDirectory.txt

  2. ProjectDirectory.txt프로젝트의 Resources.resx에 파일을 추가하십시오 (아직 존재하지 않는 경우 프로젝트-> 새 항목 추가-> 자원 파일을 마우스 오른쪽 단추로 클릭하십시오).

  3. 로 코드에서 액세스하십시오 Resources.ProjectDirectory.

-1

이것은 VS2017 w / SDK Core MSBuild 구성에서 작동합니다.

EnvDTE / EnvDTE80 패키지에서 NuGet이 필요합니다.

COM 또는 interop을 사용하지 마십시오. 무엇이든 .. 쓰레기!

 internal class Program {
    private static readonly DTE2 _dte2;

    // Static Constructor
    static Program() {
      _dte2 = (DTE2)Marshal.GetActiveObject("VisualStudio.DTE.15.0");
    }


    private static void FindProjectsIn(ProjectItem item, List<Project> results) {
      if (item.Object is Project) {
        var proj = (Project) item.Object;
        if (new Guid(proj.Kind) != new Guid(Constants.vsProjectItemKindPhysicalFolder))
          results.Add((Project) item.Object);
        else
          foreach (ProjectItem innerItem in proj.ProjectItems)
            FindProjectsIn(innerItem, results);
      }

      if (item.ProjectItems != null)
        foreach (ProjectItem innerItem in item.ProjectItems)
          FindProjectsIn(innerItem, results);
    }


    private static void FindProjectsIn(UIHierarchyItem item, List<Project> results) {
      if (item.Object is Project) {
        var proj = (Project) item.Object;
        if (new Guid(proj.Kind) != new Guid(Constants.vsProjectItemKindPhysicalFolder))
          results.Add((Project) item.Object);
        else
          foreach (ProjectItem innerItem in proj.ProjectItems)
            FindProjectsIn(innerItem, results);
      }

      foreach (UIHierarchyItem innerItem in item.UIHierarchyItems)
        FindProjectsIn(innerItem, results);
    }


    private static IEnumerable<Project> GetEnvDTEProjectsInSolution() {
      var ret = new List<Project>();
      var hierarchy = _dte2.ToolWindows.SolutionExplorer;
      foreach (UIHierarchyItem innerItem in hierarchy.UIHierarchyItems)
        FindProjectsIn(innerItem, ret);
      return ret;
    }


    private static void Main() {
      var projects = GetEnvDTEProjectsInSolution();
      var solutiondir = Path.GetDirectoryName(_dte2.Solution.FullName);

      // TODO
      ...

      var project = projects.FirstOrDefault(p => p.Name == <current project>);
      Console.WriteLine(project.FullName);
    }
  }

-6

Directory.GetParent (Directory.GetCurrentDirectory ()). Parent.Parent.Parent.Parent.FullName

프로젝트 디렉토리를 제공합니다.


77
정말? 부모님이없는 것 같습니다
sean
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.