C# 如何在设计时获得项目路径

C# 如何在设计时获得项目路径,c#,path,components,design-time,C#,Path,Components,Design Time,我使用一个组件(System.ComponentModel.component),我希望获得项目的应用程序路径,以便在其中创建一个文件 Thx Florian使用AppDomain.CurrentDomain.BaseDirectory。这有用吗 New Uri(Assembly.GetCallingAssembly().CodeBase).AbsolutePath (“CallingAssembly”,因为您可以将检索执行路径的方法放入服务层(assembly))请看: 使用此技术,您可以

我使用一个组件(System.ComponentModel.component),我希望获得项目的应用程序路径,以便在其中创建一个文件

Thx


Florian使用AppDomain.CurrentDomain.BaseDirectory。

这有用吗

 New Uri(Assembly.GetCallingAssembly().CodeBase).AbsolutePath
(“CallingAssembly”,因为您可以将检索执行路径的方法放入服务层(assembly))

请看:


使用此技术,您可以“构建”(一次),然后使用生成的文件在设计时获取项目位置。这将独立于工作空间工作

我认为罗伯特几乎是对的

这似乎有效:

Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)

唯一对我有效(一致)的方法是获取EnvDTE.DTE(从您从EditValue()获得的IServiceProvider),即:

当我尝试使用Assembly.GetXAssembly时,我得到了设计时使用的临时路径

string solutionpath = Directory.GetParent(Application.ExecutablePath).Parent.Parent.Parent.FullName;
我认为这是最好的解决方案,因为除了“使用System.IO”之外,您不必添加任何库:)

我做了一个简单的测试(作为一个临时设计,我添加了一个string属性来保存当前目录值)(我不描述数据绑定的所有过程。请参阅我的一些关于设计时/运行时绑定的帖子)

在主窗口ViewModel类的空构造函数中(专用于设计时绑定)

在mainwindow.xaml文件中,我添加了一个文本框来显示结果(不要介意网格行值)


我看到了VS的设计视图(如Florian的评论所述,但4年后有了更新的值): C:\ProgramFiles(x86)\Microsoft Visual Studio 14.0\Common7\IDE


只需调用定义为

string GetMyPath([CallerFilePath] string from = null)
{
   return from;
}

如果您谈论的是WPF设计器,请使用“上下文”属性/类型

详细信息:- 在设计时,您有modelItem的实例(我假设您知道它),若并没有,那个么您可以在Activate方法的覆盖实现中实例化它

//在Designator类中

public class DesignAdorner : PrimarySelectionAdornerProvider
{
      protected override void Activate(ModelItem item)
        {
                modelItem = item;
        }
}
现在,您可以使用以下单行代码访问当前应用程序路径

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

如果没有帮助,请告诉我。

添加对.NetFrameWork 4.5程序集中的envdte80的引用

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;
            }
        }
    }
dte2dte=DesignTimeProjectPath.processs.GetDTE();
如果(dte!=null)
{
var溶液=dte溶液;
如果(解决方案!=null)
{
字符串baseDir=Path.GetDirectoryName(solution.FullName);
MessageBox.Show(baseDir);
}
}
命名空间DesignTimeProjectPath
{
/// 
///此类负责为当前进程获取正确的DTE实例
///当前的实现从VisualStudio版本20一直到10,所以
///它应该是独立于版本的
/// 
公共静态类进程
{
[DllImport(“ole32.dll”)]
私有静态外部void CreateBindCtx(int保留,out IBindCtx ppbc);
[DllImport(“ole32.dll”)]
私有静态外部void GetRunningObjectTable(保留int,输出IRunningObjectTable prot);
私有常量int m_MaxVersion=20;
私有常量int m_MinVersion=10;
内部静态DTE2 GetDTE()
{
DTE2 dte=null;
对于(int version=m_MaxVersion;version>=m_MinVersion;version--)
{
字符串版本string=string.Format(“VisualStudio.DTE.{0}.0”,版本);
dte=processs.GetCurrent(versionString);
如果(dte!=null)
{
返回dte;
}
}
抛出新异常(string.Format(“无法获取DTE对象版本{0}到{1}”,m_MaxVersion,m_MinVersion));
}
/// 
///当Visual Studio的多个实例运行时,也会有多个DTE可用
///下面的方法负责为当前流程选择正确的DTE
/// 
/// 
///在以下位置找到此文件:http://stackoverflow.com/questions/4724381/get-the-reference-of-the-dte2-object-in-visual-c-sharp-2010/27057854#27057854
/// 
私有静态DTE2 GetCurrent(字符串版本字符串)
{
processparentproc=GetParent(Process.GetCurrentProcess());
int parentProcId=parentProc.Id;
string roentry=string.Format(“!{0}:{1}”,versionString,parentProcId);
IRunningObjectTable rot;
GetRunningObjectTable(0,out rot);
IEnumMoniker enumMoniker;
rot.EnumRunning(超出enumMoniker);
enumMoniker.Reset();
IntPtr fetched=IntPtr.Zero;
IMoniker[]名字=新IMoniker[1];
while(EnumMonike.Next(1,名字对象,获取)==0)
{
IBindCtx-bindCtx;
CreateBindCtx(0,out bindCtx);
字符串显示名;
名字对象[0]。GetDisplayName(bindCtx,null,out displayName);
如果(displayName==RoEntry)
{
对象与对象;
rot.GetObject(名字对象[0],out-comObject);
返回(EnvDTE80.DTE2)comObject;
}
}
返回null;
}
私有静态进程GetParent(进程进程)
{
var processName=process.processName;
var nbrOfProcessWithThisName=Process.getProcessByName(processName).Length;
for(var index=0;indexpublic class DesignAdorner : PrimarySelectionAdornerProvider
{
      protected override void Activate(ModelItem item)
        {
                modelItem = item;
        }
}
string aplicationPathDir = System.IO.Directory.GetParent(modelItem.Context.ToString()).FullName;
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;
            }
        }
    }