├── www └── screenshot.png ├── bin ├── slnStartupProject.exe └── slnStartupProjectLibrary.dll ├── nuget └── slnStartupProject.png ├── projects ├── vs2013 │ ├── slnStartupProject │ │ ├── packages.config │ │ ├── slnStartupProject.nuspec │ │ └── slnStartupProject.csproj │ └── slnStartupProjectLibrary │ │ ├── slnStartupProjectLibrary.nuspec │ │ └── slnStartupProjectLibrary.csproj ├── pushNugets.bat ├── vs2008 │ ├── slnStartupProject │ │ ├── slnStartupProject.nuspec │ │ └── slnStartupProject.csproj │ └── slnStartupProjectLibrary │ │ └── slnStartupProjectLibrary.csproj ├── slnStartupProject-vs2008.sln └── slnStartupProject.sln ├── .gitignore ├── src ├── slnStartupProject │ ├── Properties │ │ └── AssemblyInfo.cs │ └── Program.cs └── slnStartupProjectLibrary │ ├── Properties │ └── AssemblyInfo.cs │ ├── Project.cs │ └── Parser.cs ├── LICENCE └── README.md /www/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michakfromparis/slnStartupProject/HEAD/www/screenshot.png -------------------------------------------------------------------------------- /bin/slnStartupProject.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michakfromparis/slnStartupProject/HEAD/bin/slnStartupProject.exe -------------------------------------------------------------------------------- /nuget/slnStartupProject.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michakfromparis/slnStartupProject/HEAD/nuget/slnStartupProject.png -------------------------------------------------------------------------------- /bin/slnStartupProjectLibrary.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michakfromparis/slnStartupProject/HEAD/bin/slnStartupProjectLibrary.dll -------------------------------------------------------------------------------- /projects/vs2013/slnStartupProject/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.vshost.exe 2 | *.vshost.exe.manifest 3 | *.pdb 4 | *.nupkg 5 | *.user 6 | *.suo 7 | projects/packages/* 8 | projects/vs2008/slnStartupProject/obj/ 9 | projects/vs2008/slnStartupProjectLibrary/obj/ 10 | projects/vs2013/slnStartupProject/obj/ 11 | projects/vs2013/slnStartupProjectLibrary/obj/ -------------------------------------------------------------------------------- /projects/pushNugets.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | cd vs2013\slnStartupProjectLibrary 4 | nuget pack -prop Platform=AnyCPU slnStartupProjectLibrary.csproj 5 | nuget push slnStartupProjectLibrary.1.1.1.0.nupkg 6 | 7 | cd ..\.. 8 | 9 | cd vs2013\slnStartupProject 10 | nuget pack -prop Platform=AnyCPU slnStartupProject.csproj 11 | nuget push slnStartupProject.1.1.1.0.nupkg 12 | 13 | cd ..\.. 14 | -------------------------------------------------------------------------------- /src/slnStartupProject/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | [assembly: AssemblyTitle("slnStartupProject")] 6 | [assembly: AssemblyDescription("A command line utility to set the default StartUp project of a Visual Studio solution file")] 7 | [assembly: AssemblyConfiguration("")] 8 | [assembly: AssemblyCompany("iVoltage")] 9 | [assembly: AssemblyProduct("sln StartUp Project")] 10 | [assembly: AssemblyCopyright("Copyright © Michel Courtine 2015")] 11 | [assembly: AssemblyTrademark("")] 12 | [assembly: AssemblyCulture("")] 13 | [assembly: ComVisible(false)] 14 | [assembly: Guid("e49e0e1f-fe2d-44a0-a812-165158709e0f")] 15 | [assembly: AssemblyVersion("1.1.1.0")] 16 | [assembly: AssemblyFileVersion("1.1.1.0")] 17 | -------------------------------------------------------------------------------- /src/slnStartupProjectLibrary/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | [assembly: AssemblyTitle("slnStartupProjectLibrary")] 6 | [assembly: AssemblyDescription("A .NET library to set the default StartUp project of a Visual Studio solution file")] 7 | [assembly: AssemblyConfiguration("")] 8 | [assembly: AssemblyCompany("iVoltage")] 9 | [assembly: AssemblyProduct("sln StartUp Project Library")] 10 | [assembly: AssemblyCopyright("Copyright © Michel Courtine 2015")] 11 | [assembly: AssemblyTrademark("")] 12 | [assembly: AssemblyCulture("")] 13 | [assembly: ComVisible(false)] 14 | [assembly: Guid("e49e0e1f-fe2d-44a0-a812-165158709e0e")] 15 | [assembly: AssemblyVersion("1.1.1.0")] 16 | [assembly: AssemblyFileVersion("1.1.1.0")] 17 | -------------------------------------------------------------------------------- /projects/vs2008/slnStartupProject/slnStartupProject.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $id$ 5 | $version$ 6 | $title$ 7 | michaK 8 | $author$ 9 | https://raw.githubusercontent.com/michaKFromParis/slnStartupProject/master/LICENCE 10 | https://github.com/michaKFromParis/slnStartupProject 11 | https://raw.githubusercontent.com/michaKFromParis/slnStartupProject/master/nuget/slnStartupProject.png 12 | false 13 | $description$ 14 | Initial nuget release 15 | Copyright michaK 2015 16 | Visual Studio sln Solution Startup Project cmake C++ C# .NET 17 | 18 | -------------------------------------------------------------------------------- /projects/vs2013/slnStartupProject/slnStartupProject.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $id$ 5 | $version$ 6 | $title$ 7 | michaK 8 | $author$ 9 | https://raw.githubusercontent.com/michaKFromParis/slnStartupProject/master/LICENCE 10 | https://github.com/michaKFromParis/slnStartupProject 11 | https://raw.githubusercontent.com/michaKFromParis/slnStartupProject/master/nuget/slnStartupProject.png 12 | false 13 | $description$ 14 | Initial nuget release 15 | Copyright michaK 2015 16 | Visual Studio sln Solution Startup Project cmake C++ C# .NET 17 | 18 | -------------------------------------------------------------------------------- /projects/vs2013/slnStartupProjectLibrary/slnStartupProjectLibrary.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $id$ 5 | $version$ 6 | $title$ 7 | michaK 8 | $author$ 9 | https://raw.githubusercontent.com/michaKFromParis/slnStartupProject/master/LICENCE 10 | https://github.com/michaKFromParis/slnStartupProject 11 | https://raw.githubusercontent.com/michaKFromParis/slnStartupProject/master/nuget/slnStartupProject.png 12 | false 13 | $description$ 14 | Initial nuget release 15 | Copyright michaK 2015 16 | Visual Studio sln Solution Startup Project cmake C++ C# .NET 17 | 18 | -------------------------------------------------------------------------------- /LICENCE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Michel Courtine 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/slnStartupProjectLibrary/Project.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Text.RegularExpressions; 5 | 6 | namespace slnStartupProjectLibrary 7 | { 8 | class Project 9 | { 10 | public string ProjectName; 11 | public string CDATA; 12 | public int Offset; 13 | 14 | public Project(string cdata, int index) 15 | { 16 | CDATA = cdata; 17 | Offset = index; 18 | MatchCollection projectQuotesMatches = Regex.Matches(CDATA, @"""[^""\\]*(?:\\.[^""\\]*)*"""); 19 | if (projectQuotesMatches.Count == 0) 20 | throw new Exception("Could not extract quoted strings from the project definition while looking for its name"); 21 | if (projectQuotesMatches.Count < 2) 22 | throw new Exception("Could not locate project's name from the project definition"); 23 | ProjectName = projectQuotesMatches[1].Value.Trim('"'); 24 | } 25 | 26 | public override string ToString() 27 | { 28 | return string.Format("{0} ({1})", ProjectName, Offset); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /projects/slnStartupProject-vs2008.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 10.00 2 | # Visual Studio 2008 3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "slnStartupProject", "vs2008\slnStartupProject\slnStartupProject.csproj", "{7DC28A5B-F651-44EB-B089-CE84AB774FEC}" 4 | EndProject 5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "slnStartupProjectLibrary", "vs2008\slnStartupProjectLibrary\slnStartupProjectLibrary.csproj", "{CF03685F-40B2-4A8F-B814-538C34612480}" 6 | EndProject 7 | 8 | 9 | Global 10 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 11 | Debug|Any CPU = Debug|Any CPU 12 | Release|Any CPU = Release|Any CPU 13 | EndGlobalSection 14 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 15 | {CF03685F-40B2-4A8F-B814-538C34612480}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 16 | {CF03685F-40B2-4A8F-B814-538C34612480}.Debug|Any CPU.Build.0 = Debug|Any CPU 17 | {CF03685F-40B2-4A8F-B814-538C34612480}.Release|Any CPU.ActiveCfg = Release|Any CPU 18 | {CF03685F-40B2-4A8F-B814-538C34612480}.Release|Any CPU.Build.0 = Release|Any CPU 19 | {7DC28A5B-F651-44EB-B089-CE84AB774FEC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 20 | {7DC28A5B-F651-44EB-B089-CE84AB774FEC}.Debug|Any CPU.Build.0 = Debug|Any CPU 21 | {7DC28A5B-F651-44EB-B089-CE84AB774FEC}.Release|Any CPU.ActiveCfg = Release|Any CPU 22 | {7DC28A5B-F651-44EB-B089-CE84AB774FEC}.Release|Any CPU.Build.0 = Release|Any CPU 23 | EndGlobalSection 24 | GlobalSection(SolutionProperties) = preSolution 25 | HideSolutionNode = FALSE 26 | EndGlobalSection 27 | EndGlobal 28 | -------------------------------------------------------------------------------- /projects/slnStartupProject.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.21005.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "slnStartupProject", "vs2013\slnStartupProject\slnStartupProject.csproj", "{4DB074A8-D175-41C7-BAAF-00F2F73C970E}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "slnStartupProjectLibrary", "vs2013\slnStartupProjectLibrary\slnStartupProjectLibrary.csproj", "{A01E2F2D-CCD1-46B4-82D7-EB4C7A503004}" 9 | EndProject 10 | 11 | Global 12 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 13 | Debug|Any CPU = Debug|Any CPU 14 | Release|Any CPU = Release|Any CPU 15 | EndGlobalSection 16 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 17 | {A01E2F2D-CCD1-46B4-82D7-EB4C7A503004}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 18 | {A01E2F2D-CCD1-46B4-82D7-EB4C7A503004}.Debug|Any CPU.Build.0 = Debug|Any CPU 19 | {A01E2F2D-CCD1-46B4-82D7-EB4C7A503004}.Release|Any CPU.ActiveCfg = Release|Any CPU 20 | {A01E2F2D-CCD1-46B4-82D7-EB4C7A503004}.Release|Any CPU.Build.0 = Release|Any CPU 21 | {4DB074A8-D175-41C7-BAAF-00F2F73C970E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 22 | {4DB074A8-D175-41C7-BAAF-00F2F73C970E}.Debug|Any CPU.Build.0 = Debug|Any CPU 23 | {4DB074A8-D175-41C7-BAAF-00F2F73C970E}.Release|Any CPU.ActiveCfg = Release|Any CPU 24 | {4DB074A8-D175-41C7-BAAF-00F2F73C970E}.Release|Any CPU.Build.0 = Release|Any CPU 25 | EndGlobalSection 26 | GlobalSection(SolutionProperties) = preSolution 27 | HideSolutionNode = FALSE 28 | EndGlobalSection 29 | EndGlobal 30 | -------------------------------------------------------------------------------- /src/slnStartupProject/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text; 5 | using System.Text.RegularExpressions; 6 | using System.Linq; 7 | using slnStartupProjectLibrary; 8 | 9 | namespace slnStartupProject 10 | { 11 | class Program 12 | { 13 | static string slnFilename; 14 | static string projectName; 15 | 16 | static void Main(string[] args) 17 | { 18 | ParseArguments(args); 19 | Console.WriteLine("Setting default Startup Project to {0} in {1}", projectName, slnFilename); 20 | try 21 | { 22 | Parser.SetStartupProject(slnFilename, projectName); 23 | } 24 | catch (Exception ex) 25 | { 26 | Console.WriteLine("Error: {0}", ex.Message); 27 | System.Environment.Exit(-1); 28 | } 29 | Console.WriteLine("{0} updated successfully", slnFilename); 30 | } 31 | 32 | private static void ParseArguments(string[] args) 33 | { 34 | try 35 | { 36 | if (args.Length != 2) 37 | throw new Exception("Invalid number of arguments"); 38 | 39 | slnFilename = args[0]; 40 | projectName = args[1]; 41 | 42 | if (!File.Exists(slnFilename)) 43 | throw new Exception(string.Format("\"{0}\" does not exists", slnFilename)); 44 | } 45 | catch (Exception ex) 46 | { 47 | Usage(ex.Message); 48 | } 49 | } 50 | 51 | private static void Usage(string message) 52 | { 53 | Console.WriteLine(""); 54 | Console.WriteLine("Error: " + message); 55 | Console.WriteLine(""); 56 | Console.WriteLine("Usage: slnStartupProject slnFilename projectName"); 57 | Console.WriteLine(""); 58 | Console.WriteLine("Searches slnFilename for a project called projectName and"); 59 | Console.WriteLine("moves its definition at the top of the file so Visual Studio"); 60 | Console.WriteLine("sets it as the Startup Project automatically when you open"); 61 | Console.WriteLine("the solution file for the first time"); 62 | Console.WriteLine(); 63 | Environment.Exit(-1); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Sln StartUp Project 2 | 3 | A command line utility to set the default StartUp Project of a [Visual Studio](http://msdn.microsoft.com/en-us/vstudio/) solution file 4 | 5 | 6 | ## Usage 7 | ``` bash 8 | slnStartupProject slnFilename projectName 9 | ``` 10 | 11 | **slnFilename**: path to the Visual Studio solution file to modify 12 | 13 | **projectName**: Name of the project to set as the default StartUp project 14 | 15 | slnStartupProject searches **slnFilename** for a project called **projectName** and moves its definition at the top of the file. 16 | 17 | 18 | ## Why? 19 | 20 | ![Visual Studio Set as StartUp Project](/www/screenshot.png?raw=true "Never do that again!") 21 | 22 | When Visual Studio opens a sln file for the first time, it sets the very first project as the startup project and then stores it in the associated .suo file. This often make the first build fail and forces the developer to locate the project, right-click on it and select "Set as StartUp Project" for the build to succeed and launch. It is pretty annoying for maniacs like me. This becomes extremely relevant when you generate your solution using cmake as [cmake](http://www.cmake.org/) 3.5 and older always sets the dummy project ALL_BUILD as the first project. In CMake 3.6 and newer, there is now a [VS_STARTUP_PROJECT](https://cmake.org/cmake/help/v3.6/prop_dir/VS_STARTUP_PROJECT.html) property that allows the CMake author to specify the default startup project. 23 | 24 | You can now integrate slnStartupProject in your build script and make sure the projects you generate will build and launch everytime a developer hits **F5** 25 | 26 | Hope this helps you. 27 | 28 | ## Library 29 | 30 | slnStartupProject can also be used as a referenced library in your project to manipulate the startup project of a .sln file directly from a .NET program. 31 | 32 | ``` cs 33 | slnStartupProject.Parser.SetStartupProject(string slnFilename, string projectName); 34 | ``` 35 | 36 | I recommend installing the library through the Visual Studio package manager or the nuget command line utility. 37 | 38 | ## Compiling 39 | 40 | The source is in the src directory and you will find a Visual Studio 2013 sln / csproj in the projects directory 41 | 42 | I also provided an additional sln for Visual Studio 2008 ready to be upgraded to your needs 43 | 44 | ## Nuget 45 | 46 | The binary and library distribution can be found on [nuget.org](http://nuget.org): 47 | 48 | https://www.nuget.org/packages/slnStartupProject/ 49 | 50 | ``` pm 51 | PM> Install-Package slnStartupProject 52 | ``` 53 | https://www.nuget.org/packages/slnStartupProjectLibrary/ 54 | 55 | ``` pm 56 | PM> Install-Package slnStartupProjectLibrary 57 | ``` 58 | 59 | ## License 60 | 61 | slnStartupProject is licensed under the MIT License, see LICENSE for more information. 62 | -------------------------------------------------------------------------------- /projects/vs2008/slnStartupProjectLibrary/slnStartupProjectLibrary.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.21022 7 | 2.0 8 | {CF03685F-40B2-4A8F-B814-538C34612480} 9 | Library 10 | Properties 11 | slnStartupProjectLibrary 12 | slnStartupProjectLibrary 13 | v3.5 14 | 512 15 | 16 | 17 | true 18 | pdbonly 19 | false 20 | ..\..\..\bin\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | none 27 | true 28 | ..\..\..\bin\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | 36 | 3.5 37 | 38 | 39 | 3.5 40 | 41 | 42 | 3.5 43 | 44 | 45 | 46 | 47 | 48 | 49 | Parser.cs 50 | 51 | 52 | Project.cs 53 | 54 | 55 | Properties\AssemblyInfo.cs 56 | 57 | 58 | 59 | 66 | -------------------------------------------------------------------------------- /projects/vs2008/slnStartupProject/slnStartupProject.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Release 5 | AnyCPU 6 | 9.0.21022 7 | 2.0 8 | {7DC28A5B-F651-44EB-B089-CE84AB774FEC} 9 | Exe 10 | Properties 11 | slnStartupProject 12 | slnStartupProject 13 | v3.5 14 | 512 15 | 16 | 17 | true 18 | pdbonly 19 | false 20 | ..\..\..\bin\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | none 27 | true 28 | ..\..\..\bin\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | 36 | 3.5 37 | 38 | 39 | 3.5 40 | 41 | 42 | 3.5 43 | 44 | 45 | 46 | 47 | 48 | 49 | Parser.cs 50 | 51 | 52 | Project.cs 53 | 54 | 55 | Program.cs 56 | 57 | 58 | Properties\AssemblyInfo.cs 59 | 60 | 61 | 62 | 69 | -------------------------------------------------------------------------------- /projects/vs2013/slnStartupProjectLibrary/slnStartupProjectLibrary.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.21022 7 | 2.0 8 | {A01E2F2D-CCD1-46B4-82D7-EB4C7A503004} 9 | Library 10 | Properties 11 | slnStartupProjectLibrary 12 | slnStartupProjectLibrary 13 | v3.5 14 | 512 15 | 16 | 17 | 18 | 19 | 3.5 20 | 21 | 22 | true 23 | full 24 | false 25 | ..\..\..\bin\ 26 | DEBUG;TRACE 27 | prompt 28 | 4 29 | 30 | 31 | pdbonly 32 | true 33 | ..\..\..\bin\ 34 | TRACE 35 | prompt 36 | 4 37 | 38 | 39 | 40 | 41 | 3.5 42 | 43 | 44 | 3.5 45 | 46 | 47 | 3.5 48 | 49 | 50 | 51 | 52 | 53 | 54 | Parser.cs 55 | 56 | 57 | Project.cs 58 | 59 | 60 | AssemblyInfo.cs 61 | 62 | 63 | 64 | 65 | 66 | 67 | 74 | -------------------------------------------------------------------------------- /projects/vs2013/slnStartupProject/slnStartupProject.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.21022 7 | 2.0 8 | {4DB074A8-D175-41C7-BAAF-00F2F73C970E} 9 | Exe 10 | Properties 11 | slnStartupProject 12 | slnStartupProject 13 | v3.5 14 | 512 15 | 16 | 17 | 18 | 19 | 3.5 20 | 21 | 22 | true 23 | full 24 | false 25 | ..\..\..\bin\ 26 | DEBUG;TRACE 27 | prompt 28 | 4 29 | 30 | 31 | none 32 | true 33 | ..\..\..\bin\ 34 | TRACE 35 | prompt 36 | 4 37 | false 38 | 39 | 40 | 41 | 42 | 3.5 43 | 44 | 45 | 3.5 46 | 47 | 48 | 3.5 49 | 50 | 51 | 52 | 53 | 54 | 55 | Parser.cs 56 | 57 | 58 | Project.cs 59 | 60 | 61 | Program.cs 62 | 63 | 64 | AssemblyInfo.cs 65 | 66 | 67 | 68 | 69 | 70 | 71 | 78 | -------------------------------------------------------------------------------- /src/slnStartupProjectLibrary/Parser.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.IO; 6 | using System.Text.RegularExpressions; 7 | 8 | namespace slnStartupProjectLibrary 9 | { 10 | public class Parser 11 | { 12 | public static void SetStartupProject(string slnFilename, string projectName) 13 | { 14 | string text = null; 15 | int projectsStartOffset = -1; 16 | int projectsEndOffset = -1; 17 | List projects = new List(); 18 | 19 | /* check if the solution file has BOM */ 20 | bool hasBOM = false; 21 | using(FileStream fs = new FileStream(slnFilename, FileMode.Open)) 22 | { 23 | byte[] bits = new byte[3]; 24 | fs.Read(bits, 0, 3); 25 | if (bits[0] == 0xEF && bits[1] == 0xBB && bits[2] == 0xBF) 26 | { 27 | hasBOM = true; 28 | } 29 | } 30 | Encoding fileEncoding = new UTF8Encoding(hasBOM); 31 | 32 | try 33 | { 34 | text = File.ReadAllText(slnFilename, fileEncoding); 35 | } 36 | catch (Exception ex) 37 | { 38 | throw new Exception("Failed to read sln: " + ex.Message); 39 | } 40 | try 41 | { 42 | Regex projectRegex = new Regex(@"(\bProject\b\(.*?\bEndProject\b)", RegexOptions.Singleline); 43 | MatchCollection projectMatches = projectRegex.Matches(text); 44 | if (projectMatches.Count == 0) 45 | throw new Exception("Could not find any projects in the solution"); 46 | foreach (Match projectMatch in projectMatches) 47 | projects.Add(new Project(projectMatch.Value, projectMatch.Index)); 48 | if (!projects.Any(p => p.ProjectName == projectName)) 49 | throw new Exception(string.Format("Could not find a project named \"{0}\" in \"{1}\"", projectName, slnFilename)); 50 | int count = projects.Count(p => p.ProjectName == projectName); 51 | if (count != 1) 52 | throw new Exception(string.Format("Project \"{0}\" found more than once. \"{1}\" is probably malformed", projectName, slnFilename)); 53 | Project startupProject = projects.First(p => p.ProjectName == projectName); 54 | projectsStartOffset = projects[0].Offset; 55 | projectsEndOffset = projects[projects.Count - 1].Offset + projects[projects.Count - 1].CDATA.Length; 56 | projects.Remove(startupProject); 57 | projects.Insert(0, startupProject); 58 | } 59 | catch (Exception ex) 60 | { 61 | throw new Exception("Failed to parse sln: " + ex.Message); 62 | } 63 | try 64 | { 65 | string newSln = text.Substring(0, projectsStartOffset); 66 | List projectString = new List(); 67 | foreach (Project project in projects) 68 | { 69 | projectString.Add(project.CDATA); 70 | } 71 | newSln += string.Join(Environment.NewLine, projectString.ToArray()); 72 | newSln += text.Substring(projectsEndOffset, text.Length - projectsEndOffset); 73 | File.WriteAllText(slnFilename, newSln, fileEncoding); 74 | } 75 | catch (Exception ex) 76 | { 77 | throw new Exception("Failed to write sln: " + ex.Message); 78 | } 79 | } 80 | } 81 | } 82 | --------------------------------------------------------------------------------