简单的方法来多个现有的.csproj添加到Visual Studio解决方案?
-
19-09-2019 - |
题
我已经从源控制签出的C#代码的一个分支。它包含多个文件夹,也许50个项目。有被发现没有现成的.sln文件。
我意欲创建空白溶液添加现有的解决方案。该UI只让我做一次这个项目。
有我丢失的东西?我想指定的* .csproj的文件列表,并以某种方式拿出一个包含所有项目.sln文件。
解决方案
下面是Bertrand的脚本的PowerShell的版本,它假定未来一Src和测试目录解决方案文件。
function GetGuidFromProject([string]$fileName) {
$content = Get-Content $fileName
$xml = [xml]$content
$obj = $xml.Project.PropertyGroup.ProjectGuid
return [Guid]$obj[0]
}
$slnPath = "C:\Project\Foo.sln"
$solutionDirectory = [System.IO.Path]::GetDirectoryName($slnPath)
$srcPath = [System.IO.Path]::GetDirectoryName($slnPath)
$writer = new-object System.IO.StreamWriter ($slnPath, $false, [System.Text.Encoding]::UTF8)
$writer.WriteLine("Microsoft Visual Studio Solution File, Format Version 12.00")
$writer.WriteLine("# Visual Studio 2013")
$projects = gci $srcPath -Filter *.csproj -Recurse
foreach ($project in $projects) {
$fileName = [System.IO.Path]::GetFileNameWithoutExtension($project)
$guid = GetGuidFromProject $project.FullName
$slnRelativePath = $project.FullName.Replace($solutionDirectory, "").TrimStart("\")
# Assume the project is a C# project {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
$writer.WriteLine("Project(""{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"") = ""$fileName"", ""$slnRelativePath"",""{$($guid.ToString().ToUpper())}""")
$writer.WriteLine("EndProject")
}
$writer.Flush()
$writer.Close()
$writer.Dispose()
其他提示
一个PowerShell的实现,以递归方式扫描脚本目录的.csproj文件,并将它们添加到(生成)All.sln:
$scriptDirectory = (Get-Item $MyInvocation.MyCommand.Path).Directory.FullName
$dteObj = [System.Activator]::CreateInstance([System.Type]::GetTypeFromProgId("VisualStudio.DTE.12.0"))
$slnDir = ".\"
$slnName = "All"
$dteObj.Solution.Create($scriptDirectory, $slnName)
(ls . -Recurse *.csproj) | % { $dteObj.Solution.AddFromFile($_.FullName, $false) }
$dteObj.Solution.SaveAs( (Join-Path $scriptDirectory 'All.sln') )
$dteObj.Quit()
这产生一个可执行文件,其产生从它在执行目录和子目录包含所有独特* .csproj的文件的解决方案A C#实现。
class Program
{
static void Main(string[] args)
{
using (var writer = new StreamWriter("All.sln", false, Encoding.UTF8))
{
writer.WriteLine("Microsoft Visual Studio Solution File, Format Version 11.00");
writer.WriteLine("# Visual Studio 2010");
var seenElements = new HashSet<string>();
foreach (var file in (new DirectoryInfo(System.IO.Directory.GetCurrentDirectory())).GetFiles("*.csproj", SearchOption.AllDirectories))
{
string fileName = Path.GetFileNameWithoutExtension(file.Name);
if (seenElements.Add(fileName))
{
var guid = ReadGuid(file.FullName);
writer.WriteLine(string.Format(@"Project(""0"") = ""{0}"", ""{1}"",""{2}""", fileName, file.FullName, guid));
writer.WriteLine("EndProject");
}
}
}
}
static Guid ReadGuid(string fileName)
{
using (var file = File.OpenRead(fileName))
{
var elements = XElement.Load(XmlReader.Create(file));
return Guid.Parse(elements.Descendants().First(element => element.Name.LocalName == "ProjectGuid").Value);
}
}
}
有是扩展VS可用的,能够在选择的目录添加所有项目(和更多):
HTTP:// www.cyotek.com/blog/visual-studio-extension-for-adding-multiple-projects-to-a-solution
您也许可以写一个小PowerShell脚本或.NET应用程序,分析所有项目的.csproj XML并提取它们的细节(ProjectGuid等),然后将它们放入.sln文件。这将会是更快,风险更低手工添加它们,但仍然一个有趣的挑战。
注意:强>这是仅适用于Visual Studio 2010
此处是凉爽添加在,让你在VS一个PowerShell控制台,让您与IDE交互的Visual Studio 2010。在许多其他的东西,你可以使用内置的VS扩展性,通过@Avram提到的事,这将是非常容易的文件或项目添加到解决方案。
如果您打开SLN文件,用记事本就可以看到这是很容易理解的文件格式,但对于更多的信息看看@的哈克项目和解决方案文件 .understanding解决方案的结构的文件,你可以写一个应用程序,它会打开所有项目文件和写应用程序的名称,地址和GUID到SLN文件。
当然,我想如果这只是一次你最好做手工
每个答案似乎变平的目录结构(所有的项目被添加到该溶液中根,不尊重文件夹层次结构)。所以,我的编码生成的解决方案,并使用解决方案文件夹来组我自己的控制台应用程序,它们。
检查出该项目在 GitHub的
用法
SolutionGenerator.exe --folder C:\git\SomeSolutionRoot --output MySolutionFile.sln
取决于视觉工作室版本。结果 但这一过程的名称是“自动化和扩展Visual Studio的”点击 http://msdn.microsoft.com/en-us/library/t51cz75w。 ASPX
检查了这一点: http://nprove.codeplex.com/
这是VS2010一个免费的插件,做该多 如果项目是TFS下
在 https://stackoverflow.com/a/16069782/492 大厦Bertrand的答案 - 做一个控制台应用程序出于这一点,在你想要的VS 2015解决方案出现在根文件夹运行它。它适用于C#和VB(哎!是不错的)。
有任何覆盖现有的,但你的源代码控制,对吧?
检查最近使用的.sln文件,看你读这是什么第几writer.WriteLine()
标题行实际上应该是由时间。
不要担心项目类型GUID Ptoject("0")
- Visual Studio会的工作,并当你保存.sln文件中写
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace AddAllProjectsToNewSolution
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("starting");
using (var writer = new StreamWriter("AllProjects.sln", false, Encoding.UTF8))
{
writer.WriteLine("Microsoft Visual Studio Solution File, Format Version 14.00");
writer.WriteLine("# Visual Studio 14");
writer.WriteLine("VisualStudioVersion = 14.0.25420.1");
var seenElements = new HashSet<string>();
foreach (var file in (new DirectoryInfo(Directory.GetCurrentDirectory())).GetFiles("*.*proj", SearchOption.AllDirectories))
{
string extension = file.Extension;
if (extension != ".csproj" && extension != ".vbproj")
{
Console.WriteLine($"ignored {file.Name}");
continue;
}
Console.WriteLine($"adding {file.Name}");
string fileName = Path.GetFileNameWithoutExtension(file.Name);
if (seenElements.Add(fileName))
{
var guid = ReadGuid(file.FullName);
writer.WriteLine($"Project(\"0\") = \"{fileName}\", \"{GetRelativePath(file.FullName)} \", \"{{{guid}}}\"" );
writer.WriteLine("EndProject");
}
}
}
Console.WriteLine("Created AllProjects.sln. Any key to close");
Console.ReadLine();
}
static Guid ReadGuid(string fileName)
{
using (var file = File.OpenRead(fileName))
{
var elements = XElement.Load(XmlReader.Create(file));
return Guid.Parse(elements.Descendants().First(element => element.Name.LocalName == "ProjectGuid").Value);
}
}
// https://stackoverflow.com/a/703292/492
static string GetRelativePath(string filespec, string folder = null)
{
if (folder == null)
folder = Environment.CurrentDirectory;
Uri pathUri = new Uri(filespec);
// Folders must end in a slash
if (!folder.EndsWith(Path.DirectorySeparatorChar.ToString()))
folder += Path.DirectorySeparatorChar;
Uri folderUri = new Uri(folder);
return Uri.UnescapeDataString(folderUri.MakeRelativeUri(pathUri).ToString().Replace('/', Path.DirectorySeparatorChar));
}
}
}
如果您选择“显示所有文件”在解决方案资源管理器中,您可以查看比所有文件和folers和选择它们,然后右键单击使用“包含在项目”进行添加。