Как получить каталог текущего проекта из кода C # при создании пользовательской задачи MSBuild? - PullRequest
103 голосов
/ 03 мая 2009

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

Как бы я это сделал? AppDomain.CurrentDomain.BaseDirectory просто дает мне местоположение VS 2008.

Ответы [ 20 ]

3 голосов
/ 15 февраля 2012

После того, как я наконец закончил полировать свой первый ответ, касающийся использования открытых строк, чтобы получить ответ, я понял, что вы, вероятно, можете прочитать значение из реестра, чтобы получить желаемый результат. Оказывается, этот маршрут был еще короче:

Во-первых, вы должны включить пространство имен 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 и т. Д.), Вам, возможно, придется изменить часть 'version' строки SubKey (т. Е. 8.0, 7.0; и т. Д.).

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

  • дм
3 голосов
/ 12 августа 2015

Используйте это, чтобы получить каталог проекта (работал для меня):

string projectPath = 
    Directory.GetParent(Directory.GetCurrentDirectory()).Parent.FullName;
2 голосов
/ 25 декабря 2018

Попробуйте:

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

Это решение, отличное от других, также учитывает возможность сборки x86 или x64.

2 голосов
/ 14 октября 2018

На основании ответа Gucu112 , но для .NET Core Console / Window приложения оно должно быть:

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

Я использую это в проекте xUnit для Windows Window Window Application.

2 голосов
/ 19 сентября 2018

Я использовал следующее решение, чтобы выполнить работу:

string projectDir =
    Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"..\.."));
0 голосов
/ 19 марта 2019
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;
0 голосов
/ 29 декабря 2018

Если вы действительно хотите получить каталог исходного проекта, независимо от того, какой путь вывода для бина установлен:

  1. Добавление командной строки события перед сборкой (Visual Studio: Свойства проекта -> События сборки):

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

  2. Добавьте файл ProjectDirectory.txt в Resources.resx проекта (если он еще не существует, щелкните правой кнопкой мыши проект -> Добавить новый элемент -> Файл ресурсов)

  3. Доступ из кода с Resources.ProjectDirectory.
0 голосов
/ 29 ноября 2018

Работает на VS2017 с конфигурациями MSKuild SDK Core.

Вам необходим NuGet в пакетах EnvDTE / EnvDTE80.

Не используйте COM или взаимодействие. что угодно .... фигня !!

 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);
    }
  }
0 голосов
/ 04 сентября 2018

Лучшее решение

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 работал для меня в прошлом проекте, теперь я получаю папку отладки .... выбранный ХОРОШИЙ ответ просто НЕ РАБОТАЕТ!.

//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 голосов
/ 23 ноября 2010

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

Даст вам каталог проекта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...