如何通过文件名[c#]获取文件的路径

时间:2016-11-30 08:50:20

标签: c# visual-studio visual-studio-2015 path directory

首先,我知道有很多问题看起来像这样,但我无法真正得到答案。

所以一般来说,我正在运行一个程序,需要获得另一个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的授权错误。

我真的迷失在这里,希望有人可以帮忙!

5 个答案:

答案 0 :(得分:1)

我认为您无法轻松获得Visual Studio中的项目路径。

如果您自己的程序是打开视觉工作室和项目的那个程序会更容易 - 当然这需要一些用户合作

我自己没试过,但你需要在你自己的程序中使用devenv命令

Devenv /edit [file1[ file2]]  

答案 1 :(得分:0)

使用

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

这将为您提供完整目录。

答案 2 :(得分:0)

以下是在整个文件系统中搜索文件文件名的代码,希望这对您有帮助。

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

答案 3 :(得分:0)

这是您的解决方案。它解析所有打开的进程以查找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];

    }

我知道搜索没有优化,但我会把那部分留给你;)

答案 4 :(得分:0)

使用@BugFinder建议的code,您可以执行以下操作:

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

我们使用正则表达式\\.opendb$过滤返回的值,因为VS打开了很多文件,引用打开的解决方案的文件以opendb结尾:

enter image description here

鉴于该路径,检测.sln名称将是微不足道的。

注意:如果VS以管理员身份运行,您的流程也需要使用该权限运行...