我希望获取当前项目目录而不是在代码中直接写入外部程序路径。我通过自定义任务中的进程来调用外部程序。
如何实现呢?使用AppDomain.CurrentDomain.BaseDirectory仅会返回VS 2008的位置。
我希望获取当前项目目录而不是在代码中直接写入外部程序路径。我通过自定义任务中的进程来调用外部程序。
如何实现呢?使用AppDomain.CurrentDomain.BaseDirectory仅会返回VS 2008的位置。
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 bin directory (ie ../bin/)
string projectDirectory = Directory.GetParent(workingDirectory).Parent.FullName;
// This will get the current PROJECT directory
string projectDirectory = Directory.GetParent(workingDirectory).Parent.Parent.FullName;
您可以尝试以下两种方法之一。
string startupPath = System.IO.Directory.GetCurrentDirectory();
string startupPath = Environment.CurrentDirectory;
告诉我,你觉得哪个更好。Environment.CurrentDirectory
可能指向IIS Express的位置(默认路径为C:\Program Files (x86)\IIS Express),而不是项目所在的位置。
AppDomain.CurrentDomain.BaseDirectory
这是MSDN的定义。
获取程序集解析程序用于探测程序集的基目录。
获取C#项目根目录的正确1方法是利用[CallerFilePath]
属性获取源文件的完整路径名,然后从中减去文件名加扩展名,留下项目路径。
以下是实际上的做法:
在您的项目根目录中,添加名为ProjectSourcePath.cs
的文件,并将以下内容添加到其中:
internal static class ProjectSourcePath
{
private const string myRelativePath = nameof(ProjectSourcePath) + ".cs";
private static string? lazyValue;
public static string Value => lazyValue ??= calculatePath();
private static string calculatePath()
{
string pathName = GetSourceFilePathName();
Assert( pathName.EndsWith( myRelativePath, StringComparison.Ordinal ) );
return pathName.Substring( 0, pathName.Length - myRelativePath.Length );
}
}
如果您的C#版本不够新,没有#nullable enable
功能,那么字符串string?
就需要移除?
。
Assert()
函数是我自己写的,你可以用你自己的函数替换它,或者如果你喜欢冒险的话,也可以省略它。
函数GetSourceFilePathName()
的定义如下:
using System.Runtime.CompilerServices
public static string GetSourceFilePathName( [CallerFilePath] string? callerFilePath = null ) //
=> callerFilePath ?? "";
一旦您具备上述条件,您可以按以下方式使用它:
string projectSourcePath = ProjectSourcePath.Value;
1 "proper" 指的是:防错的、百分百可靠的、没有任何假设的、不是凑合着用的,没有用绳带捆扎在一起的、不仅对某些项目有效,对其他项目也无效的、不太可能因为你改变无关事项而突然出现严重故障等等。
Directory.GetParent()
的源代码,它会执行大量奇怪的操作,包括路径规范化(这是不必要的,因为CallerFilePath
已经产生了规范化的路径),在所有这些奇怪的操作之后,它进行了一个低效的反向线性搜索以查找最后一个分隔符的索引(而我已经知道是pathName.Length-myRelativePath.Length
),最后只是调用了Substring()
。那么,为什么不直接使用Substring()
呢? - Mike NakisGetParent
看起来更好,因为你不必计算子字符串;但是你说了那么多,Substring
更有意义。 - NotAPro这也将通过从当前执行目录向上导航两个级别来为您提供项目目录(这不会为每次构建返回项目目录,但这是最常见的情况)。
System.IO.Path.GetFullPath(@"..\..\")
当然,您会希望将此内容包含在某种验证/错误处理逻辑内。
如果你想知道你的解决方案所在的目录,你需要执行以下操作:
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()
方法,无论是调试还是发布,你都会得到构建文件夹。希望这能帮到你!如果你忘记了验证,它将像这样:
var startDirectory = Directory.GetParent(Directory.GetCurrentDirectory()).Parent.Parent.FullName;
根据Gucu112的答案,但是对于.NET Core控制台/窗口应用程序,应该是这样的:
string projectDir =
Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"..\..\.."));
如果您确实想要确保获取源项目目录,无论bin输出路径设置为什么:
添加一个预建事件命令行(Visual Studio:项目属性 -> 生成事件):
echo $(MSBuildProjectDirectory) > $(MSBuildProjectDirectory)\Resources\ProjectDirectory.txt
将ProjectDirectory.txt
文件添加到项目的Resources.resx中(如果尚不存在,请右键单击项目 -> 添加新项 -> 资源文件)
Resources.ProjectDirectory
从代码中访问。var projectDir = Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory);
$(ProjectDir)
我曾遇到类似的情况,在无果的谷歌搜索后,我声明了一个公共字符串,修改调试/发布路径的字符串值以获取项目路径。使用此方法的好处是,由于它使用当前项目的目录,所以无论您是从调试目录还是发布目录工作,都不会有影响:
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();
这应该在大多数情况下有效。