I am creating a .Net application that should import a VS2010 / 2008 solution and find the initial project by reading the .suo file. I looked at How to programmatically find out the effect of each StartUp project in a solution? , but the mentioned solution only works if I select several running projects in the "Solution Properties" window. My solution does not have several launch projects. Is there a way to find a startup project when the solution has only 1 startup project?
Here is the code
`open static class StartUpProjectHelper {
public static FileInfo GetStartUpProject(FileInfo solutionFile) { FileInfo startUpProject = null; string suoFile = solutionFile.FullName.Substring(0, solutionFile.FullName.Length - 4) + ".suo"; string guid = null; bool found = false; foreach (var kvp in ReadStartupOptions(suoFile)) { if (((kvp.Value & 1) != 0 || (kvp.Value & 2) != 0) && !found) { guid = kvp.Key.ToString(); found = true; } } if (!string.IsNullOrEmpty(guid)) { string projectname = GetProjectNameFromGuid(solutionFile, guid).Trim().TrimStart('\"').TrimEnd('\"'); startUpProject = new FileInfo(Path.Combine(solutionFile.DirectoryName, projectname)); } return startUpProject; } public static string GetProjectNameFromGuid(FileInfo solutionFile, string guid) { string projectName = null; using (var reader = new StreamReader(solutionFile.FullName)) { string line; bool found = false; while ((line = reader.ReadLine()) != null && !found) { // sample format //Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Saltus.digiTICKET.laptop", "digiTICKET.laptop\Saltus.digiTICKET.laptop.csproj", //"{236D51A1-DEB7-41C3-A4C1-1D16D0A85382}" EndProject if ((line.IndexOf(guid.ToUpper()) > -1) && line.Contains(",") && line.Contains("=")) { projectName = line.Split(',')[1].Split(',')[0]; found = true; } } } return projectName; } //// from /questions/905697/how-do-i-programmatically-find-out-the-action-of-each-startup-project-in-a-solution public static IDictionary<Guid, int> ReadStartupOptions(string filePath) { if (filePath == null) { throw new InvalidOperationException("No file selected"); } // look for this token in the file const string token = "dwStartupOpt\0="; byte[] tokenBytes = Encoding.Unicode.GetBytes(token); var dic = new Dictionary<Guid, int>(); byte[] bytes; using (var stream = new MemoryStream()) { ExtractStream(filePath, "SolutionConfiguration", stream); bytes = stream.ToArray(); } int i = 0; do { bool found = true; for (int j = 0; j < tokenBytes.Length; j++) { if (bytes[i + j] != tokenBytes[j]) { found = false; break; } } if (found) { // back read the corresponding project guid // guid is formatted as {guid} // len to read is Guid length* 2 and there are two offset bytes between guid and startup options token var guidBytes = new byte[38*2]; Array.Copy(bytes, i - guidBytes.Length - 2, guidBytes, 0, guidBytes.Length); var guid = new Guid(Encoding.Unicode.GetString(guidBytes)); // skip VT_I4 int options = BitConverter.ToInt32(bytes, i + tokenBytes.Length + 2); dic[guid] = options; } i++; } while (i < bytes.Length); return dic; } public static void ExtractStream(string filePath, string streamName, Stream output) { if (filePath == null) throw new ArgumentNullException("filePath"); if (streamName == null) throw new ArgumentNullException("streamName"); if (output == null) throw new ArgumentNullException("output"); IStorage storage; int hr = StgOpenStorage(filePath, null, STGM.READ | STGM.SHARE_DENY_WRITE, IntPtr.Zero, 0, out storage); if (hr != 0) throw new Win32Exception(hr); try { IStream stream; hr = storage.OpenStream(streamName, IntPtr.Zero, STGM.READ | STGM.SHARE_EXCLUSIVE, 0, out stream); if (hr != 0) throw new Win32Exception(hr); int read = 0; IntPtr readPtr = Marshal.AllocHGlobal(Marshal.SizeOf(read)); try { var bytes = new byte[0x1000]; do { stream.Read(bytes, bytes.Length, readPtr); read = Marshal.ReadInt32(readPtr); if (read == 0) break; output.Write(bytes, 0, read); } while (true); } finally { Marshal.FreeHGlobal(readPtr); Marshal.ReleaseComObject(stream); } } finally { Marshal.ReleaseComObject(storage); } } [DllImport("ole32.dll")] private static extern int StgOpenStorage([MarshalAs(UnmanagedType.LPWStr)] string pwcsName, IStorage pstgPriority, STGM grfMode, IntPtr snbExclude, uint reserved, out IStorage ppstgOpen);