I am providing this code in C# for a Visual Studio 2010 add-in to set the caption of the Visual Studio window based on information in the solution. All of the other code samples I found, all two of them, are only partially usable.

My VS Solution always contains a solution directory item whose name is a version number. This allows me to know what I am working with when I edit more than one version of my product at the same time.

Note that ideas about renaming the solution are actually silly when given any thought. You cannot maintain good source control practices when renaming files in a project and you can’t automate command line build operations if the solution name changes. Okay, so there are probably work-arounds for those things but it’s just better to not mess with a project and its contents for the purpose of making Visual Studio work better.

Here is the code for the add-in in C#. I didn’t bother with a useful namespace name because I didn’t even know if this would work:

using System;
using Extensibility;
using EnvDTE;
using EnvDTE80;
using System.Timers;
using System.IO;
using System.Runtime.InteropServices; // DllImport

namespace MyAddin3
{
	public class Connect : IDTExtensibility2
	{
		[DllImport("User32.Dll")]
		public static extern void SetWindowText(int h, String s);
		
		public Connect()
		{
		}

		private void OnTimedEvent(object source, ElapsedEventArgs e)
		{
			string Output;
			
			if( _applicationObject.Solution.Count > 0 )
			{
				Output = Path.GetFileNameWithoutExtension( _applicationObject.Solution.FullName );
				
				for( int Index = 1; Index < = _applicationObject.Solution.Count; ++Index )
				{
					if( Char.IsDigit( _applicationObject.Solution.Item(Index).Name[0] ) )
					{
						Output += " ";
						Output += _applicationObject.Solution.Item(Index).Name;
						Output += " - ";
						Output += _applicationObject.Name;
						break;
					}
				}
			}
			else
			{
				Output = _applicationObject.Name;
			}

			int hWnd = (int)_applicationObject.MainWindow.HWnd;
			SetWindowText((int)hWnd, Output);
		}
		
		public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom)
		{
			_applicationObject = (DTE2)application;
			_addInInstance = (AddIn)addInInst;

			aTimer = new System.Timers.Timer();
			aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
			aTimer.Interval = 3000;
			aTimer.Enabled = true;
		}

		public void OnDisconnection(ext_DisconnectMode disconnectMode, ref Array custom)
		{
			aTimer.Enabled = false;
			aTimer.Dispose();
		}

		public void OnAddInsUpdate(ref Array custom)
		{
		}

		public void OnStartupComplete(ref Array custom)
		{
		}

		public void OnBeginShutdown(ref Array custom)
		{
		}
		
		private DTE2 _applicationObject;
		private AddIn _addInInstance;
		private System.Timers.Timer aTimer;
	}
}

P.S. I am a C++ programmer by trade so there may be some C# issues in this code. It compiles and runs but it might not be the most effective way to accomplish my task.