Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7493019
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 29, 20262026-05-29T16:42:19+00:00 2026-05-29T16:42:19+00:00

Under Solution->Properties, I can set multiple start-up projects: I know that I can get

  • 0

Under Solution->Properties, I can set multiple start-up projects:
Solution Properties

I know that I can get the list of projects marked with “Start” (by using EnvDTE: solution.SolutionBuild.StartupProjects), but how do I get the list of projects whose action is “Start without debugging”? They do not appear in the list.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-29T16:42:20+00:00Added an answer on May 29, 2026 at 4:42 pm

    I don’t think this is documented and available officially, but here are some information:

    • This is stored in the solution’s .SUO file by the Visual Studio built-in package. The SUO file has the OLE compound storage format. You can browse it using a tool such as OpenMCDF (it has an explorer sample). In this file, you will see a stream named ‘SolutionConfiguration‘ that contains a dwStartupOpt token followed by the information you’re looking for. The stream itself has a custom binary format.

    • The same information is available from within VS through the IVsPersistSolutionProps Interface. You need to get a pointer to it from one of the loaded packages (for example enumerating the list of packages using the IVsShell.GetPackageEnum Method. One package will support the IVsPersistSolutionProps interface with the ‘SolutionConfiguration‘ stream.

    However, whatever method you choose, you will end up parsing the ‘SolutionConfiguration’ stream manually I believe. I present here a method that does it simply opening the SUO file and hacking the bits out ‘manually’, so it works outside of VS.

    Here is the utility class that parses the ‘SolutionConfiguration’ stream:

    public sealed class StartupOptions
    {
        private StartupOptions()
        {
        }
    
        public static IDictionary<Guid, int> ReadStartupOptions(string filePath)
        {
            if (filePath == null)
                throw new ArgumentNullException("filePath");
    
            // look for this token in the file
            const string token = "dwStartupOpt\0=";
            byte[] tokenBytes = Encoding.Unicode.GetBytes(token);
            Dictionary<Guid, int> dic = new Dictionary<Guid, int>();
            byte[] bytes;
            using (MemoryStream stream = new MemoryStream())
            {
                CompoundFileUtilities.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
                    byte[] guidBytes = new byte[38 * 2];
                    Array.Copy(bytes, i - guidBytes.Length - 2, guidBytes, 0, guidBytes.Length);
                    Guid 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;
        }
    }
    

    Followed by a small compound stream read utility (no need for external library):

    public static class CompoundFileUtilities
    {
        public static void ExtractStream(string filePath, string streamName, string streamPath)
        {
            if (filePath == null)
                throw new ArgumentNullException("filePath");
    
            if (streamName == null)
                throw new ArgumentNullException("streamName");
    
            if (streamPath == null)
                throw new ArgumentNullException("streamPath");
    
            using (FileStream output = new FileStream(streamPath, FileMode.Create))
            {
                ExtractStream(filePath, streamName, output);
            }
        }
    
        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
                {
                    byte[] 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);
            }
        }
    
        [ComImport, Guid("0000000b-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        private interface IStorage
        {
            void Unimplemented0();
    
            [PreserveSig]
            int OpenStream([MarshalAs(UnmanagedType.LPWStr)] string pwcsName, IntPtr reserved1, STGM grfMode, uint reserved2, out IStream ppstm);
    
            // other methods not declared for simplicity
        }
    
        [Flags]
        private enum STGM
        {
            READ = 0x00000000,
            SHARE_DENY_WRITE = 0x00000020,
            SHARE_EXCLUSIVE = 0x00000010,
            // other values not declared for simplicity
        }
    
        [DllImport("ole32.dll")]
        private static extern int StgOpenStorage([MarshalAs(UnmanagedType.LPWStr)] string pwcsName, IStorage pstgPriority, STGM grfMode, IntPtr snbExclude, uint reserved, out IStorage ppstgOpen);
    }
    

    And the sample that display project guids associated with startup options:

    static void SafeMain(string[] args)
    {
        foreach (var kvp in StartupOptions.ReadStartupOptions("mySample.suo"))
        {
            if ((kvp.Value & 1) != 0)
            {
                Console.WriteLine("Project " + kvp.Key + " has option Start");
            }
            if ((kvp.Value & 2) != 0)
            {
                Console.WriteLine("Project " + kvp.Key + " has option Start with debugging");
            }
        }
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm working on a .NET 3.5 website, with three projects under one solution. I'm
Under what circumstances might you want to use multiple indirection (that is, a chain
Under Linux, my C++ application is using fork() and execv() to launch multiple instances
I understand that is not possible to have applications with multiple entry points under
I'm using Visual Studio 2008 to build a Solution with two Projects: a C#
I have a solution with multiple projects in it. When I want to debug
We have a Visual Studio 2008 solution under VSS source control. The solution contains
Under Windows XP WPF true 3D content (which is usually displayed using the Viewport3D
Under VS's external tools settings there is a Use Output Window check box that
I have a VS2008 Professional solution that I tried to convert to VS2010 Professional

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.