From b25ee9095deca0cd0c7eedafda89e021734d0ca7 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 15 Aug 2016 14:13:56 -0400
Subject: Remove VSTool, its build info and all invocations.

VSTool manipulates the SecondLife.sln solution file for the convenience of a
developer subsequently running Visual Studio interactively. But the cost of
having it sometimes break TeamCity automated builds is too high -- especially
since we never expect to run Visual Studio interactively on a TC build host.

Also remove the CMake UNATTENDED variable that controlled it.
---
 autobuild.xml                         |  34 --
 indra/cmake/Variables.cmake           |   1 -
 indra/newview/CMakeLists.txt          |  15 -
 indra/tools/vstool/DispatchUtility.cs | 271 -------------
 indra/tools/vstool/README.txt         |   9 -
 indra/tools/vstool/VSTool.csproj      |  98 -----
 indra/tools/vstool/VSTool.exe         | Bin 24576 -> 0 bytes
 indra/tools/vstool/VSTool.sln         |  19 -
 indra/tools/vstool/app.config         |   3 -
 indra/tools/vstool/main.cs            | 729 ----------------------------------
 10 files changed, 1179 deletions(-)
 delete mode 100644 indra/tools/vstool/DispatchUtility.cs
 delete mode 100644 indra/tools/vstool/README.txt
 delete mode 100755 indra/tools/vstool/VSTool.csproj
 delete mode 100755 indra/tools/vstool/VSTool.exe
 delete mode 100755 indra/tools/vstool/VSTool.sln
 delete mode 100644 indra/tools/vstool/app.config
 delete mode 100755 indra/tools/vstool/main.cs

diff --git a/autobuild.xml b/autobuild.xml
index 072dfa678a..5a91ba15f5 100755
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -2617,14 +2617,6 @@
                 <key>arguments</key>
                 <array>
                   <string>..\indra</string>
-                  <string>&amp;&amp;</string>
-                  <string>..\indra\tools\vstool\VSTool.exe</string>
-                  <string>--solution</string>
-                  <string>SecondLife.sln</string>
-                  <string>--config</string>
-                  <string>RelWithDebInfo</string>
-                  <string>--startup</string>
-                  <string>secondlife-bin</string>
                 </array>
                 <key>options</key>
                 <array>
@@ -2663,20 +2655,11 @@
                 <key>arguments</key>
                 <array>
                   <string>..\indra</string>
-                  <string>&amp;&amp;</string>
-                  <string>..\indra\tools\vstool\VSTool.exe</string>
-                  <string>--solution</string>
-                  <string>SecondLife.sln</string>
-                  <string>--config</string>
-                  <string>RelWithDebInfo</string>
-                  <string>--startup</string>
-                  <string>secondlife-bin</string>
                 </array>
                 <key>options</key>
                 <array>
                   <string>-G</string>
                   <string>"Visual Studio 12"</string>
-                  <string>-DUNATTENDED:BOOL=ON</string>
                   <string>-DINSTALL_PROPRIETARY=FALSE</string>
                   <string>-DUSE_KDU=FALSE</string>
                 </array>
@@ -2705,14 +2688,6 @@
                 <key>arguments</key>
                 <array>
                   <string>..\indra</string>
-                  <string>&amp;&amp;</string>
-                  <string>..\indra\tools\vstool\VSTool.exe</string>
-                  <string>--solution</string>
-                  <string>SecondLife.sln</string>
-                  <string>--config</string>
-                  <string>Release</string>
-                  <string>--startup</string>
-                  <string>secondlife-bin</string>
                 </array>
                 <key>options</key>
                 <array>
@@ -2749,20 +2724,11 @@
                 <key>arguments</key>
                 <array>
                   <string>..\indra</string>
-                  <string>&amp;&amp;</string>
-                  <string>..\indra\tools\vstool\VSTool.exe</string>
-                  <string>--solution</string>
-                  <string>SecondLife.sln</string>
-                  <string>--config</string>
-                  <string>Release</string>
-                  <string>--startup</string>
-                  <string>secondlife-bin</string>
                 </array>
                 <key>options</key>
                 <array>
                   <string>-G</string>
                   <string>"Visual Studio 12"</string>
-                  <string>-DUNATTENDED:BOOL=ON</string>
                   <string>-DINSTALL_PROPRIETARY=FALSE</string>
                   <string>-DUSE_KDU=FALSE</string>
                 </array>
diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake
index 63e296b556..8292a0c63d 100644
--- a/indra/cmake/Variables.cmake
+++ b/indra/cmake/Variables.cmake
@@ -164,7 +164,6 @@ set(SIGNING_IDENTITY "" CACHE STRING "Specifies the signing identity to use, if
 
 set(VERSION_BUILD "0" CACHE STRING "Revision number passed in from the outside")
 set(USESYSTEMLIBS OFF CACHE BOOL "Use libraries from your system rather than Linden-supplied prebuilt libraries.")
-set(UNATTENDED OFF CACHE BOOL "Should be set to ON for building with VC Express editions.")
 
 set(USE_PRECOMPILED_HEADERS ON CACHE BOOL "Enable use of precompiled header directives where supported.")
 
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index dce0ea73cd..586a56b49a 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1799,21 +1799,6 @@ if (WINDOWS)
    windows-crash-logger
     )
 
-    # sets the 'working directory' for debugging from visual studio.
-    if (NOT UNATTENDED)
-        add_custom_command(
-            TARGET ${VIEWER_BINARY_NAME} POST_BUILD
-            COMMAND ${CMAKE_SOURCE_DIR}/tools/vstool/vstool.exe
-            ARGS
-              --solution
-              ${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}.sln
-              --workingdir
-              ${VIEWER_BINARY_NAME}
-              "${CMAKE_CURRENT_SOURCE_DIR}"
-            COMMENT "Setting the ${VIEWER_BINARY_NAME} working directory for debugging."
-            )
-    endif (NOT UNATTENDED)
-
     if (PACKAGE)
       add_custom_command(
         OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/event_host.tar.bz2
diff --git a/indra/tools/vstool/DispatchUtility.cs b/indra/tools/vstool/DispatchUtility.cs
deleted file mode 100644
index 6056ac55a1..0000000000
--- a/indra/tools/vstool/DispatchUtility.cs
+++ /dev/null
@@ -1,271 +0,0 @@
-#region Using Directives
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Runtime.InteropServices;
-using System.Reflection;
-using System.Security.Permissions;
-
-#endregion
-
-namespace TestDispatchUtility
-{
-	/// <summary>
-	/// Provides helper methods for working with COM IDispatch objects that have a registered type library.
-	/// </summary>
-	public static class DispatchUtility
-	{
-		#region Private Constants
-
-		private const int S_OK = 0; //From WinError.h
-		private const int LOCALE_SYSTEM_DEFAULT = 2 << 10; //From WinNT.h == 2048 == 0x800
-
-		#endregion
-
-		#region Public Methods
-
-		/// <summary>
-		/// Gets whether the specified object implements IDispatch.
-		/// </summary>
-		/// <param name="obj">An object to check.</param>
-		/// <returns>True if the object implements IDispatch.  False otherwise.</returns>
-		public static bool ImplementsIDispatch(object obj)
-		{
-			bool result = obj is IDispatchInfo;
-			return result;
-		}
-
-		/// <summary>
-		/// Gets a Type that can be used with reflection.
-		/// </summary>
-		/// <param name="obj">An object that implements IDispatch.</param>
-		/// <param name="throwIfNotFound">Whether an exception should be thrown if a Type can't be obtained.</param>
-		/// <returns>A .NET Type that can be used with reflection.</returns>
-		/// <exception cref="InvalidCastException">If <paramref name="obj"/> doesn't implement IDispatch.</exception>
-		[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
-		public static Type GetType(object obj, bool throwIfNotFound)
-		{
-			RequireReference(obj, "obj");
-			Type result = GetType((IDispatchInfo)obj, throwIfNotFound);
-			return result;
-		}
-
-		/// <summary>
-		/// Tries to get the DISPID for the requested member name.
-		/// </summary>
-		/// <param name="obj">An object that implements IDispatch.</param>
-		/// <param name="name">The name of a member to lookup.</param>
-		/// <param name="dispId">If the method returns true, this holds the DISPID on output.
-		/// If the method returns false, this value should be ignored.</param>
-		/// <returns>True if the member was found and resolved to a DISPID.  False otherwise.</returns>
-		/// <exception cref="InvalidCastException">If <paramref name="obj"/> doesn't implement IDispatch.</exception>
-		[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
-		public static bool TryGetDispId(object obj, string name, out int dispId)
-		{
-			RequireReference(obj, "obj");
-			bool result = TryGetDispId((IDispatchInfo)obj, name, out dispId);
-			return result;
-		}
-
-		/// <summary>
-		/// Invokes a member by DISPID.
-		/// </summary>
-		/// <param name="obj">An object that implements IDispatch.</param>
-		/// <param name="dispId">The DISPID of a member.  This can be obtained using
-		/// <see cref="TryGetDispId(object, string, out int)"/>.</param>
-		/// <param name="args">The arguments to pass to the member.</param>
-		/// <returns>The member's return value.</returns>
-		/// <remarks>
-		/// This can invoke a method or a property get accessor.
-		/// </remarks>
-		public static object Invoke(object obj, int dispId, object[] args)
-		{
-			string memberName = "[DispId=" + dispId + "]";
-			object result = Invoke(obj, memberName, args);
-			return result;
-		}
-
-		/// <summary>
-		/// Invokes a member by name.
-		/// </summary>
-		/// <param name="obj">An object.</param>
-		/// <param name="memberName">The name of the member to invoke.</param>
-		/// <param name="args">The arguments to pass to the member.</param>
-		/// <returns>The member's return value.</returns>
-		/// <remarks>
-		/// This can invoke a method or a property get accessor.
-		/// </remarks>
-		public static object Invoke(object obj, string memberName, object[] args)
-		{
-			RequireReference(obj, "obj");
-			Type type = obj.GetType();
-			object result = type.InvokeMember(memberName, BindingFlags.InvokeMethod | BindingFlags.GetProperty,
-				null, obj, args, null);
-			return result;
-		}
-
-		#endregion
-
-		#region Private Methods
-
-		/// <summary>
-		/// Requires that the value is non-null.
-		/// </summary>
-		/// <typeparam name="T">The type of the value.</typeparam>
-		/// <param name="value">The value to check.</param>
-		/// <param name="name">The name of the value.</param>
-		private static void RequireReference<T>(T value, string name) where T : class
-		{
-			if (value == null)
-			{
-				throw new ArgumentNullException(name);
-			}
-		}
-
-		/// <summary>
-		/// Gets a Type that can be used with reflection.
-		/// </summary>
-		/// <param name="dispatch">An object that implements IDispatch.</param>
-		/// <param name="throwIfNotFound">Whether an exception should be thrown if a Type can't be obtained.</param>
-		/// <returns>A .NET Type that can be used with reflection.</returns>
-		private static Type GetType(IDispatchInfo dispatch, bool throwIfNotFound)
-		{
-			RequireReference(dispatch, "dispatch");
-
-			Type result = null;
-			int typeInfoCount;
-			int hr = dispatch.GetTypeInfoCount(out typeInfoCount);
-			if (hr == S_OK && typeInfoCount > 0)
-			{
-				// Type info isn't usually culture-aware for IDispatch, so we might as well pass
-				// the default locale instead of looking up the current thread's LCID each time
-				// (via CultureInfo.CurrentCulture.LCID).
-				dispatch.GetTypeInfo(0, LOCALE_SYSTEM_DEFAULT, out result);
-			}
-
-			if (result == null && throwIfNotFound)
-			{
-				// If the GetTypeInfoCount called failed, throw an exception for that.
-				Marshal.ThrowExceptionForHR(hr);
-
-				// Otherwise, throw the same exception that Type.GetType would throw.
-				throw new TypeLoadException();
-			}
-
-			return result;
-		}
-
-		/// <summary>
-		/// Tries to get the DISPID for the requested member name.
-		/// </summary>
-		/// <param name="dispatch">An object that implements IDispatch.</param>
-		/// <param name="name">The name of a member to lookup.</param>
-		/// <param name="dispId">If the method returns true, this holds the DISPID on output.
-		/// If the method returns false, this value should be ignored.</param>
-		/// <returns>True if the member was found and resolved to a DISPID.  False otherwise.</returns>
-		private static bool TryGetDispId(IDispatchInfo dispatch, string name, out int dispId)
-		{
-			RequireReference(dispatch, "dispatch");
-			RequireReference(name, "name");
-
-			bool result = false;
-
-			// Members names aren't usually culture-aware for IDispatch, so we might as well
-			// pass the default locale instead of looking up the current thread's LCID each time
-			// (via CultureInfo.CurrentCulture.LCID).
-			Guid iidNull = Guid.Empty;
-			int hr = dispatch.GetDispId(ref iidNull, ref name, 1, LOCALE_SYSTEM_DEFAULT, out dispId);
-
-			const int DISP_E_UNKNOWNNAME = unchecked((int)0x80020006); //From WinError.h
-			const int DISPID_UNKNOWN = -1; //From OAIdl.idl
-			if (hr == S_OK)
-			{
-				result = true;
-			}
-			else if (hr == DISP_E_UNKNOWNNAME && dispId == DISPID_UNKNOWN)
-			{
-				// This is the only supported "error" case because it means IDispatch
-				// is saying it doesn't know the member we asked about.
-				result = false;
-			}
-			else
-			{
-				// The other documented result codes are all errors.
-				Marshal.ThrowExceptionForHR(hr);
-			}
-
-			return result;
-		}
-
-		#endregion
-
-		#region Private Interfaces
-
-		/// <summary>
-		/// A partial declaration of IDispatch used to lookup Type information and DISPIDs.
-		/// </summary>
-		/// <remarks>
-		/// This interface only declares the first three methods of IDispatch.  It omits the
-		/// fourth method (Invoke) because there are already plenty of ways to do dynamic
-		/// invocation in .NET.  But the first three methods provide dynamic type metadata
-		/// discovery, which .NET doesn't provide normally if you have a System.__ComObject
-		/// RCW instead of a strongly-typed RCW.
-		/// <para/>
-		/// Note: The original declaration of IDispatch is in OAIdl.idl.
-		/// </remarks>
-		[ComImport]
-		[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
-		[Guid("00020400-0000-0000-C000-000000000046")]
-		private interface IDispatchInfo
-		{
-			/// <summary>
-			/// Gets the number of Types that the object provides (0 or 1).
-			/// </summary>
-			/// <param name="typeInfoCount">Returns 0 or 1 for the number of Types provided by <see cref="GetTypeInfo"/>.</param>
-			/// <remarks>
-			/// http://msdn.microsoft.com/en-us/library/da876d53-cb8a-465c-a43e-c0eb272e2a12(VS.85)
-			/// </remarks>
-			[PreserveSig]
-			int GetTypeInfoCount(out int typeInfoCount);
-
-			/// <summary>
-			/// Gets the Type information for an object if <see cref="GetTypeInfoCount"/> returned 1.
-			/// </summary>
-			/// <param name="typeInfoIndex">Must be 0.</param>
-			/// <param name="lcid">Typically, LOCALE_SYSTEM_DEFAULT (2048).</param>
-			/// <param name="typeInfo">Returns the object's Type information.</param>
-			/// <remarks>
-			/// http://msdn.microsoft.com/en-us/library/cc1ec9aa-6c40-4e70-819c-a7c6dd6b8c99(VS.85)
-			/// </remarks>
-			void GetTypeInfo(int typeInfoIndex, int lcid, [MarshalAs(UnmanagedType.CustomMarshaler,
-				MarshalTypeRef = typeof(System.Runtime.InteropServices.CustomMarshalers.TypeToTypeInfoMarshaler))] out Type typeInfo);
-
-			/// <summary>
-			/// Gets the DISPID of the specified member name.
-			/// </summary>
-			/// <param name="riid">Must be IID_NULL.  Pass a copy of Guid.Empty.</param>
-			/// <param name="name">The name of the member to look up.</param>
-			/// <param name="nameCount">Must be 1.</param>
-			/// <param name="lcid">Typically, LOCALE_SYSTEM_DEFAULT (2048).</param>
-			/// <param name="dispId">If a member with the requested <paramref name="name"/>
-			/// is found, this returns its DISPID and the method's return value is 0.
-			/// If the method returns a non-zero value, then this parameter's output value is
-			/// undefined.</param>
-			/// <returns>Zero for success. Non-zero for failure.</returns>
-			/// <remarks>
-			/// http://msdn.microsoft.com/en-us/library/6f6cf233-3481-436e-8d6a-51f93bf91619(VS.85)
-			/// </remarks>
-			[PreserveSig]
-			int GetDispId(ref Guid riid, ref string name, int nameCount, int lcid, out int dispId);
-
-			// NOTE: The real IDispatch also has an Invoke method next, but we don't need it.
-			// We can invoke methods using .NET's Type.InvokeMember method with the special
-			// [DISPID=n] syntax for member "names", or we can get a .NET Type using GetTypeInfo
-			// and invoke methods on that through reflection.
-			// Type.InvokeMember: http://msdn.microsoft.com/en-us/library/de3dhzwy.aspx
-		}
-
-		#endregion
-	}
-}
diff --git a/indra/tools/vstool/README.txt b/indra/tools/vstool/README.txt
deleted file mode 100644
index e419180031..0000000000
--- a/indra/tools/vstool/README.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-VSTool is a command line utility to manipulate VisualStudio settings. 
-
-The windows cmake project configuration uses VSTool.exe
-
-A handy upgrade:
- figure out how to make cmake build this csharp app
- - or write the app using script (jscript?!?) so it doesn't need to be built.
-
-
diff --git a/indra/tools/vstool/VSTool.csproj b/indra/tools/vstool/VSTool.csproj
deleted file mode 100755
index 7f431e85c7..0000000000
--- a/indra/tools/vstool/VSTool.csproj
+++ /dev/null
@@ -1,98 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
-  <PropertyGroup>
-    <ProjectType>Local</ProjectType>
-    <ProductVersion>8.0.50727</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{96943E2D-1373-4617-A117-D0F997A94919}</ProjectGuid>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ApplicationIcon>
-    </ApplicationIcon>
-    <AssemblyKeyContainerName>
-    </AssemblyKeyContainerName>
-    <AssemblyName>VSTool</AssemblyName>
-    <AssemblyOriginatorKeyFile>
-    </AssemblyOriginatorKeyFile>
-    <DefaultClientScript>JScript</DefaultClientScript>
-    <DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
-    <DefaultTargetSchema>IE50</DefaultTargetSchema>
-    <DelaySign>false</DelaySign>
-    <OutputType>Exe</OutputType>
-    <RootNamespace>VSTool</RootNamespace>
-    <RunPostBuildEvent>Always</RunPostBuildEvent>
-    <StartupObject>VSTool.VSToolMain</StartupObject>
-    <FileUpgradeFlags>
-    </FileUpgradeFlags>
-    <UpgradeBackupLocation>
-    </UpgradeBackupLocation>
-    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
-    <OldToolsVersion>2.0</OldToolsVersion>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <OutputPath>.\</OutputPath>
-    <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
-    <BaseAddress>285212672</BaseAddress>
-    <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
-    <ConfigurationOverrideFile>
-    </ConfigurationOverrideFile>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <DocumentationFile>
-    </DocumentationFile>
-    <DebugSymbols>true</DebugSymbols>
-    <FileAlignment>4096</FileAlignment>
-    <NoStdLib>false</NoStdLib>
-    <NoWarn>
-    </NoWarn>
-    <Optimize>false</Optimize>
-    <RegisterForComInterop>false</RegisterForComInterop>
-    <RemoveIntegerChecks>false</RemoveIntegerChecks>
-    <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
-    <WarningLevel>4</WarningLevel>
-    <DebugType>full</DebugType>
-    <ErrorReport>prompt</ErrorReport>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <OutputPath>.\</OutputPath>
-    <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
-    <BaseAddress>285212672</BaseAddress>
-    <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
-    <ConfigurationOverrideFile>
-    </ConfigurationOverrideFile>
-    <DefineConstants>TRACE</DefineConstants>
-    <DocumentationFile>
-    </DocumentationFile>
-    <DebugSymbols>false</DebugSymbols>
-    <FileAlignment>4096</FileAlignment>
-    <NoStdLib>false</NoStdLib>
-    <NoWarn>
-    </NoWarn>
-    <Optimize>true</Optimize>
-    <RegisterForComInterop>false</RegisterForComInterop>
-    <RemoveIntegerChecks>false</RemoveIntegerChecks>
-    <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
-    <WarningLevel>4</WarningLevel>
-    <DebugType>none</DebugType>
-    <ErrorReport>prompt</ErrorReport>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="System">
-      <Name>System</Name>
-    </Reference>
-    <Reference Include="System.Data">
-      <Name>System.Data</Name>
-    </Reference>
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="main.cs">
-      <SubType>Code</SubType>
-    </Compile>
-  </ItemGroup>
-  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
-  <PropertyGroup>
-    <PreBuildEvent>
-    </PreBuildEvent>
-    <PostBuildEvent>
-    </PostBuildEvent>
-  </PropertyGroup>
-</Project>
\ No newline at end of file
diff --git a/indra/tools/vstool/VSTool.exe b/indra/tools/vstool/VSTool.exe
deleted file mode 100755
index 854290b90a..0000000000
Binary files a/indra/tools/vstool/VSTool.exe and /dev/null differ
diff --git a/indra/tools/vstool/VSTool.sln b/indra/tools/vstool/VSTool.sln
deleted file mode 100755
index 21e3d75971..0000000000
--- a/indra/tools/vstool/VSTool.sln
+++ /dev/null
@@ -1,19 +0,0 @@
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual Studio 2010
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VSTool", "VSTool.csproj", "{96943E2D-1373-4617-A117-D0F997A94919}"
-EndProject
-Global
-	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Debug|Any CPU = Debug|Any CPU
-		Release|Any CPU = Release|Any CPU
-	EndGlobalSection
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{96943E2D-1373-4617-A117-D0F997A94919}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{96943E2D-1373-4617-A117-D0F997A94919}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{96943E2D-1373-4617-A117-D0F997A94919}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{96943E2D-1373-4617-A117-D0F997A94919}.Release|Any CPU.Build.0 = Release|Any CPU
-	EndGlobalSection
-	GlobalSection(SolutionProperties) = preSolution
-		HideSolutionNode = FALSE
-	EndGlobalSection
-EndGlobal
diff --git a/indra/tools/vstool/app.config b/indra/tools/vstool/app.config
deleted file mode 100644
index 8494f728ff..0000000000
--- a/indra/tools/vstool/app.config
+++ /dev/null
@@ -1,3 +0,0 @@
-<?xml version="1.0"?>
-<configuration>
-<startup><supportedRuntime version="v2.0.50727"/></startup></configuration>
diff --git a/indra/tools/vstool/main.cs b/indra/tools/vstool/main.cs
deleted file mode 100755
index ef2e582b90..0000000000
--- a/indra/tools/vstool/main.cs
+++ /dev/null
@@ -1,729 +0,0 @@
-// Code about getting running instances visual studio
-// was borrowed from 
-// http://www.codeproject.com/KB/cs/automatingvisualstudio.aspx
-
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Reflection;
-using System.Runtime.InteropServices;
-using System.Runtime.InteropServices.ComTypes;
-using Microsoft.CSharp;
-
-namespace VSTool
-{
-    // The MessageFilter class comes from:
-    // http://msdn.microsoft.com/en-us/library/ms228772(VS.80).aspx
-    // It allows vstool to get timing error messages from 
-    // visualstudio and handle them.
-    public class MessageFilter : IOleMessageFilter
-    {
-        //
-        // Class containing the IOleMessageFilter
-        // thread error-handling functions.
-
-        // Start the filter.
-        public static void Register()
-        {
-            IOleMessageFilter newFilter = new MessageFilter(); 
-            IOleMessageFilter oldFilter = null; 
-            CoRegisterMessageFilter(newFilter, out oldFilter);
-        }
-
-        // Done with the filter, close it.
-        public static void Revoke()
-        {
-            IOleMessageFilter oldFilter = null; 
-            CoRegisterMessageFilter(null, out oldFilter);
-        }
-
-        //
-        // IOleMessageFilter functions.
-        // Handle incoming thread requests.
-        int IOleMessageFilter.HandleInComingCall(int dwCallType, 
-          System.IntPtr hTaskCaller, int dwTickCount, System.IntPtr 
-          lpInterfaceInfo) 
-        {
-            //Return the flag SERVERCALL_ISHANDLED.
-            return 0;
-        }
-
-        // Thread call was rejected, so try again.
-        int IOleMessageFilter.RetryRejectedCall(System.IntPtr 
-          hTaskCallee, int dwTickCount, int dwRejectType)
-        {
-            if (dwRejectType == 2)
-            // flag = SERVERCALL_RETRYLATER.
-            {
-                // Retry the thread call immediately if return >=0 & 
-                // <100.
-                return 99;
-            }
-            // Too busy; cancel call.
-            return -1;
-        }
-
-        int IOleMessageFilter.MessagePending(System.IntPtr hTaskCallee, 
-          int dwTickCount, int dwPendingType)
-        {
-            //Return the flag PENDINGMSG_WAITDEFPROCESS.
-            return 2; 
-        }
-
-        // Implement the IOleMessageFilter interface.
-        [DllImport("Ole32.dll")]
-        private static extern int 
-          CoRegisterMessageFilter(IOleMessageFilter newFilter, out 
-          IOleMessageFilter oldFilter);
-    }
-
-    [ComImport(), Guid("00000016-0000-0000-C000-000000000046"), 
-    InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
-    interface IOleMessageFilter 
-    {
-        [PreserveSig]
-        int HandleInComingCall( 
-            int dwCallType, 
-            IntPtr hTaskCaller, 
-            int dwTickCount, 
-            IntPtr lpInterfaceInfo);
-
-        [PreserveSig]
-        int RetryRejectedCall( 
-            IntPtr hTaskCallee, 
-            int dwTickCount,
-            int dwRejectType);
-
-        [PreserveSig]
-        int MessagePending( 
-            IntPtr hTaskCallee, 
-            int dwTickCount,
-            int dwPendingType);
-    }
-
-    class ViaCOM
-    {
-        public static object GetProperty(object from_obj, string prop_name)
-        {
-            try
-            {
-                Type objType = from_obj.GetType();
-                return objType.InvokeMember(
-                    prop_name,
-                    BindingFlags.GetProperty, null,
-                    from_obj,
-                    null);
-            }
-            catch (Exception e)
-            {
-                Console.WriteLine("Error getting property: \"{0}\"", prop_name);
-                Console.WriteLine(e.Message);
-                throw e;
-            }
-        }
-
-        public static object SetProperty(object from_obj, string prop_name, object new_value)
-        {
-            try
-            {
-                object[] args = { new_value };
-                Type objType = from_obj.GetType();
-                return objType.InvokeMember(
-                    prop_name,
-                    BindingFlags.DeclaredOnly |
-                    BindingFlags.Public |
-                    BindingFlags.NonPublic |
-                    BindingFlags.Instance |
-                    BindingFlags.SetProperty,
-                    null,
-                    from_obj,
-                    args);
-            }
-            catch (Exception e)
-            {
-                Console.WriteLine("Error setting property: \"{0}\"", prop_name);
-                Console.WriteLine(e.Message);
-                throw e;
-            }
-        }
-
-        public static object CallMethod(object from_obj, string method_name, params object[] args)
-        {
-            try
-            {
-                Type objType = from_obj.GetType();
-                return objType.InvokeMember(
-                    method_name,
-                    BindingFlags.DeclaredOnly |
-                    BindingFlags.Public |
-                    BindingFlags.NonPublic |
-                    BindingFlags.Instance |
-                    BindingFlags.InvokeMethod,
-                    null,
-                    from_obj,
-                    args);
-            }
-            catch (Exception e)
-            {
-                Console.WriteLine("Error calling method \"{0}\"", method_name);
-                Console.WriteLine(e.Message);
-                throw e;
-            }
-        }
-    };
-
-    /// <summary>
-	/// The main entry point class for VSTool.
-	/// </summary>
-    class VSToolMain
-    {
-        #region Interop imports
-        [DllImport("ole32.dll")]  
-        public static extern int GetRunningObjectTable(int reserved, out IRunningObjectTable prot); 
- 
-        [DllImport("ole32.dll")]  
-        public static extern int  CreateBindCtx(int reserved, out IBindCtx ppbc);
-        #endregion 
-
-        static System.Boolean ignore_case = true;
-
-        static string solution_name = null;
-        static bool use_new_vs = false;
-        static Hashtable projectDict = new Hashtable();
-        static string startup_project = null;
-        static string config = null;
-
-        static object dte = null;
-        static object solution = null;
-
-        /// <summary>
-		/// The main entry point for the application.
-		/// </summary>
-		[STAThread]
-		static int Main(string[] args)
-		{
-            int retVal = 0;
-            bool need_save = false;
-
-            try
-            {
-                parse_command_line(args);
-
-                Console.WriteLine("Editing solution: {0}", solution_name);
-
-                bool found_open_solution = GetDTEAndSolution();
-
-                if (dte == null || solution == null)
-                {
-                    retVal = 1;
-                }
-                else
-                {
-                    MessageFilter.Register();
-
-                    // Walk through all of the projects in the solution
-                    // and list the type of each project.
-                    foreach (DictionaryEntry p in projectDict)
-                    {
-                        string project_name = (string)p.Key;
-                        string working_dir = (string)p.Value;
-                        if (SetProjectWorkingDir(solution, project_name, working_dir))
-                        {
-                            need_save = true;
-                        }
-                    }
-
-                    if (config != null)
-                    {
-                        need_save = SetActiveConfig(config);
-                    }
-
-                    if (startup_project != null)
-                    {
-                        need_save = SetStartupProject(startup_project);
-                    }
-
-                    if (need_save)
-                    {
-                        if (found_open_solution == false)
-                        {
-                            ViaCOM.CallMethod(solution, "Close", null);
-                        }
-                    }
-                }
-            }
-            catch (Exception e)
-            {
-                Console.WriteLine(e.Message);
-                retVal = 1;
-            }
-            finally
-            {
-                if (solution != null)
-                {
-                    Marshal.ReleaseComObject(solution);
-                    solution = null;
-                }
-
-                if (dte != null)
-                {
-                    Marshal.ReleaseComObject(dte);
-                    dte = null;
-                }
-
-                MessageFilter.Revoke();
-            }
-            return retVal;
-        }
-
-        public static bool parse_command_line(string[] args)
-        {
-            string options_desc = 
-                "--solution <solution_name>   : MSVC solution name. (required)\n" +
-                "--use_new_vs                 : Ignore running versions of visual studio.\n" +
-                "--workingdir <project> <dir> : Set working dir of a VC project.\n" +
-                "--config <config>            : Set the active config for the solution.\n" +
-                "--startup <project>          : Set the startup project for the solution.\n";
-
-            try
-            {
-                // Command line param parsing loop.
-                int i = 0;
-                for (; i < args.Length; ++i)
-                {
-                    if ("--solution" == args[i])
-                    {
-                        if (solution_name != null)
-                        {
-                            throw new ApplicationException("Found second --solution option");
-                        }
-                        solution_name = args[++i];
-                    }
-                    else if ("--use_new_vs" == args[i])
-                    {
-                        use_new_vs = true;
-                    }
-
-                    else if ("--workingdir" == args[i])
-                    {
-                        string project_name = args[++i];
-                        string working_dir = args[++i];
-                        projectDict.Add(project_name, working_dir);
-                    }
-                    else if ("--config" == args[i])
-                    {
-                        if (config != null)
-                        {
-                            throw new ApplicationException("Found second --config option");
-                        }
-                        config = args[++i];
-                    }
-                    else if ("--startup" == args[i])
-                    {
-                        if (startup_project != null)
-                        {
-                            throw new ApplicationException("Found second --startup option");
-                        }
-                        startup_project = args[++i];
-                    }
-                    else
-                    {
-                        throw new ApplicationException("Found unrecognized token on command line: " + args[i]);
-                    }
-                }
-
-                if (solution_name == null)
-                {
-                    throw new ApplicationException("The --solution option is required.");
-                }
-            }
-            catch(ApplicationException e)
-            {
-
-                Console.WriteLine("Oops! " + e.Message);
-                Console.Write("Command line:");
-                foreach (string arg in args)
-                {
-                    Console.Write(" " + arg);
-                }
-                Console.Write("\n\n");
-                Console.WriteLine("VSTool command line usage");
-                Console.Write(options_desc);
-                throw e;
-            }
-            return true;
-        }
-
-        public static bool GetDTEAndSolution()
-        {
-            bool found_open_solution = true;
-
-            Console.WriteLine("Looking for existing VisualStudio instance...");
-
-            // Get an instance of the currently running Visual Studio .NET IDE.
-            // dte = (EnvDTE.DTE)System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE.7.1");
-            string full_solution_name = System.IO.Path.GetFullPath(solution_name);
-            if (false == use_new_vs)
-            {
-                dte = GetIDEInstance(full_solution_name);
-            }
-
-            if (dte == null)
-            {
-                try
-                {
-                    Console.WriteLine("  Didn't find open solution, starting new background VisualStudio instance...");
-                    Console.WriteLine("  Reading .sln file version...");
-                    string version = GetSolutionVersion(full_solution_name);
-
-                    Console.WriteLine("  Using version: {0}...", version);
-                    string progid = GetVSProgID(version);
-
-                    Type objType = Type.GetTypeFromProgID(progid);
-                    dte = System.Activator.CreateInstance(objType);
-                    Console.WriteLine("  Reading solution: \"{0}\"", full_solution_name);
-
-                    solution = ViaCOM.GetProperty(dte, "Solution");
-                    object[] openArgs = { full_solution_name };
-                    ViaCOM.CallMethod(solution, "Open", openArgs);
-                }
-                catch (Exception e)
-                {
-                    Console.WriteLine(e.Message);
-                    Console.WriteLine("Quitting do to error opening: {0}", full_solution_name);
-                    solution = null;
-                    dte = null;
-                    return found_open_solution;
-                }
-                found_open_solution = false;
-            }
-
-            if (solution == null)
-            {
-                solution = ViaCOM.GetProperty(dte, "Solution");
-            }
-
-            return found_open_solution;
-        }
-
-        /// <summary>
-        /// Get the DTE object for the instance of Visual Studio IDE that has 
-        /// the specified solution open.
-        /// </summary>
-        /// <param name="solutionFile">The absolute filename of the solution</param>
-        /// <returns>Corresponding DTE object or null if no such IDE is running</returns>
-        public static object GetIDEInstance( string solutionFile )
-        {
-            Hashtable runningInstances = GetIDEInstances( true );
-            IDictionaryEnumerator enumerator = runningInstances.GetEnumerator();
-
-            while ( enumerator.MoveNext() )
-            {
-                try
-                {
-                    object ide = enumerator.Value;
-                    if (ide != null)
-                    {
-                        object sol = ViaCOM.GetProperty(ide, "Solution");
-                        if (0 == string.Compare((string)ViaCOM.GetProperty(sol, "FullName"), solutionFile, ignore_case))
-                        {
-                            return ide;
-                        }
-                    }
-                } 
-                catch{}
-            }
-
-            return null;
-        }
-
-        /// <summary>
-        /// Get a table of the currently running instances of the Visual Studio .NET IDE.
-        /// </summary>
-        /// <param name="openSolutionsOnly">Only return instances that have opened a solution</param>
-        /// <returns>A hashtable mapping the name of the IDE in the running object table to the corresponding DTE object</returns>
-        public static Hashtable GetIDEInstances( bool openSolutionsOnly )
-        {
-            Hashtable runningIDEInstances = new Hashtable();
-            Hashtable runningObjects = GetRunningObjectTable();
-
-            IDictionaryEnumerator rotEnumerator = runningObjects.GetEnumerator();
-            while ( rotEnumerator.MoveNext() )
-            {
-                string candidateName = (string) rotEnumerator.Key;
-                if (!candidateName.StartsWith("!VisualStudio.DTE"))
-                    continue;
-
-                object ide = rotEnumerator.Value;
-                if (ide == null)
-                    continue;
-
-                if (openSolutionsOnly)
-                {
-                    try
-                    {
-                        object sol = ViaCOM.GetProperty(ide, "Solution");
-                        string solutionFile = (string)ViaCOM.GetProperty(sol, "FullName");
-                        if (solutionFile != String.Empty)
-                        {
-                            runningIDEInstances[ candidateName ] = ide;
-                        }
-                    } 
-                    catch {}
-                }
-                else
-                {
-                    runningIDEInstances[ candidateName ] = ide;
-                }                       
-            }
-            return runningIDEInstances;
-        }
-
-        /// <summary>
-        /// Get a snapshot of the running object table (ROT).
-        /// </summary>
-        /// <returns>A hashtable mapping the name of the object in the ROT to the corresponding object</returns>
-        [STAThread]
-        public static Hashtable GetRunningObjectTable()
-        {
-            Hashtable result = new Hashtable();
-
-            int numFetched = 0;
-            IRunningObjectTable runningObjectTable;   
-            IEnumMoniker monikerEnumerator;
-            IMoniker[] monikers = new IMoniker[1];
-
-            GetRunningObjectTable(0, out runningObjectTable);    
-            runningObjectTable.EnumRunning(out monikerEnumerator);
-            monikerEnumerator.Reset();          
-            
-            while (monikerEnumerator.Next(1, monikers, new IntPtr(numFetched)) == 0)
-            {     
-                IBindCtx ctx;
-                CreateBindCtx(0, out ctx);     
-                    
-                string runningObjectName;
-                monikers[0].GetDisplayName(ctx, null, out runningObjectName);
-
-                object runningObjectVal;  
-                runningObjectTable.GetObject( monikers[0], out runningObjectVal); 
-
-                result[ runningObjectName ] = runningObjectVal;
-            } 
-
-            return result;
-        }
-
-        public static string GetSolutionVersion(string solutionFullFileName) 
-        {
-            string version;
-            System.IO.StreamReader solutionStreamReader = null;
-            string firstLine;
-            string format;
-            
-            try
-            {
-                solutionStreamReader = new System.IO.StreamReader(solutionFullFileName);
-                do
-                {
-                    firstLine = solutionStreamReader.ReadLine();
-                }
-                while (firstLine == "");
-                
-                format = firstLine.Substring(firstLine.LastIndexOf(" ")).Trim();
-        
-                switch(format)
-                {
-                    case "7.00":
-                        version = "VC70";
-                        break;
-
-                    case "8.00":
-                        version = "VC71";
-                        break;
-
-                    case "9.00":
-                        version = "VC80";
-                        break;
-                
-                    case "10.00":
-                        version = "VC90";
-                        break;
-
-                    case "11.00":
-                        version = "VC100";
-                        break;
-
-                    case "12.00":
-                        version = "VC120";
-                        break;
-
-                    default:
-                        throw new ApplicationException("Unknown .sln version: " + format);
-                }
-            }
-            finally
-            {
-                if(solutionStreamReader != null) 
-                {
-                    solutionStreamReader.Close();
-                }
-            }
-            
-            return version;
-        }
-
-        public static string GetVSProgID(string version)
-        {
-            string progid = null;
-            switch(version)
-            {
-                case "VC70":
-                    progid = "VisualStudio.DTE.7";
-                    break;
-
-                case "VC71":
-                    progid = "VisualStudio.DTE.7.1";
-                    break;
-
-                case "VC80":
-                    progid = "VisualStudio.DTE.8.0";
-                    break;
-                
-                case "VC90":
-                    progid = "VisualStudio.DTE.9.0";
-                    break;
-
-                case "VC100":
-                    progid = "VisualStudio.DTE.10.0";
-                    break;
-
-                case "VC120":
-                    progid = "VisualStudio.DTE.12.0";
-                    break;
-
-                default:
-                    throw new ApplicationException("Can't handle VS version: " + version);
-            }
-
-            return progid;
-        }
-
-        public static bool SetProjectWorkingDir(object sol, string project_name, string working_dir)
-        {
-            bool made_change = false;
-            Console.WriteLine("Looking for project {0}...", project_name);
-            try
-            {
-                object prjs = ViaCOM.GetProperty(sol, "Projects");
-                object count = ViaCOM.GetProperty(prjs, "Count");
-                for(int i = 1; i <= (int)count; ++i)
-                {
-                    object[] prjItemArgs = { (object)i };
-                    object prj = ViaCOM.CallMethod(prjs, "Item", prjItemArgs);
-                    string name = (string)ViaCOM.GetProperty(prj, "Name");
-                    if (0 == string.Compare(name, project_name, ignore_case))
-                    {
-                        Console.WriteLine("Found project: {0}", project_name);
-                        Console.WriteLine("Setting working directory");
-
-                        string full_project_name = (string)ViaCOM.GetProperty(prj, "FullName");
-                        Console.WriteLine(full_project_name);
-
-                        // *NOTE:Mani Thanks to incompatibilities between different versions of the 
-                        // VCProjectEngine.dll assembly, we can't cast the objects recevied from the DTE to
-                        // the VCProjectEngine types from a different version than the one built 
-                        // with. ie, VisualStudio.DTE.7.1 objects can't be converted in a project built 
-                        // in VS 8.0. To avoid this problem, we can use the com object interfaces directly, 
-                        // without the type casting. Its tedious code, but it seems to work.
-
-                        // oCfgs should be assigned to a 'Project.Configurations' collection.
-                        object oCfgs = ViaCOM.GetProperty(ViaCOM.GetProperty(prj, "Object"), "Configurations");
-
-                        // oCount will be assigned to the number of configs present in oCfgs.
-                        object oCount = ViaCOM.GetProperty(oCfgs, "Count");
-
-                        for (int cfgIndex = 1; cfgIndex <= (int)oCount; ++cfgIndex)
-                        {
-                            object[] itemArgs = {(object)cfgIndex};
-                            object oCfg = ViaCOM.CallMethod(oCfgs, "Item", itemArgs);
-                            object oDebugSettings = ViaCOM.GetProperty(oCfg, "DebugSettings");
-                            ViaCOM.SetProperty(oDebugSettings, "WorkingDirectory", (object)working_dir);
-                        }
-
-                        break;
-                    }
-                }
-                made_change = true;
-            }
-            catch( Exception e )
-            {
-                Console.WriteLine(e.Message);
-                Console.WriteLine("Failed to set working dir for project, {0}.", project_name);
-            }
-
-            return made_change;
-        }
-
-        public static bool SetStartupProject(string startup_project)
-        {
-            bool result = false;
-            try
-            {
-                // You need the 'unique name of the project to set StartupProjects.
-                // find the project by generic name.
-                Console.WriteLine("Trying to set \"{0}\" to the startup project", startup_project);
-                object prjs = ViaCOM.GetProperty(solution, "Projects");
-                object count = ViaCOM.GetProperty(prjs, "Count");
-                for (int i = 1; i <= (int)count; ++i)
-                {
-                    object[] itemArgs = { (object)i };
-                    object prj = ViaCOM.CallMethod(prjs, "Item", itemArgs);
-                    object prjName = ViaCOM.GetProperty(prj, "Name");
-                    if (0 == string.Compare((string)prjName, startup_project, ignore_case))
-                    {
-                        object solBuild = ViaCOM.GetProperty(solution, "SolutionBuild");
-                        ViaCOM.SetProperty(solBuild, "StartupProjects", ViaCOM.GetProperty(prj, "UniqueName"));
-                        Console.WriteLine("  Success!");
-                        result = true;
-                        break;
-                    }
-                }
-
-                if (result == false)
-                {
-                    Console.WriteLine("  Could not find project \"{0}\" in the solution.", startup_project);
-                }
-            }
-            catch (Exception e)
-            {
-                Console.WriteLine("  Failed to set the startup project!");
-                Console.WriteLine(e.Message);
-            }
-            return result;
-        }
-
-        public static bool SetActiveConfig(string config)
-        {
-            bool result = false;
-            try
-            {
-                Console.WriteLine("Trying to set active config to \"{0}\"", config);
-                object solBuild = ViaCOM.GetProperty(solution, "SolutionBuild");
-                object solCfgs = ViaCOM.GetProperty(solBuild, "SolutionConfigurations");
-                object[] itemArgs = { (object)config };
-                object solCfg = ViaCOM.CallMethod(solCfgs, "Item", itemArgs);
-                ViaCOM.CallMethod(solCfg, "Activate", null);
-                Console.WriteLine("  Success!");
-                result = true;
-            }
-            catch (Exception e)
-            {
-                Console.WriteLine("  Failed to set \"{0}\" as the active config.", config);
-                Console.WriteLine(e.Message);
-            }
-            return result;
-        }
-    }
-}
-- 
cgit v1.2.3


From 454da876dc648d34aacf27217952e640f4fdaa88 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 15 Aug 2016 17:12:37 -0400
Subject: Backed out changeset e187a6b45ce6: restored VSTool et al.

---
 autobuild.xml                         |  34 ++
 indra/cmake/Variables.cmake           |   1 +
 indra/newview/CMakeLists.txt          |  15 +
 indra/tools/vstool/DispatchUtility.cs | 271 +++++++++++++
 indra/tools/vstool/README.txt         |   9 +
 indra/tools/vstool/VSTool.csproj      |  98 +++++
 indra/tools/vstool/VSTool.exe         | Bin 0 -> 24576 bytes
 indra/tools/vstool/VSTool.sln         |  19 +
 indra/tools/vstool/app.config         |   3 +
 indra/tools/vstool/main.cs            | 729 ++++++++++++++++++++++++++++++++++
 10 files changed, 1179 insertions(+)
 create mode 100644 indra/tools/vstool/DispatchUtility.cs
 create mode 100644 indra/tools/vstool/README.txt
 create mode 100755 indra/tools/vstool/VSTool.csproj
 create mode 100755 indra/tools/vstool/VSTool.exe
 create mode 100755 indra/tools/vstool/VSTool.sln
 create mode 100644 indra/tools/vstool/app.config
 create mode 100755 indra/tools/vstool/main.cs

diff --git a/autobuild.xml b/autobuild.xml
index 5a91ba15f5..072dfa678a 100755
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -2617,6 +2617,14 @@
                 <key>arguments</key>
                 <array>
                   <string>..\indra</string>
+                  <string>&amp;&amp;</string>
+                  <string>..\indra\tools\vstool\VSTool.exe</string>
+                  <string>--solution</string>
+                  <string>SecondLife.sln</string>
+                  <string>--config</string>
+                  <string>RelWithDebInfo</string>
+                  <string>--startup</string>
+                  <string>secondlife-bin</string>
                 </array>
                 <key>options</key>
                 <array>
@@ -2655,11 +2663,20 @@
                 <key>arguments</key>
                 <array>
                   <string>..\indra</string>
+                  <string>&amp;&amp;</string>
+                  <string>..\indra\tools\vstool\VSTool.exe</string>
+                  <string>--solution</string>
+                  <string>SecondLife.sln</string>
+                  <string>--config</string>
+                  <string>RelWithDebInfo</string>
+                  <string>--startup</string>
+                  <string>secondlife-bin</string>
                 </array>
                 <key>options</key>
                 <array>
                   <string>-G</string>
                   <string>"Visual Studio 12"</string>
+                  <string>-DUNATTENDED:BOOL=ON</string>
                   <string>-DINSTALL_PROPRIETARY=FALSE</string>
                   <string>-DUSE_KDU=FALSE</string>
                 </array>
@@ -2688,6 +2705,14 @@
                 <key>arguments</key>
                 <array>
                   <string>..\indra</string>
+                  <string>&amp;&amp;</string>
+                  <string>..\indra\tools\vstool\VSTool.exe</string>
+                  <string>--solution</string>
+                  <string>SecondLife.sln</string>
+                  <string>--config</string>
+                  <string>Release</string>
+                  <string>--startup</string>
+                  <string>secondlife-bin</string>
                 </array>
                 <key>options</key>
                 <array>
@@ -2724,11 +2749,20 @@
                 <key>arguments</key>
                 <array>
                   <string>..\indra</string>
+                  <string>&amp;&amp;</string>
+                  <string>..\indra\tools\vstool\VSTool.exe</string>
+                  <string>--solution</string>
+                  <string>SecondLife.sln</string>
+                  <string>--config</string>
+                  <string>Release</string>
+                  <string>--startup</string>
+                  <string>secondlife-bin</string>
                 </array>
                 <key>options</key>
                 <array>
                   <string>-G</string>
                   <string>"Visual Studio 12"</string>
+                  <string>-DUNATTENDED:BOOL=ON</string>
                   <string>-DINSTALL_PROPRIETARY=FALSE</string>
                   <string>-DUSE_KDU=FALSE</string>
                 </array>
diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake
index 8292a0c63d..63e296b556 100644
--- a/indra/cmake/Variables.cmake
+++ b/indra/cmake/Variables.cmake
@@ -164,6 +164,7 @@ set(SIGNING_IDENTITY "" CACHE STRING "Specifies the signing identity to use, if
 
 set(VERSION_BUILD "0" CACHE STRING "Revision number passed in from the outside")
 set(USESYSTEMLIBS OFF CACHE BOOL "Use libraries from your system rather than Linden-supplied prebuilt libraries.")
+set(UNATTENDED OFF CACHE BOOL "Should be set to ON for building with VC Express editions.")
 
 set(USE_PRECOMPILED_HEADERS ON CACHE BOOL "Enable use of precompiled header directives where supported.")
 
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 586a56b49a..dce0ea73cd 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1799,6 +1799,21 @@ if (WINDOWS)
    windows-crash-logger
     )
 
+    # sets the 'working directory' for debugging from visual studio.
+    if (NOT UNATTENDED)
+        add_custom_command(
+            TARGET ${VIEWER_BINARY_NAME} POST_BUILD
+            COMMAND ${CMAKE_SOURCE_DIR}/tools/vstool/vstool.exe
+            ARGS
+              --solution
+              ${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}.sln
+              --workingdir
+              ${VIEWER_BINARY_NAME}
+              "${CMAKE_CURRENT_SOURCE_DIR}"
+            COMMENT "Setting the ${VIEWER_BINARY_NAME} working directory for debugging."
+            )
+    endif (NOT UNATTENDED)
+
     if (PACKAGE)
       add_custom_command(
         OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/event_host.tar.bz2
diff --git a/indra/tools/vstool/DispatchUtility.cs b/indra/tools/vstool/DispatchUtility.cs
new file mode 100644
index 0000000000..6056ac55a1
--- /dev/null
+++ b/indra/tools/vstool/DispatchUtility.cs
@@ -0,0 +1,271 @@
+#region Using Directives
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Runtime.InteropServices;
+using System.Reflection;
+using System.Security.Permissions;
+
+#endregion
+
+namespace TestDispatchUtility
+{
+	/// <summary>
+	/// Provides helper methods for working with COM IDispatch objects that have a registered type library.
+	/// </summary>
+	public static class DispatchUtility
+	{
+		#region Private Constants
+
+		private const int S_OK = 0; //From WinError.h
+		private const int LOCALE_SYSTEM_DEFAULT = 2 << 10; //From WinNT.h == 2048 == 0x800
+
+		#endregion
+
+		#region Public Methods
+
+		/// <summary>
+		/// Gets whether the specified object implements IDispatch.
+		/// </summary>
+		/// <param name="obj">An object to check.</param>
+		/// <returns>True if the object implements IDispatch.  False otherwise.</returns>
+		public static bool ImplementsIDispatch(object obj)
+		{
+			bool result = obj is IDispatchInfo;
+			return result;
+		}
+
+		/// <summary>
+		/// Gets a Type that can be used with reflection.
+		/// </summary>
+		/// <param name="obj">An object that implements IDispatch.</param>
+		/// <param name="throwIfNotFound">Whether an exception should be thrown if a Type can't be obtained.</param>
+		/// <returns>A .NET Type that can be used with reflection.</returns>
+		/// <exception cref="InvalidCastException">If <paramref name="obj"/> doesn't implement IDispatch.</exception>
+		[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
+		public static Type GetType(object obj, bool throwIfNotFound)
+		{
+			RequireReference(obj, "obj");
+			Type result = GetType((IDispatchInfo)obj, throwIfNotFound);
+			return result;
+		}
+
+		/// <summary>
+		/// Tries to get the DISPID for the requested member name.
+		/// </summary>
+		/// <param name="obj">An object that implements IDispatch.</param>
+		/// <param name="name">The name of a member to lookup.</param>
+		/// <param name="dispId">If the method returns true, this holds the DISPID on output.
+		/// If the method returns false, this value should be ignored.</param>
+		/// <returns>True if the member was found and resolved to a DISPID.  False otherwise.</returns>
+		/// <exception cref="InvalidCastException">If <paramref name="obj"/> doesn't implement IDispatch.</exception>
+		[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
+		public static bool TryGetDispId(object obj, string name, out int dispId)
+		{
+			RequireReference(obj, "obj");
+			bool result = TryGetDispId((IDispatchInfo)obj, name, out dispId);
+			return result;
+		}
+
+		/// <summary>
+		/// Invokes a member by DISPID.
+		/// </summary>
+		/// <param name="obj">An object that implements IDispatch.</param>
+		/// <param name="dispId">The DISPID of a member.  This can be obtained using
+		/// <see cref="TryGetDispId(object, string, out int)"/>.</param>
+		/// <param name="args">The arguments to pass to the member.</param>
+		/// <returns>The member's return value.</returns>
+		/// <remarks>
+		/// This can invoke a method or a property get accessor.
+		/// </remarks>
+		public static object Invoke(object obj, int dispId, object[] args)
+		{
+			string memberName = "[DispId=" + dispId + "]";
+			object result = Invoke(obj, memberName, args);
+			return result;
+		}
+
+		/// <summary>
+		/// Invokes a member by name.
+		/// </summary>
+		/// <param name="obj">An object.</param>
+		/// <param name="memberName">The name of the member to invoke.</param>
+		/// <param name="args">The arguments to pass to the member.</param>
+		/// <returns>The member's return value.</returns>
+		/// <remarks>
+		/// This can invoke a method or a property get accessor.
+		/// </remarks>
+		public static object Invoke(object obj, string memberName, object[] args)
+		{
+			RequireReference(obj, "obj");
+			Type type = obj.GetType();
+			object result = type.InvokeMember(memberName, BindingFlags.InvokeMethod | BindingFlags.GetProperty,
+				null, obj, args, null);
+			return result;
+		}
+
+		#endregion
+
+		#region Private Methods
+
+		/// <summary>
+		/// Requires that the value is non-null.
+		/// </summary>
+		/// <typeparam name="T">The type of the value.</typeparam>
+		/// <param name="value">The value to check.</param>
+		/// <param name="name">The name of the value.</param>
+		private static void RequireReference<T>(T value, string name) where T : class
+		{
+			if (value == null)
+			{
+				throw new ArgumentNullException(name);
+			}
+		}
+
+		/// <summary>
+		/// Gets a Type that can be used with reflection.
+		/// </summary>
+		/// <param name="dispatch">An object that implements IDispatch.</param>
+		/// <param name="throwIfNotFound">Whether an exception should be thrown if a Type can't be obtained.</param>
+		/// <returns>A .NET Type that can be used with reflection.</returns>
+		private static Type GetType(IDispatchInfo dispatch, bool throwIfNotFound)
+		{
+			RequireReference(dispatch, "dispatch");
+
+			Type result = null;
+			int typeInfoCount;
+			int hr = dispatch.GetTypeInfoCount(out typeInfoCount);
+			if (hr == S_OK && typeInfoCount > 0)
+			{
+				// Type info isn't usually culture-aware for IDispatch, so we might as well pass
+				// the default locale instead of looking up the current thread's LCID each time
+				// (via CultureInfo.CurrentCulture.LCID).
+				dispatch.GetTypeInfo(0, LOCALE_SYSTEM_DEFAULT, out result);
+			}
+
+			if (result == null && throwIfNotFound)
+			{
+				// If the GetTypeInfoCount called failed, throw an exception for that.
+				Marshal.ThrowExceptionForHR(hr);
+
+				// Otherwise, throw the same exception that Type.GetType would throw.
+				throw new TypeLoadException();
+			}
+
+			return result;
+		}
+
+		/// <summary>
+		/// Tries to get the DISPID for the requested member name.
+		/// </summary>
+		/// <param name="dispatch">An object that implements IDispatch.</param>
+		/// <param name="name">The name of a member to lookup.</param>
+		/// <param name="dispId">If the method returns true, this holds the DISPID on output.
+		/// If the method returns false, this value should be ignored.</param>
+		/// <returns>True if the member was found and resolved to a DISPID.  False otherwise.</returns>
+		private static bool TryGetDispId(IDispatchInfo dispatch, string name, out int dispId)
+		{
+			RequireReference(dispatch, "dispatch");
+			RequireReference(name, "name");
+
+			bool result = false;
+
+			// Members names aren't usually culture-aware for IDispatch, so we might as well
+			// pass the default locale instead of looking up the current thread's LCID each time
+			// (via CultureInfo.CurrentCulture.LCID).
+			Guid iidNull = Guid.Empty;
+			int hr = dispatch.GetDispId(ref iidNull, ref name, 1, LOCALE_SYSTEM_DEFAULT, out dispId);
+
+			const int DISP_E_UNKNOWNNAME = unchecked((int)0x80020006); //From WinError.h
+			const int DISPID_UNKNOWN = -1; //From OAIdl.idl
+			if (hr == S_OK)
+			{
+				result = true;
+			}
+			else if (hr == DISP_E_UNKNOWNNAME && dispId == DISPID_UNKNOWN)
+			{
+				// This is the only supported "error" case because it means IDispatch
+				// is saying it doesn't know the member we asked about.
+				result = false;
+			}
+			else
+			{
+				// The other documented result codes are all errors.
+				Marshal.ThrowExceptionForHR(hr);
+			}
+
+			return result;
+		}
+
+		#endregion
+
+		#region Private Interfaces
+
+		/// <summary>
+		/// A partial declaration of IDispatch used to lookup Type information and DISPIDs.
+		/// </summary>
+		/// <remarks>
+		/// This interface only declares the first three methods of IDispatch.  It omits the
+		/// fourth method (Invoke) because there are already plenty of ways to do dynamic
+		/// invocation in .NET.  But the first three methods provide dynamic type metadata
+		/// discovery, which .NET doesn't provide normally if you have a System.__ComObject
+		/// RCW instead of a strongly-typed RCW.
+		/// <para/>
+		/// Note: The original declaration of IDispatch is in OAIdl.idl.
+		/// </remarks>
+		[ComImport]
+		[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
+		[Guid("00020400-0000-0000-C000-000000000046")]
+		private interface IDispatchInfo
+		{
+			/// <summary>
+			/// Gets the number of Types that the object provides (0 or 1).
+			/// </summary>
+			/// <param name="typeInfoCount">Returns 0 or 1 for the number of Types provided by <see cref="GetTypeInfo"/>.</param>
+			/// <remarks>
+			/// http://msdn.microsoft.com/en-us/library/da876d53-cb8a-465c-a43e-c0eb272e2a12(VS.85)
+			/// </remarks>
+			[PreserveSig]
+			int GetTypeInfoCount(out int typeInfoCount);
+
+			/// <summary>
+			/// Gets the Type information for an object if <see cref="GetTypeInfoCount"/> returned 1.
+			/// </summary>
+			/// <param name="typeInfoIndex">Must be 0.</param>
+			/// <param name="lcid">Typically, LOCALE_SYSTEM_DEFAULT (2048).</param>
+			/// <param name="typeInfo">Returns the object's Type information.</param>
+			/// <remarks>
+			/// http://msdn.microsoft.com/en-us/library/cc1ec9aa-6c40-4e70-819c-a7c6dd6b8c99(VS.85)
+			/// </remarks>
+			void GetTypeInfo(int typeInfoIndex, int lcid, [MarshalAs(UnmanagedType.CustomMarshaler,
+				MarshalTypeRef = typeof(System.Runtime.InteropServices.CustomMarshalers.TypeToTypeInfoMarshaler))] out Type typeInfo);
+
+			/// <summary>
+			/// Gets the DISPID of the specified member name.
+			/// </summary>
+			/// <param name="riid">Must be IID_NULL.  Pass a copy of Guid.Empty.</param>
+			/// <param name="name">The name of the member to look up.</param>
+			/// <param name="nameCount">Must be 1.</param>
+			/// <param name="lcid">Typically, LOCALE_SYSTEM_DEFAULT (2048).</param>
+			/// <param name="dispId">If a member with the requested <paramref name="name"/>
+			/// is found, this returns its DISPID and the method's return value is 0.
+			/// If the method returns a non-zero value, then this parameter's output value is
+			/// undefined.</param>
+			/// <returns>Zero for success. Non-zero for failure.</returns>
+			/// <remarks>
+			/// http://msdn.microsoft.com/en-us/library/6f6cf233-3481-436e-8d6a-51f93bf91619(VS.85)
+			/// </remarks>
+			[PreserveSig]
+			int GetDispId(ref Guid riid, ref string name, int nameCount, int lcid, out int dispId);
+
+			// NOTE: The real IDispatch also has an Invoke method next, but we don't need it.
+			// We can invoke methods using .NET's Type.InvokeMember method with the special
+			// [DISPID=n] syntax for member "names", or we can get a .NET Type using GetTypeInfo
+			// and invoke methods on that through reflection.
+			// Type.InvokeMember: http://msdn.microsoft.com/en-us/library/de3dhzwy.aspx
+		}
+
+		#endregion
+	}
+}
diff --git a/indra/tools/vstool/README.txt b/indra/tools/vstool/README.txt
new file mode 100644
index 0000000000..e419180031
--- /dev/null
+++ b/indra/tools/vstool/README.txt
@@ -0,0 +1,9 @@
+VSTool is a command line utility to manipulate VisualStudio settings. 
+
+The windows cmake project configuration uses VSTool.exe
+
+A handy upgrade:
+ figure out how to make cmake build this csharp app
+ - or write the app using script (jscript?!?) so it doesn't need to be built.
+
+
diff --git a/indra/tools/vstool/VSTool.csproj b/indra/tools/vstool/VSTool.csproj
new file mode 100755
index 0000000000..7f431e85c7
--- /dev/null
+++ b/indra/tools/vstool/VSTool.csproj
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
+  <PropertyGroup>
+    <ProjectType>Local</ProjectType>
+    <ProductVersion>8.0.50727</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{96943E2D-1373-4617-A117-D0F997A94919}</ProjectGuid>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ApplicationIcon>
+    </ApplicationIcon>
+    <AssemblyKeyContainerName>
+    </AssemblyKeyContainerName>
+    <AssemblyName>VSTool</AssemblyName>
+    <AssemblyOriginatorKeyFile>
+    </AssemblyOriginatorKeyFile>
+    <DefaultClientScript>JScript</DefaultClientScript>
+    <DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
+    <DefaultTargetSchema>IE50</DefaultTargetSchema>
+    <DelaySign>false</DelaySign>
+    <OutputType>Exe</OutputType>
+    <RootNamespace>VSTool</RootNamespace>
+    <RunPostBuildEvent>Always</RunPostBuildEvent>
+    <StartupObject>VSTool.VSToolMain</StartupObject>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <UpgradeBackupLocation>
+    </UpgradeBackupLocation>
+    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
+    <OldToolsVersion>2.0</OldToolsVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <OutputPath>.\</OutputPath>
+    <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
+    <BaseAddress>285212672</BaseAddress>
+    <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
+    <ConfigurationOverrideFile>
+    </ConfigurationOverrideFile>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DocumentationFile>
+    </DocumentationFile>
+    <DebugSymbols>true</DebugSymbols>
+    <FileAlignment>4096</FileAlignment>
+    <NoStdLib>false</NoStdLib>
+    <NoWarn>
+    </NoWarn>
+    <Optimize>false</Optimize>
+    <RegisterForComInterop>false</RegisterForComInterop>
+    <RemoveIntegerChecks>false</RemoveIntegerChecks>
+    <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+    <WarningLevel>4</WarningLevel>
+    <DebugType>full</DebugType>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <OutputPath>.\</OutputPath>
+    <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
+    <BaseAddress>285212672</BaseAddress>
+    <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
+    <ConfigurationOverrideFile>
+    </ConfigurationOverrideFile>
+    <DefineConstants>TRACE</DefineConstants>
+    <DocumentationFile>
+    </DocumentationFile>
+    <DebugSymbols>false</DebugSymbols>
+    <FileAlignment>4096</FileAlignment>
+    <NoStdLib>false</NoStdLib>
+    <NoWarn>
+    </NoWarn>
+    <Optimize>true</Optimize>
+    <RegisterForComInterop>false</RegisterForComInterop>
+    <RemoveIntegerChecks>false</RemoveIntegerChecks>
+    <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+    <WarningLevel>4</WarningLevel>
+    <DebugType>none</DebugType>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System">
+      <Name>System</Name>
+    </Reference>
+    <Reference Include="System.Data">
+      <Name>System.Data</Name>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="main.cs">
+      <SubType>Code</SubType>
+    </Compile>
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <PropertyGroup>
+    <PreBuildEvent>
+    </PreBuildEvent>
+    <PostBuildEvent>
+    </PostBuildEvent>
+  </PropertyGroup>
+</Project>
\ No newline at end of file
diff --git a/indra/tools/vstool/VSTool.exe b/indra/tools/vstool/VSTool.exe
new file mode 100755
index 0000000000..854290b90a
Binary files /dev/null and b/indra/tools/vstool/VSTool.exe differ
diff --git a/indra/tools/vstool/VSTool.sln b/indra/tools/vstool/VSTool.sln
new file mode 100755
index 0000000000..21e3d75971
--- /dev/null
+++ b/indra/tools/vstool/VSTool.sln
@@ -0,0 +1,19 @@
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VSTool", "VSTool.csproj", "{96943E2D-1373-4617-A117-D0F997A94919}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{96943E2D-1373-4617-A117-D0F997A94919}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{96943E2D-1373-4617-A117-D0F997A94919}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{96943E2D-1373-4617-A117-D0F997A94919}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{96943E2D-1373-4617-A117-D0F997A94919}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/indra/tools/vstool/app.config b/indra/tools/vstool/app.config
new file mode 100644
index 0000000000..8494f728ff
--- /dev/null
+++ b/indra/tools/vstool/app.config
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<configuration>
+<startup><supportedRuntime version="v2.0.50727"/></startup></configuration>
diff --git a/indra/tools/vstool/main.cs b/indra/tools/vstool/main.cs
new file mode 100755
index 0000000000..ef2e582b90
--- /dev/null
+++ b/indra/tools/vstool/main.cs
@@ -0,0 +1,729 @@
+// Code about getting running instances visual studio
+// was borrowed from 
+// http://www.codeproject.com/KB/cs/automatingvisualstudio.aspx
+
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Runtime.InteropServices.ComTypes;
+using Microsoft.CSharp;
+
+namespace VSTool
+{
+    // The MessageFilter class comes from:
+    // http://msdn.microsoft.com/en-us/library/ms228772(VS.80).aspx
+    // It allows vstool to get timing error messages from 
+    // visualstudio and handle them.
+    public class MessageFilter : IOleMessageFilter
+    {
+        //
+        // Class containing the IOleMessageFilter
+        // thread error-handling functions.
+
+        // Start the filter.
+        public static void Register()
+        {
+            IOleMessageFilter newFilter = new MessageFilter(); 
+            IOleMessageFilter oldFilter = null; 
+            CoRegisterMessageFilter(newFilter, out oldFilter);
+        }
+
+        // Done with the filter, close it.
+        public static void Revoke()
+        {
+            IOleMessageFilter oldFilter = null; 
+            CoRegisterMessageFilter(null, out oldFilter);
+        }
+
+        //
+        // IOleMessageFilter functions.
+        // Handle incoming thread requests.
+        int IOleMessageFilter.HandleInComingCall(int dwCallType, 
+          System.IntPtr hTaskCaller, int dwTickCount, System.IntPtr 
+          lpInterfaceInfo) 
+        {
+            //Return the flag SERVERCALL_ISHANDLED.
+            return 0;
+        }
+
+        // Thread call was rejected, so try again.
+        int IOleMessageFilter.RetryRejectedCall(System.IntPtr 
+          hTaskCallee, int dwTickCount, int dwRejectType)
+        {
+            if (dwRejectType == 2)
+            // flag = SERVERCALL_RETRYLATER.
+            {
+                // Retry the thread call immediately if return >=0 & 
+                // <100.
+                return 99;
+            }
+            // Too busy; cancel call.
+            return -1;
+        }
+
+        int IOleMessageFilter.MessagePending(System.IntPtr hTaskCallee, 
+          int dwTickCount, int dwPendingType)
+        {
+            //Return the flag PENDINGMSG_WAITDEFPROCESS.
+            return 2; 
+        }
+
+        // Implement the IOleMessageFilter interface.
+        [DllImport("Ole32.dll")]
+        private static extern int 
+          CoRegisterMessageFilter(IOleMessageFilter newFilter, out 
+          IOleMessageFilter oldFilter);
+    }
+
+    [ComImport(), Guid("00000016-0000-0000-C000-000000000046"), 
+    InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+    interface IOleMessageFilter 
+    {
+        [PreserveSig]
+        int HandleInComingCall( 
+            int dwCallType, 
+            IntPtr hTaskCaller, 
+            int dwTickCount, 
+            IntPtr lpInterfaceInfo);
+
+        [PreserveSig]
+        int RetryRejectedCall( 
+            IntPtr hTaskCallee, 
+            int dwTickCount,
+            int dwRejectType);
+
+        [PreserveSig]
+        int MessagePending( 
+            IntPtr hTaskCallee, 
+            int dwTickCount,
+            int dwPendingType);
+    }
+
+    class ViaCOM
+    {
+        public static object GetProperty(object from_obj, string prop_name)
+        {
+            try
+            {
+                Type objType = from_obj.GetType();
+                return objType.InvokeMember(
+                    prop_name,
+                    BindingFlags.GetProperty, null,
+                    from_obj,
+                    null);
+            }
+            catch (Exception e)
+            {
+                Console.WriteLine("Error getting property: \"{0}\"", prop_name);
+                Console.WriteLine(e.Message);
+                throw e;
+            }
+        }
+
+        public static object SetProperty(object from_obj, string prop_name, object new_value)
+        {
+            try
+            {
+                object[] args = { new_value };
+                Type objType = from_obj.GetType();
+                return objType.InvokeMember(
+                    prop_name,
+                    BindingFlags.DeclaredOnly |
+                    BindingFlags.Public |
+                    BindingFlags.NonPublic |
+                    BindingFlags.Instance |
+                    BindingFlags.SetProperty,
+                    null,
+                    from_obj,
+                    args);
+            }
+            catch (Exception e)
+            {
+                Console.WriteLine("Error setting property: \"{0}\"", prop_name);
+                Console.WriteLine(e.Message);
+                throw e;
+            }
+        }
+
+        public static object CallMethod(object from_obj, string method_name, params object[] args)
+        {
+            try
+            {
+                Type objType = from_obj.GetType();
+                return objType.InvokeMember(
+                    method_name,
+                    BindingFlags.DeclaredOnly |
+                    BindingFlags.Public |
+                    BindingFlags.NonPublic |
+                    BindingFlags.Instance |
+                    BindingFlags.InvokeMethod,
+                    null,
+                    from_obj,
+                    args);
+            }
+            catch (Exception e)
+            {
+                Console.WriteLine("Error calling method \"{0}\"", method_name);
+                Console.WriteLine(e.Message);
+                throw e;
+            }
+        }
+    };
+
+    /// <summary>
+	/// The main entry point class for VSTool.
+	/// </summary>
+    class VSToolMain
+    {
+        #region Interop imports
+        [DllImport("ole32.dll")]  
+        public static extern int GetRunningObjectTable(int reserved, out IRunningObjectTable prot); 
+ 
+        [DllImport("ole32.dll")]  
+        public static extern int  CreateBindCtx(int reserved, out IBindCtx ppbc);
+        #endregion 
+
+        static System.Boolean ignore_case = true;
+
+        static string solution_name = null;
+        static bool use_new_vs = false;
+        static Hashtable projectDict = new Hashtable();
+        static string startup_project = null;
+        static string config = null;
+
+        static object dte = null;
+        static object solution = null;
+
+        /// <summary>
+		/// The main entry point for the application.
+		/// </summary>
+		[STAThread]
+		static int Main(string[] args)
+		{
+            int retVal = 0;
+            bool need_save = false;
+
+            try
+            {
+                parse_command_line(args);
+
+                Console.WriteLine("Editing solution: {0}", solution_name);
+
+                bool found_open_solution = GetDTEAndSolution();
+
+                if (dte == null || solution == null)
+                {
+                    retVal = 1;
+                }
+                else
+                {
+                    MessageFilter.Register();
+
+                    // Walk through all of the projects in the solution
+                    // and list the type of each project.
+                    foreach (DictionaryEntry p in projectDict)
+                    {
+                        string project_name = (string)p.Key;
+                        string working_dir = (string)p.Value;
+                        if (SetProjectWorkingDir(solution, project_name, working_dir))
+                        {
+                            need_save = true;
+                        }
+                    }
+
+                    if (config != null)
+                    {
+                        need_save = SetActiveConfig(config);
+                    }
+
+                    if (startup_project != null)
+                    {
+                        need_save = SetStartupProject(startup_project);
+                    }
+
+                    if (need_save)
+                    {
+                        if (found_open_solution == false)
+                        {
+                            ViaCOM.CallMethod(solution, "Close", null);
+                        }
+                    }
+                }
+            }
+            catch (Exception e)
+            {
+                Console.WriteLine(e.Message);
+                retVal = 1;
+            }
+            finally
+            {
+                if (solution != null)
+                {
+                    Marshal.ReleaseComObject(solution);
+                    solution = null;
+                }
+
+                if (dte != null)
+                {
+                    Marshal.ReleaseComObject(dte);
+                    dte = null;
+                }
+
+                MessageFilter.Revoke();
+            }
+            return retVal;
+        }
+
+        public static bool parse_command_line(string[] args)
+        {
+            string options_desc = 
+                "--solution <solution_name>   : MSVC solution name. (required)\n" +
+                "--use_new_vs                 : Ignore running versions of visual studio.\n" +
+                "--workingdir <project> <dir> : Set working dir of a VC project.\n" +
+                "--config <config>            : Set the active config for the solution.\n" +
+                "--startup <project>          : Set the startup project for the solution.\n";
+
+            try
+            {
+                // Command line param parsing loop.
+                int i = 0;
+                for (; i < args.Length; ++i)
+                {
+                    if ("--solution" == args[i])
+                    {
+                        if (solution_name != null)
+                        {
+                            throw new ApplicationException("Found second --solution option");
+                        }
+                        solution_name = args[++i];
+                    }
+                    else if ("--use_new_vs" == args[i])
+                    {
+                        use_new_vs = true;
+                    }
+
+                    else if ("--workingdir" == args[i])
+                    {
+                        string project_name = args[++i];
+                        string working_dir = args[++i];
+                        projectDict.Add(project_name, working_dir);
+                    }
+                    else if ("--config" == args[i])
+                    {
+                        if (config != null)
+                        {
+                            throw new ApplicationException("Found second --config option");
+                        }
+                        config = args[++i];
+                    }
+                    else if ("--startup" == args[i])
+                    {
+                        if (startup_project != null)
+                        {
+                            throw new ApplicationException("Found second --startup option");
+                        }
+                        startup_project = args[++i];
+                    }
+                    else
+                    {
+                        throw new ApplicationException("Found unrecognized token on command line: " + args[i]);
+                    }
+                }
+
+                if (solution_name == null)
+                {
+                    throw new ApplicationException("The --solution option is required.");
+                }
+            }
+            catch(ApplicationException e)
+            {
+
+                Console.WriteLine("Oops! " + e.Message);
+                Console.Write("Command line:");
+                foreach (string arg in args)
+                {
+                    Console.Write(" " + arg);
+                }
+                Console.Write("\n\n");
+                Console.WriteLine("VSTool command line usage");
+                Console.Write(options_desc);
+                throw e;
+            }
+            return true;
+        }
+
+        public static bool GetDTEAndSolution()
+        {
+            bool found_open_solution = true;
+
+            Console.WriteLine("Looking for existing VisualStudio instance...");
+
+            // Get an instance of the currently running Visual Studio .NET IDE.
+            // dte = (EnvDTE.DTE)System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE.7.1");
+            string full_solution_name = System.IO.Path.GetFullPath(solution_name);
+            if (false == use_new_vs)
+            {
+                dte = GetIDEInstance(full_solution_name);
+            }
+
+            if (dte == null)
+            {
+                try
+                {
+                    Console.WriteLine("  Didn't find open solution, starting new background VisualStudio instance...");
+                    Console.WriteLine("  Reading .sln file version...");
+                    string version = GetSolutionVersion(full_solution_name);
+
+                    Console.WriteLine("  Using version: {0}...", version);
+                    string progid = GetVSProgID(version);
+
+                    Type objType = Type.GetTypeFromProgID(progid);
+                    dte = System.Activator.CreateInstance(objType);
+                    Console.WriteLine("  Reading solution: \"{0}\"", full_solution_name);
+
+                    solution = ViaCOM.GetProperty(dte, "Solution");
+                    object[] openArgs = { full_solution_name };
+                    ViaCOM.CallMethod(solution, "Open", openArgs);
+                }
+                catch (Exception e)
+                {
+                    Console.WriteLine(e.Message);
+                    Console.WriteLine("Quitting do to error opening: {0}", full_solution_name);
+                    solution = null;
+                    dte = null;
+                    return found_open_solution;
+                }
+                found_open_solution = false;
+            }
+
+            if (solution == null)
+            {
+                solution = ViaCOM.GetProperty(dte, "Solution");
+            }
+
+            return found_open_solution;
+        }
+
+        /// <summary>
+        /// Get the DTE object for the instance of Visual Studio IDE that has 
+        /// the specified solution open.
+        /// </summary>
+        /// <param name="solutionFile">The absolute filename of the solution</param>
+        /// <returns>Corresponding DTE object or null if no such IDE is running</returns>
+        public static object GetIDEInstance( string solutionFile )
+        {
+            Hashtable runningInstances = GetIDEInstances( true );
+            IDictionaryEnumerator enumerator = runningInstances.GetEnumerator();
+
+            while ( enumerator.MoveNext() )
+            {
+                try
+                {
+                    object ide = enumerator.Value;
+                    if (ide != null)
+                    {
+                        object sol = ViaCOM.GetProperty(ide, "Solution");
+                        if (0 == string.Compare((string)ViaCOM.GetProperty(sol, "FullName"), solutionFile, ignore_case))
+                        {
+                            return ide;
+                        }
+                    }
+                } 
+                catch{}
+            }
+
+            return null;
+        }
+
+        /// <summary>
+        /// Get a table of the currently running instances of the Visual Studio .NET IDE.
+        /// </summary>
+        /// <param name="openSolutionsOnly">Only return instances that have opened a solution</param>
+        /// <returns>A hashtable mapping the name of the IDE in the running object table to the corresponding DTE object</returns>
+        public static Hashtable GetIDEInstances( bool openSolutionsOnly )
+        {
+            Hashtable runningIDEInstances = new Hashtable();
+            Hashtable runningObjects = GetRunningObjectTable();
+
+            IDictionaryEnumerator rotEnumerator = runningObjects.GetEnumerator();
+            while ( rotEnumerator.MoveNext() )
+            {
+                string candidateName = (string) rotEnumerator.Key;
+                if (!candidateName.StartsWith("!VisualStudio.DTE"))
+                    continue;
+
+                object ide = rotEnumerator.Value;
+                if (ide == null)
+                    continue;
+
+                if (openSolutionsOnly)
+                {
+                    try
+                    {
+                        object sol = ViaCOM.GetProperty(ide, "Solution");
+                        string solutionFile = (string)ViaCOM.GetProperty(sol, "FullName");
+                        if (solutionFile != String.Empty)
+                        {
+                            runningIDEInstances[ candidateName ] = ide;
+                        }
+                    } 
+                    catch {}
+                }
+                else
+                {
+                    runningIDEInstances[ candidateName ] = ide;
+                }                       
+            }
+            return runningIDEInstances;
+        }
+
+        /// <summary>
+        /// Get a snapshot of the running object table (ROT).
+        /// </summary>
+        /// <returns>A hashtable mapping the name of the object in the ROT to the corresponding object</returns>
+        [STAThread]
+        public static Hashtable GetRunningObjectTable()
+        {
+            Hashtable result = new Hashtable();
+
+            int numFetched = 0;
+            IRunningObjectTable runningObjectTable;   
+            IEnumMoniker monikerEnumerator;
+            IMoniker[] monikers = new IMoniker[1];
+
+            GetRunningObjectTable(0, out runningObjectTable);    
+            runningObjectTable.EnumRunning(out monikerEnumerator);
+            monikerEnumerator.Reset();          
+            
+            while (monikerEnumerator.Next(1, monikers, new IntPtr(numFetched)) == 0)
+            {     
+                IBindCtx ctx;
+                CreateBindCtx(0, out ctx);     
+                    
+                string runningObjectName;
+                monikers[0].GetDisplayName(ctx, null, out runningObjectName);
+
+                object runningObjectVal;  
+                runningObjectTable.GetObject( monikers[0], out runningObjectVal); 
+
+                result[ runningObjectName ] = runningObjectVal;
+            } 
+
+            return result;
+        }
+
+        public static string GetSolutionVersion(string solutionFullFileName) 
+        {
+            string version;
+            System.IO.StreamReader solutionStreamReader = null;
+            string firstLine;
+            string format;
+            
+            try
+            {
+                solutionStreamReader = new System.IO.StreamReader(solutionFullFileName);
+                do
+                {
+                    firstLine = solutionStreamReader.ReadLine();
+                }
+                while (firstLine == "");
+                
+                format = firstLine.Substring(firstLine.LastIndexOf(" ")).Trim();
+        
+                switch(format)
+                {
+                    case "7.00":
+                        version = "VC70";
+                        break;
+
+                    case "8.00":
+                        version = "VC71";
+                        break;
+
+                    case "9.00":
+                        version = "VC80";
+                        break;
+                
+                    case "10.00":
+                        version = "VC90";
+                        break;
+
+                    case "11.00":
+                        version = "VC100";
+                        break;
+
+                    case "12.00":
+                        version = "VC120";
+                        break;
+
+                    default:
+                        throw new ApplicationException("Unknown .sln version: " + format);
+                }
+            }
+            finally
+            {
+                if(solutionStreamReader != null) 
+                {
+                    solutionStreamReader.Close();
+                }
+            }
+            
+            return version;
+        }
+
+        public static string GetVSProgID(string version)
+        {
+            string progid = null;
+            switch(version)
+            {
+                case "VC70":
+                    progid = "VisualStudio.DTE.7";
+                    break;
+
+                case "VC71":
+                    progid = "VisualStudio.DTE.7.1";
+                    break;
+
+                case "VC80":
+                    progid = "VisualStudio.DTE.8.0";
+                    break;
+                
+                case "VC90":
+                    progid = "VisualStudio.DTE.9.0";
+                    break;
+
+                case "VC100":
+                    progid = "VisualStudio.DTE.10.0";
+                    break;
+
+                case "VC120":
+                    progid = "VisualStudio.DTE.12.0";
+                    break;
+
+                default:
+                    throw new ApplicationException("Can't handle VS version: " + version);
+            }
+
+            return progid;
+        }
+
+        public static bool SetProjectWorkingDir(object sol, string project_name, string working_dir)
+        {
+            bool made_change = false;
+            Console.WriteLine("Looking for project {0}...", project_name);
+            try
+            {
+                object prjs = ViaCOM.GetProperty(sol, "Projects");
+                object count = ViaCOM.GetProperty(prjs, "Count");
+                for(int i = 1; i <= (int)count; ++i)
+                {
+                    object[] prjItemArgs = { (object)i };
+                    object prj = ViaCOM.CallMethod(prjs, "Item", prjItemArgs);
+                    string name = (string)ViaCOM.GetProperty(prj, "Name");
+                    if (0 == string.Compare(name, project_name, ignore_case))
+                    {
+                        Console.WriteLine("Found project: {0}", project_name);
+                        Console.WriteLine("Setting working directory");
+
+                        string full_project_name = (string)ViaCOM.GetProperty(prj, "FullName");
+                        Console.WriteLine(full_project_name);
+
+                        // *NOTE:Mani Thanks to incompatibilities between different versions of the 
+                        // VCProjectEngine.dll assembly, we can't cast the objects recevied from the DTE to
+                        // the VCProjectEngine types from a different version than the one built 
+                        // with. ie, VisualStudio.DTE.7.1 objects can't be converted in a project built 
+                        // in VS 8.0. To avoid this problem, we can use the com object interfaces directly, 
+                        // without the type casting. Its tedious code, but it seems to work.
+
+                        // oCfgs should be assigned to a 'Project.Configurations' collection.
+                        object oCfgs = ViaCOM.GetProperty(ViaCOM.GetProperty(prj, "Object"), "Configurations");
+
+                        // oCount will be assigned to the number of configs present in oCfgs.
+                        object oCount = ViaCOM.GetProperty(oCfgs, "Count");
+
+                        for (int cfgIndex = 1; cfgIndex <= (int)oCount; ++cfgIndex)
+                        {
+                            object[] itemArgs = {(object)cfgIndex};
+                            object oCfg = ViaCOM.CallMethod(oCfgs, "Item", itemArgs);
+                            object oDebugSettings = ViaCOM.GetProperty(oCfg, "DebugSettings");
+                            ViaCOM.SetProperty(oDebugSettings, "WorkingDirectory", (object)working_dir);
+                        }
+
+                        break;
+                    }
+                }
+                made_change = true;
+            }
+            catch( Exception e )
+            {
+                Console.WriteLine(e.Message);
+                Console.WriteLine("Failed to set working dir for project, {0}.", project_name);
+            }
+
+            return made_change;
+        }
+
+        public static bool SetStartupProject(string startup_project)
+        {
+            bool result = false;
+            try
+            {
+                // You need the 'unique name of the project to set StartupProjects.
+                // find the project by generic name.
+                Console.WriteLine("Trying to set \"{0}\" to the startup project", startup_project);
+                object prjs = ViaCOM.GetProperty(solution, "Projects");
+                object count = ViaCOM.GetProperty(prjs, "Count");
+                for (int i = 1; i <= (int)count; ++i)
+                {
+                    object[] itemArgs = { (object)i };
+                    object prj = ViaCOM.CallMethod(prjs, "Item", itemArgs);
+                    object prjName = ViaCOM.GetProperty(prj, "Name");
+                    if (0 == string.Compare((string)prjName, startup_project, ignore_case))
+                    {
+                        object solBuild = ViaCOM.GetProperty(solution, "SolutionBuild");
+                        ViaCOM.SetProperty(solBuild, "StartupProjects", ViaCOM.GetProperty(prj, "UniqueName"));
+                        Console.WriteLine("  Success!");
+                        result = true;
+                        break;
+                    }
+                }
+
+                if (result == false)
+                {
+                    Console.WriteLine("  Could not find project \"{0}\" in the solution.", startup_project);
+                }
+            }
+            catch (Exception e)
+            {
+                Console.WriteLine("  Failed to set the startup project!");
+                Console.WriteLine(e.Message);
+            }
+            return result;
+        }
+
+        public static bool SetActiveConfig(string config)
+        {
+            bool result = false;
+            try
+            {
+                Console.WriteLine("Trying to set active config to \"{0}\"", config);
+                object solBuild = ViaCOM.GetProperty(solution, "SolutionBuild");
+                object solCfgs = ViaCOM.GetProperty(solBuild, "SolutionConfigurations");
+                object[] itemArgs = { (object)config };
+                object solCfg = ViaCOM.CallMethod(solCfgs, "Item", itemArgs);
+                ViaCOM.CallMethod(solCfg, "Activate", null);
+                Console.WriteLine("  Success!");
+                result = true;
+            }
+            catch (Exception e)
+            {
+                Console.WriteLine("  Failed to set \"{0}\" as the active config.", config);
+                Console.WriteLine(e.Message);
+            }
+            return result;
+        }
+    }
+}
-- 
cgit v1.2.3


From b0c434fadfb7085fa93d13b3f61f29d48c610834 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 15 Aug 2016 17:15:31 -0400
Subject: Set CMake UNATTENDED variable to suppress VSTool in TC builds.

---
 build.sh | 1 +
 1 file changed, 1 insertion(+)

diff --git a/build.sh b/build.sh
index cd2a9ebf5e..ab7a1faa37 100755
--- a/build.sh
+++ b/build.sh
@@ -97,6 +97,7 @@ pre_build()
 
     "$autobuild" configure --quiet -c $variant -- \
      -DPACKAGE:BOOL=ON \
+     -DUNATTENDED:BOOL=ON \
      -DRELEASE_CRASH_REPORTING:BOOL=ON \
      -DVIEWER_CHANNEL:STRING="\"$viewer_channel\"" \
      -DGRID:STRING="\"$viewer_grid\"" \
-- 
cgit v1.2.3