能否通过代码获取Xamarin Studio/Visual Studio当前使用的解决方案文件名?
获取当前正在使用的解决方案文件名的两种思路
嘿,这个场景我之前碰到过,给你分享两种可行的方案,看哪种适合你的情况:
一、直接获取当前活跃的解决方案(Visual Studio上下文内)
如果你是在写Visual Studio的扩展(比如VSIX插件)、外接程序,或者是在项目代码里需要获取当前打开的.sln,那可以通过Visual Studio的DTE对象直接拿到,这是最准确的方式。
举个C#的例子:
// 需先引用EnvDTE程序集 EnvDTE.DTE dte = (EnvDTE.DTE)System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE"); // 获取解决方案完整路径 string fullSolutionPath = dte.Solution.FullName; // 提取文件名 string solutionFileName = System.IO.Path.GetFileName(fullSolutionPath);
这个方法的前提是:当前Visual Studio确实打开了某个解决方案,且你的代码是在VS的运行环境下执行的(比如插件、宏)。
二、外部程序中判断(遍历+进程关联)
如果你的代码是独立于Visual Studio的(比如控制台工具、脚本),没法直接用DTE,那单纯遍历目录下的.sln文件只能拿到所有存在的文件,没法判断哪个正在被使用。这时候可以结合Visual Studio的进程来判断:
VS的进程名是devenv.exe,它启动时的命令行参数里会包含打开的.sln文件路径。我们可以通过遍历这个进程,提取对应的路径:
using System.Diagnostics; using System.Linq; using System; using System.Management; var vsProcesses = Process.GetProcessesByName("devenv"); foreach (var process in vsProcesses) { string commandLine = GetCommandLine(process); if (string.IsNullOrEmpty(commandLine)) continue; string solutionPath = ParseSolutionPathFromCommandLine(commandLine); if (!string.IsNullOrEmpty(solutionPath)) { string solutionFileName = System.IO.Path.GetFileName(solutionPath); Console.WriteLine($"当前VS实例打开的解决方案:{solutionFileName}"); } } // 辅助方法:通过WMI获取进程的完整命令行 static string GetCommandLine(Process process) { using (var searcher = new ManagementObjectSearcher($"SELECT CommandLine FROM Win32_Process WHERE ProcessId = {process.Id}")) { foreach (var obj in searcher.Get()) { return obj["CommandLine"]?.ToString(); } } return null; } // 辅助方法:解析命令行中的.sln路径(处理带空格的引号包裹场景) static string ParseSolutionPathFromCommandLine(string commandLine) { // 优先处理引号包裹的路径 int quoteStart = commandLine.IndexOf('"'); if (quoteStart != -1) { int quoteEnd = commandLine.IndexOf('"', quoteStart + 1); if (quoteEnd != -1) { string path = commandLine.Substring(quoteStart + 1, quoteEnd - quoteStart - 1); if (path.EndsWith(".sln", StringComparison.OrdinalIgnoreCase)) { return path; } } } // 处理无引号的路径 return commandLine.Split(' ') .FirstOrDefault(arg => arg.EndsWith(".sln", StringComparison.OrdinalIgnoreCase)); }
这个方法能拿到所有正在运行的VS实例打开的解决方案,但要注意:如果用户打开了多个VS窗口,会返回多个结果;另外,解析命令行时要考虑路径带空格被引号包裹的情况,上面的辅助方法已经做了基础处理。
如果实在不想处理进程,那只能遍历目录下的所有.sln文件,代码很简单,但没法判断哪个是正在使用的:
string[] slnFiles = Directory.GetFiles(@"你的项目根目录", "*.sln", SearchOption.TopDirectoryOnly); foreach (var file in slnFiles) { Console.WriteLine($"找到解决方案文件:{Path.GetFileName(file)}"); }
总结一下:能在VS上下文内用DTE就优先用,最准确;外部程序就结合进程命令行来判断,比单纯遍历靠谱。
内容的提问来源于stack exchange,提问作者Carlos Rodrigez
相关产品推荐
相关产品推荐

