繁体   English   中英

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM