How to get file path by file name [C #]

First of all, I know that there are many questions that are similar to this, but I could not get an answer to my problems.

So, in general, I run a program that should get the path to solving another visual studio project solution file, and I only have the name of the file itself.

For example, my program runs in the background and a visual studio project is currently being encoded, I need to get a way to solve this project. The project has not yet been drawn up; it is a new project that has just been created. For example, MyProject.sln is the file and directory I'm looking for, it's C:\Users\MyUser\Documents\Visual Studio 2015\Projects\MyProject\MyProject.sln . Of course, the project can be anywhere on the computer, for example, on another disk or not in the visual studio folder.

I tried using methods like Path.GetDirectoryName(filename) , which returns an empty string, or Path.GetFullPath(path) , which returns the wrong path (the one that searches for the path), or Directory.GetDirectories(path,searchPattern) some with SearchOptions, and then I get authorization errors for SearchOption.AllDirectories for a large number of files.

I really got lost here, hope someone can help!

+5
source share
5 answers

I do not think that you can easily get a project in a visual studio.

It would be much easier if your own program opened a visual studio and a project, which, of course, would require cooperation with the user

I have not tried it myself, but you need to use the devenv command in your own program

 Devenv /edit [file1[ file2]] 
+1
source

Use

  var ProjectLocation = Path.GetDirectoryName(Path.GetDirectoryName(System.IO.Directory.GetCurrentDirectory())); var SlnLocation = (ProjectLocation + "\\" + "SolutionName.sln"); 

this will give you a complete catalog.

0
source

Here is the code that searches for the file name of the file in the file system, hope this helps you.

  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; } 
0
source

Here is the solution for you. It analyzes all open processes to find any open in Visual Studio (even files that don't work still create the vshost process). Then it checks the name of the process module for your provided name and finally returns the path to the solution file. The example in button1_click shows how to get the actual solution file name (not sure if it will ever differ from the directory name):

  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; } 

Usage example:

  private void button1_Click(object sender, EventArgs e) { string path = GetVSProgramPath("MyProject"); string solutionFile = System.IO.Directory.GetFiles(path, "*.sln")[0]; } 

I know that the search is not optimized, but I will leave this part to you;)

0
source

Using the code suggested by @BugFinder, you can do something like this:

 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(); } } 

We filter the return values ​​with the regular expression \\.opendb$ , because VS opens a lot of files and the one that references the open solution ends with opendb :

enter image description here

Given this path, it is trivial to discover the name .sln .

Note: if VS works as an administrator, also your process will have to work with such rights ...

0
source

Source: https://habr.com/ru/post/1260570/


All Articles