maneira fácil de adicionar múltiplos .csproj existente para uma solução do Visual Studio?
-
19-09-2019 - |
Pergunta
Eu verifiquei um ramo de código C # do controle de origem. Ele contém talvez 50 projetos em diversas pastas. Não há ficheiro.SLN existente para ser encontrado.
Eu pretendia criar uma solução em branco para adicionar soluções existentes. A interface do usuário só me permite fazer isso um projeto de cada vez.
Existe algo que eu estou perdendo? Eu gostaria de especificar uma lista de arquivos * .csproj e de alguma forma chegar a um ficheiro.SLN que contém todos os projetos.
Solução
Aqui está uma versão PowerShell do roteiro de Bertrand que assume um diretório Src e Teste ao lado do arquivo de solução.
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()
Outras dicas
A PowerShell implementação que examina recursivamente o diretório de script para csproj arquivos e os adiciona a um (gerado) 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()
A C # implementação que produz um executável, o que cria uma solução que contém todos os arquivos * única .csproj do diretório e subdiretórios ele é executado em.
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);
}
}
}
Há extensão para VS disponíveis, capazes de agregar todos os projetos no diretório selecionado (e mais):
http: // www.cyotek.com/blog/visual-studio-extension-for-adding-multiple-projects-to-a-solution
Você pode ser capaz de escrever um pouco PowerShell script ou .NET aplicativo que analisa todos os XML csproj projetos e extrai seus detalhes (ProjectGuid etc.), em seguida, adiciona-los no arquivo .sln. Seria mais rápido e menos arriscado para adicioná-los todos à mão, mas um desafio interessante, no entanto.
Nota: Esta é apenas para o Visual Studio 2010
aqui é um fresco adicionar no Visual Studio 2010 que lhe dá um console PowerShell em VS para deixá-lo interagir com o IDE. Entre muitas outras coisas que você pode fazer usando o construído em VS extensibilidade como mencionado por @Avram, seria muito fácil para adicionar arquivos ou projetos a uma solução.
Use Visual Studio extensão " Adicione projetos existentes ". Ele funciona com o Visual Studio 2012, 2013, 2015, 2017.
Para usar a extensão, abra o Ferramentas menu e escolha Adicionar Projetos .
Se você abrir o arquivo sln com bloco de notas você pode ver o formato do arquivo que é fácil de entender, mas para mais informações dê uma olhada @ Corte o projeto e arquivos Solution .understanding a estrutura dos arquivos de solução você pode escrever um aplicativo que irá abrir todos os arquivos de projeto e escrever a aplicação nome, endereço e GUID para o arquivo sln.
é claro que eu acho que seja apenas uma vez é melhor fazê-lo manualmente
Cada resposta parece achatar a estrutura de diretórios (todos os projectos são adicionados à raiz solução, sem respeitar a hierarquia de pastas). Então, eu codificado meu próprio aplicativo console que gera a solução e usa pastas de solução para agrupá-los.
Confira o projeto em GitHub
Uso
SolutionGenerator.exe --folder C:\git\SomeSolutionRoot --output MySolutionFile.sln
depende da versão do Visual Studio.
Mas o nome deste processo é "Automação e extensibilidade do Visual Studio"
http://msdn.microsoft.com/en-us/library/t51cz75w. aspx
Veja isto: http://nprove.codeplex.com/
É um suplemento livre para VS2010 que faz isso e muito mais se os projetos estão sob os tfs
Com base na resposta de Bertrand em https://stackoverflow.com/a/16069782/492 - fazer uma aplicação de console fora deste e executá-lo na pasta raiz onde deseja que o VS 2015 Solution para aparecer. Ele trabalha para C # & VB (hey! Ser bom).
Ele substitui qualquer coisa existente, mas você controle de origem, certo?
Verifique a ficheiro.SLN recentemente utilizado para ver o que as primeiras linhas de cabeçalho writer.WriteLine()
realmente deve ser pelo tempo que você ler isto.
Não se preocupe com o Ptoject("0")
tipo de projeto GUID - Visual Studio irá trabalhar para fora e escrevê-lo em quando você salvar o arquivo .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));
}
}
}
Se você selecionar 'Mostrar todos os arquivos', no Solution Explorer, você pode de ver todos os arquivos e folers e selecione-os e clique direito para adicioná-los usando 'Incluir no Projeto'.