[英]how to get a file's path by the name of the file [c#]
首先,我知道有很多问题看起来像这个但我无法真正得到我的问题的答案。
所以一般来说,我正在运行一个程序,需要获得另一个Visual Studio项目解决方案文件的解决方案的路径,我只有文件本身的名称。
例如,我的程序在后台运行,目前正在编写一个visual studio项目,我需要获得该项目解决方案的路径。 该项目尚未编译,这是一个刚刚创建的新项目。 例如, MyProject.sln
是文件,我要查找的目录是C:\\Users\\MyUser\\Documents\\Visual Studio 2015\\Projects\\MyProject\\MyProject.sln
。 当然,项目可以在计算机上的任何位置,如不同的驱动器,或者不在visual studio文件夹中。
我尝试使用返回空字符串的Path.GetDirectoryName(filename)
等方法,或返回错误路径的Path.GetFullPath(path)
(搜索路径的程序之一)或Directory.GetDirectories(path,searchPattern)
一些使用SearchOptions,然后我在很多文件上获得SearchOption.AllDirectories
授权错误。
我真的迷失在这里,希望有人能帮忙!
我认为你不能轻易地在visual studio中获得项目路径。
如果您自己的程序是打开视觉工作室和项目的那个程序会更容易 - 当然这需要一些用户合作
我自己没有尝试过,但你需要在你自己的程序中使用devenv命令
Devenv /edit [file1[ file2]]
采用
var ProjectLocation = Path.GetDirectoryName(Path.GetDirectoryName(System.IO.Directory.GetCurrentDirectory()));
var SlnLocation = (ProjectLocation + "\\" + "SolutionName.sln");
这将为您提供完整的目录。
以下是在整个文件系统中搜索文件文件名的代码,希望这对您有所帮助。
static void Main(string[] args)
{
Console.WriteLine("Enter file name...");
string fileName = Console.ReadLine();
var result = FindFile(fileName);
foreach (var files in result)
{
foreach (var file in files)
{
Console.WriteLine(file);
}
}
}
public static List<string[]> FindFile(string fileName)
{
string[] drives = Environment.GetLogicalDrives();
List<string[]> findedFiles = new List<string[]>();
foreach (string dr in drives)
{
Console.WriteLine($"Start looking in {dr}");
System.IO.DriveInfo di = new System.IO.DriveInfo(dr);
if (!di.IsReady)
{
Console.WriteLine("The drive {0} could not be read", di.Name);
continue;
}
DirectoryInfo rootDir = di.RootDirectory;
var findedFiletmp = Directory.GetFiles(rootDir.Name, fileName, SearchOption.TopDirectoryOnly);
if (findedFiletmp.Length > 0)
{
findedFiles.Add(findedFiletmp);
Console.WriteLine("Finded file.Continue search?(Y/N)");
string answer = Console.ReadLine();
if (answer.ToLower().Equals("n"))
{
break;
}
}
var subDirectories = Directory.GetDirectories(rootDir.Name);
bool breaked = false;
foreach (var subDirectory in subDirectories)
{
try
{
var findedFiletmp1 = Directory.GetFiles(subDirectory, fileName, SearchOption.AllDirectories);
if (findedFiletmp1.Length > 0)
{
findedFiles.Add(findedFiletmp1);
Console.WriteLine("Finded file.Continue search?(Y/N)");
string answer = Console.ReadLine();
if (answer.ToLower().Equals("n"))
{
breaked = true;
break;
}
}
}
catch (Exception exc)
{
Console.WriteLine(exc.Message);
}
}
Console.WriteLine($"Finished looking in {dr}");
if (breaked)
break;
}
return findedFiles;
}
这是一个适合您的解决方案。 它解析所有打开的进程以查找Visual Studio中的任何打开(即使未运行的文件仍会创建vshost进程)。 然后它根据您提供的名称检查进程模块名称,最后返回解决方案文件的路径。 button1_click中的示例显示了如何检索实际的解决方案文件名(不确定它是否会与目录名不同):
public string GetVSProgramPath(string filename)
{
Process[] plist = Process.GetProcesses();
foreach (Process theprocess in plist)
{
try
{
ProcessModule pm = theprocess.MainModule;
if (theprocess.MainModule.ModuleName.Contains("vshost") && theprocess.MainModule.ModuleName.ToLower().Contains(filename.ToLower()))
{
string path = theprocess.MainModule.FileName;
int loc = path.IndexOf(@"\Projects\");
return path.Substring(0, path.IndexOf(@"\", loc + 10));
}
}
catch (Exception ex)
{
}
}
return string.Empty;
}
用法示例:
private void button1_Click(object sender, EventArgs e)
{
string path = GetVSProgramPath("MyProject");
string solutionFile = System.IO.Directory.GetFiles(path, "*.sln")[0];
}
我知道搜索没有优化,但我会把那部分留给你;)
使用@BugFinder建议的代码 ,您可以执行以下操作:
static void Main(string[] args)
{
try
{
foreach (var proc in Process.GetProcessesByName("devenv"))
{
var files = Win32Processes.GetFilesLockedBy(proc);
Regex rgxDbFile = new Regex("\\.opendb$", RegexOptions.IgnoreCase);
foreach (var item in files.Where(f => rgxDbFile.IsMatch(f)))
{
Console.WriteLine(item);
}
}
Console.ReadKey(true);
}
catch (Exception ex)
{
ex.ToString();
}
}
我们使用regex \\\\.opendb$
过滤返回的值,因为VS打开了很多文件,引用打开的解决方案的文件以opendb
:
鉴于该路径,检测.sln
名称将是微不足道的。
注意:如果VS以管理员身份运行,那么您的流程也需要使用该权限运行...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.