Remove VSTool

This commit is contained in:
Lirusaito
2018-05-02 18:54:48 -04:00
parent a8e8f6d409
commit dd49033a08
9 changed files with 0 additions and 1177 deletions

View File

@@ -3027,14 +3027,6 @@
<key>arguments</key>
<array>
<string>..\indra</string>
<string>&amp;&amp;</string>
<string>..\indra\tools\vstool\VSTool.exe</string>
<string>--solution</string>
<string>Singularity.sln</string>
<string>--config</string>
<string>RelWithDebInfo</string>
<string>--startup</string>
<string>singularity-bin</string>
</array>
<key>options</key>
<array>
@@ -3074,14 +3066,6 @@
<key>arguments</key>
<array>
<string>..\indra</string>
<string>&amp;&amp;</string>
<string>..\indra\tools\vstool\VSTool.exe</string>
<string>--solution</string>
<string>Singularity.sln</string>
<string>--config</string>
<string>Release</string>
<string>--startup</string>
<string>singularity-bin</string>
</array>
<key>options</key>
<array>
@@ -3129,14 +3113,6 @@
<key>arguments</key>
<array>
<string>..\indra</string>
<string>&amp;&amp;</string>
<string>..\indra\tools\vstool\VSTool.exe</string>
<string>--solution</string>
<string>Singularity.sln</string>
<string>--config</string>
<string>RelWithDebInfo</string>
<string>--startup</string>
<string>singularity-bin</string>
</array>
<key>options</key>
<array>
@@ -3177,14 +3153,6 @@
<key>arguments</key>
<array>
<string>..\indra</string>
<string>&amp;&amp;</string>
<string>..\indra\tools\vstool\VSTool.exe</string>
<string>--solution</string>
<string>Singularity.sln</string>
<string>--config</string>
<string>Release</string>
<string>--startup</string>
<string>singularity-bin</string>
</array>
<key>options</key>
<array>

View File

@@ -1571,20 +1571,6 @@ if (WINDOWS)
EMBED_MANIFEST(${VIEWER_BINARY_NAME} 1)
# sets the 'working directory' for debugging from visual studio.
if (NOT UNATTENDED)
add_custom_command(
TARGET ${VIEWER_BINARY_NAME} PRE_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(

View File

@@ -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
}
}

View File

@@ -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.

View File

@@ -1,99 +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>v4.0</TargetFrameworkVersion>
<OldToolsVersion>2.0</OldToolsVersion>
<TargetFrameworkProfile />
</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>

Binary file not shown.

View File

@@ -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

View File

@@ -1,3 +0,0 @@
<?xml version="1.0"?>
<configuration>
<startup><supportedRuntime version="v2.0.50727"/></startup></configuration>

View File

@@ -1,730 +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.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
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
{
//
// IOleMessageFilter functions.
// Handle incoming thread requests.
int IOleMessageFilter.HandleInComingCall(int dwCallType,
IntPtr hTaskCaller, int dwTickCount, IntPtr
lpInterfaceInfo)
{
//Return the flag SERVERCALL_ISHANDLED.
return 0;
}
// Thread call was rejected, so try again.
int IOleMessageFilter.RetryRejectedCall(IntPtr
hTaskCallee, int dwTickCount, int dwRejectType)
{
if (dwRejectType == 1 || dwRejectType == 2)
// flag = SERVERCALL_RETRYLATER or SERVERCALL_REJECTED.
{
// Retry the thread call immediately if return >=0 &
// <100.
return 99;
}
// Too busy; cancel call.
return -1;
}
int IOleMessageFilter.MessagePending(IntPtr hTaskCallee,
int dwTickCount, int dwPendingType)
{
//Return the flag PENDINGMSG_WAITDEFPROCESS.
return 2;
}
//
// 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);
}
// Implement the IOleMessageFilter interface.
[DllImport("Ole32.dll")]
private static extern int
CoRegisterMessageFilter(IOleMessageFilter newFilter, out
IOleMessageFilter oldFilter);
}
[ComImport, Guid("00000016-0000-0000-C000-000000000046"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal 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);
}
internal class ViaCOM
{
public static object GetProperty(object from_obj, string prop_name)
{
try
{
var 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};
var 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
{
var 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>
internal class VSToolMain
{
private static readonly bool ignore_case = true;
private static string solution_name;
private static bool use_new_vs;
private static readonly Hashtable projectDict = new Hashtable();
private static string startup_project;
private static string config;
private static object dte;
private static object solution;
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
private static int Main(string[] args)
{
var retVal = 0;
var need_save = false;
try
{
parse_command_line(args);
Console.WriteLine("Editing solution: {0}", solution_name);
var 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)
{
var project_name = (string) p.Key;
var 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)
{
var 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.
var 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])
{
var project_name = args[++i];
var 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 (var 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()
{
var 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");
var full_solution_name = 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...");
var version = GetSolutionVersion(full_solution_name);
Console.WriteLine(" Using version: {0}...", version);
var progid = GetVSProgID(version);
var objType = Type.GetTypeFromProgID(progid);
dte = 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)
{
var runningInstances = GetIDEInstances(true);
var enumerator = runningInstances.GetEnumerator();
while (enumerator.MoveNext())
{
try
{
var ide = enumerator.Value;
if (ide != null)
{
var sol = ViaCOM.GetProperty(ide, "Solution");
if (0 == string.Compare((string) ViaCOM.GetProperty(sol, "FullName"), solutionFile, ignore_case))
{
return ide;
}
}
}
catch
{
// ignored
}
}
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)
{
var runningIDEInstances = new Hashtable();
var runningObjects = GetRunningObjectTable();
var rotEnumerator = runningObjects.GetEnumerator();
while (rotEnumerator.MoveNext())
{
var candidateName = (string) rotEnumerator.Key;
if (!candidateName.StartsWith("!VisualStudio.DTE"))
continue;
var ide = rotEnumerator.Value;
if (ide == null)
continue;
if (openSolutionsOnly)
{
try
{
var sol = ViaCOM.GetProperty(ide, "Solution");
var solutionFile = (string) ViaCOM.GetProperty(sol, "FullName");
if (solutionFile != string.Empty)
{
runningIDEInstances[candidateName] = ide;
}
}
catch
{
// ignored
}
}
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()
{
var result = new Hashtable();
var numFetched = 0;
IRunningObjectTable runningObjectTable;
IEnumMoniker monikerEnumerator;
var 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;
StreamReader solutionStreamReader = null;
try
{
solutionStreamReader = new StreamReader(solutionFullFileName);
string firstLine;
do
{
firstLine = solutionStreamReader.ReadLine();
} while (firstLine == "");
var 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 = "VC140";
break;
default:
throw new ApplicationException("Unknown .sln version: " + format);
}
}
finally
{
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 "VC140":
progid = "VisualStudio.DTE.14.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)
{
var made_change = false;
Console.WriteLine("Looking for project {0}...", project_name);
try
{
var prjs = ViaCOM.GetProperty(sol, "Projects");
var count = ViaCOM.GetProperty(prjs, "Count");
for (var i = 1; i <= (int) count; ++i)
{
object[] prjItemArgs = {i};
var prj = ViaCOM.CallMethod(prjs, "Item", prjItemArgs);
var 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");
var 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.
var oCfgs = ViaCOM.GetProperty(ViaCOM.GetProperty(prj, "Object"), "Configurations");
// oCount will be assigned to the number of configs present in oCfgs.
var oCount = ViaCOM.GetProperty(oCfgs, "Count");
for (var cfgIndex = 1; cfgIndex <= (int) oCount; ++cfgIndex)
{
object[] itemArgs = {cfgIndex};
var oCfg = ViaCOM.CallMethod(oCfgs, "Item", itemArgs);
var oDebugSettings = ViaCOM.GetProperty(oCfg, "DebugSettings");
ViaCOM.SetProperty(oDebugSettings, "WorkingDirectory", 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)
{
var 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);
var prjs = ViaCOM.GetProperty(solution, "Projects");
var count = ViaCOM.GetProperty(prjs, "Count");
for (var i = 1; i <= (int) count; ++i)
{
object[] itemArgs = {i};
var prj = ViaCOM.CallMethod(prjs, "Item", itemArgs);
var prjName = ViaCOM.GetProperty(prj, "Name");
if (0 == string.Compare((string) prjName, startup_project, ignore_case))
{
var 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)
{
var result = false;
try
{
Console.WriteLine("Trying to set active config to \"{0}\"", config);
var solBuild = ViaCOM.GetProperty(solution, "SolutionBuild");
var solCfgs = ViaCOM.GetProperty(solBuild, "SolutionConfigurations");
object[] itemArgs = {config};
var 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;
}
#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
}
}