Как получить путь проекта во время проектирования - PullRequest
5 голосов
/ 11 марта 2010

Я использую компонент (System.ComponentModel.Component) и хочу получить путь к приложению моего проекта для создания в нем файла.

Thx

Florian

Ответы [ 10 ]

4 голосов
/ 14 декабря 2010

Единственной вещью, которая, казалось, работала (последовательно) для меня, было получение EnvDTE.DTE (от IServiceProvider, который вы получаете от EditValue ()), т.е.

EnvDTE.DTE dte = envProvider.GetService(typeof(EnvDTE.DTE)) as EnvDTE.DTE;
string dir = Path.GetDirectoryName(dte.Solution.FullName);

Когда я попытался использовать Assembly.GetXAssembly, я получил временный путь, используемый VS во время разработки.

2 голосов
/ 09 апреля 2017

Просто вызовите GetMyPath, который определен как

string GetMyPath([CallerFilePath] string from = null)
{
   return from;
}
0 голосов
/ 22 марта 2019

Добавить ссылку на envdte80, которая находится в сборках .NetFrameWork 4.5.

DTE2 dte = DesignTimeProjectPath.Processes.GetDTE();
    if (dte != null)
     {
        var solution = dte.Solution;
        if (solution != null)
         {
             string baseDir = Path.GetDirectoryName(solution.FullName);
             MessageBox.Show(baseDir);
         }
     }

  namespace DesignTimeProjectPath
    {
        /// <summary>
        /// This class takes care of fetching the correct DTE instance for the current process
        /// The current implementation works it way down from Visual Studio version 20 to 10 so
        /// it should be farely version independent
        /// </summary>
        public static class Processes
        {
            [DllImport("ole32.dll")]
            private static extern void CreateBindCtx(int reserved, out IBindCtx ppbc);
            [DllImport("ole32.dll")]
            private static extern void GetRunningObjectTable(int reserved, out IRunningObjectTable prot);

            private const int m_MaxVersion = 20;
            private const int m_MinVersion = 10;

            internal static DTE2 GetDTE()
            {
                DTE2 dte = null;

                for (int version = m_MaxVersion; version >= m_MinVersion; version--)
                {
                    string versionString = string.Format("VisualStudio.DTE.{0}.0", version);

                    dte = Processes.GetCurrent(versionString);

                    if (dte != null)
                    {
                        return dte;
                    }
                }

                throw new Exception(string.Format("Can not get DTE object tried versions {0} through {1}", m_MaxVersion, m_MinVersion));
            }

            /// <summary>
            /// When multiple instances of Visual Studio are running there also multiple DTE available
            /// The method below takes care of selecting the right DTE for the current process
            /// </summary>
            /// <remarks>
            /// Found this at: http://stackoverflow.com/questions/4724381/get-the-reference-of-the-dte2-object-in-visual-c-sharp-2010/27057854#27057854
            /// </remarks>
            private static DTE2 GetCurrent(string versionString)
            {
                Process parentProc = GetParent(Process.GetCurrentProcess());
                int parentProcId = parentProc.Id;
                string rotEntry = String.Format("!{0}:{1}", versionString, parentProcId);

                IRunningObjectTable rot;
                GetRunningObjectTable(0, out rot);

                IEnumMoniker enumMoniker;
                rot.EnumRunning(out enumMoniker);
                enumMoniker.Reset();

                IntPtr fetched = IntPtr.Zero;
                IMoniker[] moniker = new IMoniker[1];

                while (enumMoniker.Next(1, moniker, fetched) == 0)
                {
                    IBindCtx bindCtx;
                    CreateBindCtx(0, out bindCtx);
                    string displayName;
                    moniker[0].GetDisplayName(bindCtx, null, out displayName);

                    if (displayName == rotEntry)
                    {
                        object comObject;

                        rot.GetObject(moniker[0], out comObject);

                       return (EnvDTE80.DTE2)comObject;
                    }
                }

                return null;
            }

            private static Process GetParent(Process process)
            {
                var processName = process.ProcessName;
                var nbrOfProcessWithThisName = Process.GetProcessesByName(processName).Length;
                for (var index = 0; index < nbrOfProcessWithThisName; index++)
                {
                    var processIndexdName = index == 0 ? processName : processName + "#" + index;
                    var processId = new PerformanceCounter("Process", "ID Process", processIndexdName);
                    if ((int)processId.NextValue() == process.Id)
                    {
                        var parentId = new PerformanceCounter("Process", "Creating Process ID", processIndexdName);
                        return Process.GetProcessById((int)parentId.NextValue());
                    }
                }
                return null;
            }
        }
    }
0 голосов
/ 05 июня 2017

Если вы говорите о дизайнере WPF, пожалуйста, используйте свойство / тип "Context"

Подробности: - Во время разработки у вас есть экземпляр modelItem (я полагаю, вы это знаете) если нет, то вы можете создать его в реализации переопределения метода Activate

// в классе DesignAdorner

public class DesignAdorner : PrimarySelectionAdornerProvider
{
      protected override void Activate(ModelItem item)
        {
                modelItem = item;
        }
}

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

string aplicationPathDir = System.IO.Directory.GetParent(modelItem.Context.ToString()).FullName;

Дайте мне знать, если это вам не поможет.

0 голосов
/ 21 сентября 2015

Я сделал простой тест (как временный проект, я добавил строковое свойство для хранения текущего значения каталога) ( Я не описываю весь процесс привязки данных . См. Часть моего поста о привязке времени разработки / выполнения)

В пустом конструкторе главного окна класса ViewModel (посвящен привязке времени разработки)

public MainWindow_ViewModel():this(null)
{
    dtpath = Directory.GetCurrentDirectory();
    Console.WriteLine("CTor finished");
}

В файле mainwindow.xaml я добавил текстовое поле для отображения результата (не обращайте внимания на значение строки сетки)

<TextBox Text="{Binding dtpath}" Grid.Row="3"/>

И я получил представление о конструкции VS (как сказано в комментарии Флориана, но с более новым значением через 4 года): C: \ Program Files (x86) \ Microsoft Visual Studio 14.0 \ Common7 \ IDE

enter image description here

0 голосов
/ 26 октября 2012
string solutionpath = Directory.GetParent(Application.ExecutablePath).Parent.Parent.Parent.FullName;

Я думаю, что это лучшее решение, потому что вам не нужно добавлять какую-либо библиотеку, кроме "Использование System.IO":)

0 голосов
/ 22 июня 2010

Я думаю, что Роберт почти прав.

Это похоже на работу:

Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
0 голосов
/ 11 марта 2010

Взгляните на: Путь к папке проекта (bin) во время компиляции?

С помощью этой методики вы можете «создать» (один раз), а затем использовать сгенерированный файл, чтобы получить местоположение проекта в DesignTime. Это будет работать независимо от рабочей области.

0 голосов
/ 11 марта 2010

Это работает?

 New Uri(Assembly.GetCallingAssembly().CodeBase).AbsolutePath

(«CallingAssembly», потому что вы можете поместить метод для извлечения пути выполнения на уровень обслуживания (сборка))

0 голосов
/ 11 марта 2010

Использовать AppDomain.CurrentDomain.BaseDirectory.

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