首先,我知道有很多问题看起来像这样,但我无法真正得到答案。
所以一般来说,我正在运行一个程序,需要获得另一个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
的授权错误。
我真的迷失在这里,希望有人可以帮忙!
答案 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
结尾:
鉴于该路径,检测.sln
名称将是微不足道的。
注意:如果VS以管理员身份运行,您的流程也需要使用该权限运行...