Ensure clean compile when 3p-Tracy not installed
parent
07d2b1b6fd
commit
bd20cfad1d
|
|
@ -14,6 +14,15 @@
|
|||
#include "common/TracySystem.cpp"
|
||||
|
||||
#ifdef TRACY_ENABLE
|
||||
// <FS:Beq> are we actively profiling?
|
||||
// At some point this should move to fsprofiler.cpp to correspond with the headerfile
|
||||
#ifdef TRACY_ENABLE
|
||||
namespace FSProfiler
|
||||
{
|
||||
bool active{false};
|
||||
}
|
||||
#endif
|
||||
// </FS:Beq>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(push, 0)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
#pragma once
|
||||
#ifndef FS_PROFILER_H_INCLUDED
|
||||
#define FS_PROFILER_H_INCLUDED
|
||||
|
||||
// define a simple set of empty macros that allow us to build without the Tracy profiler installed in 3p
|
||||
// this is similar to the profiler abstraction used by LL but as they have no plans to release that any time soon we'll replace it
|
||||
// Just a minimal set at the moment will add locks/gpu/memory and other stuff later
|
||||
|
||||
#ifdef TRACY_ENABLE
|
||||
#include "Tracy.hpp"
|
||||
namespace FSProfiler
|
||||
{
|
||||
extern bool active;
|
||||
}
|
||||
|
||||
#define FSZone ZoneNamed( ___tracy_scoped_zone, FSProfiler::active)
|
||||
#define FSZoneN( name ) ZoneNamedN( ___tracy_scoped_zone, name, FSProfiler::active)
|
||||
#define FSZoneC(color) ZoneNamedC( ___tracy_scoped_zone, color, FSProfiler::active)
|
||||
#define FSZoneNC(name, color) ZoneNamedNC( ___tracy_scoped_zone, name, color, FSProfiler::active)
|
||||
#define FSPlot( name, value ) TracyPlot( name, value)
|
||||
#define FSFrameMark FrameMark
|
||||
|
||||
#else
|
||||
|
||||
#define FSZone
|
||||
#define FSZoneN( name )
|
||||
#define FSZoneC(color)
|
||||
#define FSZoneNC(name, color)
|
||||
#define FSPlot( name, value )
|
||||
#define FSFrameMark
|
||||
#endif // TRACY_ENABLE
|
||||
#endif
|
||||
|
|
@ -54,15 +54,7 @@
|
|||
#else
|
||||
#error "architecture not supported"
|
||||
#endif
|
||||
// <FS:Beq> are we actively profiling?
|
||||
#ifdef TRACY_ENABLE
|
||||
namespace LLTrace
|
||||
{
|
||||
bool active{false};
|
||||
}
|
||||
// </FS:Beq>
|
||||
|
||||
#endif
|
||||
namespace LLTrace
|
||||
{
|
||||
|
||||
|
|
|
|||
|
|
@ -41,21 +41,15 @@
|
|||
// <FS:Beq> Add Tracy profiler support
|
||||
// #define LL_RECORD_BLOCK_TIME(timer_stat) \
|
||||
// const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(timer_stat)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__);
|
||||
#include "fsprofiler.h"
|
||||
#ifdef TRACY_ENABLE
|
||||
|
||||
#include "Tracy.hpp"
|
||||
|
||||
namespace LLTrace
|
||||
{
|
||||
extern bool active;
|
||||
}
|
||||
// #undef TRACY_NO_FASTTIMERS // Uncomment if you want FASTTIMERS as well.
|
||||
#ifdef TRACY_NO_FASTTIMERS
|
||||
#define LL_RECORD_BLOCK_TIME(timer_stat) \
|
||||
ZoneNamedN( ___tracy_scoped_zone, #timer_stat , LLTrace::active);
|
||||
FSZoneN( #timer_stat );
|
||||
#else // TRACY_NO_FASTTIMERS
|
||||
#define LL_RECORD_BLOCK_TIME(timer_stat) \
|
||||
ZoneNamedN( ___tracy_scoped_zone, #timer_stat , LLTrace::active); \
|
||||
FSZoneN( #timer_stat ); \
|
||||
const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(timer_stat)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__);
|
||||
#endif // TRACY_NO_FASTTIMERS
|
||||
#else // TRACY_ENABLE
|
||||
|
|
|
|||
|
|
@ -33,8 +33,7 @@
|
|||
#include "llfilesystem.h"
|
||||
#include "llfasttimer.h"
|
||||
#include "lldiskcache.h"
|
||||
|
||||
#define FSZoneScoped ZoneNamedC( ___tracy_scoped_zone, tracy::Color::Gold, LLTrace::active);
|
||||
#include "fsprofiler.h"
|
||||
|
||||
const S32 LLFileSystem::READ = 0x00000001;
|
||||
const S32 LLFileSystem::WRITE = 0x00000002;
|
||||
|
|
@ -59,7 +58,7 @@ LLFileSystem::~LLFileSystem()
|
|||
// static
|
||||
bool LLFileSystem::getExists(const LLUUID& file_id, const LLAssetType::EType file_type)
|
||||
{
|
||||
FSZoneScoped;
|
||||
FSZoneC(tracy::Color::Gold);
|
||||
std::string id_str;
|
||||
file_id.toString(id_str);
|
||||
const std::string extra_info = "";
|
||||
|
|
@ -88,7 +87,7 @@ bool LLFileSystem::getExists(const LLUUID& file_id, const LLAssetType::EType fil
|
|||
bool LLFileSystem::removeFile(const LLUUID& file_id, const LLAssetType::EType file_type, int suppress_error /*= 0*/)
|
||||
// </FS:Ansariel>
|
||||
{
|
||||
FSZoneScoped;
|
||||
FSZoneC(tracy::Color::Gold);
|
||||
std::string id_str;
|
||||
file_id.toString(id_str);
|
||||
const std::string extra_info = "";
|
||||
|
|
@ -106,7 +105,8 @@ bool LLFileSystem::removeFile(const LLUUID& file_id, const LLAssetType::EType fi
|
|||
bool LLFileSystem::renameFile(const LLUUID& old_file_id, const LLAssetType::EType old_file_type,
|
||||
const LLUUID& new_file_id, const LLAssetType::EType new_file_type)
|
||||
{
|
||||
FSZoneScoped;
|
||||
FSZoneC(tracy::Color::Gold);
|
||||
;
|
||||
std::string old_id_str;
|
||||
old_file_id.toString(old_id_str);
|
||||
const std::string extra_info = "";
|
||||
|
|
@ -137,7 +137,8 @@ bool LLFileSystem::renameFile(const LLUUID& old_file_id, const LLAssetType::ETyp
|
|||
// static
|
||||
S32 LLFileSystem::getFileSize(const LLUUID& file_id, const LLAssetType::EType file_type)
|
||||
{
|
||||
FSZoneScoped;
|
||||
FSZoneC(tracy::Color::Gold);
|
||||
;
|
||||
std::string id_str;
|
||||
file_id.toString(id_str);
|
||||
const std::string extra_info = "";
|
||||
|
|
@ -163,7 +164,8 @@ S32 LLFileSystem::getFileSize(const LLUUID& file_id, const LLAssetType::EType fi
|
|||
|
||||
BOOL LLFileSystem::read(U8* buffer, S32 bytes)
|
||||
{
|
||||
FSZoneScoped;
|
||||
FSZoneC(tracy::Color::Gold);
|
||||
;
|
||||
BOOL success = TRUE;
|
||||
|
||||
std::string id;
|
||||
|
|
@ -222,19 +224,22 @@ BOOL LLFileSystem::read(U8* buffer, S32 bytes)
|
|||
|
||||
S32 LLFileSystem::getLastBytesRead()
|
||||
{
|
||||
FSZoneScoped;
|
||||
FSZoneC(tracy::Color::Gold);
|
||||
;
|
||||
return mBytesRead;
|
||||
}
|
||||
|
||||
BOOL LLFileSystem::eof()
|
||||
{
|
||||
FSZoneScoped;
|
||||
FSZoneC(tracy::Color::Gold);
|
||||
;
|
||||
return mPosition >= getSize();
|
||||
}
|
||||
|
||||
BOOL LLFileSystem::write(const U8* buffer, S32 bytes)
|
||||
{
|
||||
FSZoneScoped;
|
||||
FSZoneC(tracy::Color::Gold);
|
||||
;
|
||||
std::string id_str;
|
||||
mFileID.toString(id_str);
|
||||
const std::string extra_info = "";
|
||||
|
|
@ -344,7 +349,8 @@ BOOL LLFileSystem::write(const U8* buffer, S32 bytes)
|
|||
|
||||
BOOL LLFileSystem::seek(S32 offset, S32 origin)
|
||||
{
|
||||
FSZoneScoped;
|
||||
FSZoneC(tracy::Color::Gold);
|
||||
;
|
||||
if (-1 == origin)
|
||||
{
|
||||
origin = mPosition;
|
||||
|
|
@ -375,26 +381,30 @@ BOOL LLFileSystem::seek(S32 offset, S32 origin)
|
|||
|
||||
S32 LLFileSystem::tell() const
|
||||
{
|
||||
FSZoneScoped;
|
||||
FSZoneC(tracy::Color::Gold);
|
||||
;
|
||||
return mPosition;
|
||||
}
|
||||
|
||||
S32 LLFileSystem::getSize()
|
||||
{
|
||||
FSZoneScoped;
|
||||
FSZoneC(tracy::Color::Gold);
|
||||
;
|
||||
return LLFileSystem::getFileSize(mFileID, mFileType);
|
||||
}
|
||||
|
||||
S32 LLFileSystem::getMaxSize()
|
||||
{
|
||||
FSZoneScoped;
|
||||
FSZoneC(tracy::Color::Gold);
|
||||
;
|
||||
// offer up a huge size since we don't care what the max is
|
||||
return INT_MAX;
|
||||
}
|
||||
|
||||
BOOL LLFileSystem::rename(const LLUUID& new_id, const LLAssetType::EType new_type)
|
||||
{
|
||||
FSZoneScoped;
|
||||
FSZoneC(tracy::Color::Gold);
|
||||
;
|
||||
LLFileSystem::renameFile(mFileID, mFileType, new_id, new_type);
|
||||
|
||||
mFileID = new_id;
|
||||
|
|
@ -405,7 +415,8 @@ BOOL LLFileSystem::rename(const LLUUID& new_id, const LLAssetType::EType new_typ
|
|||
|
||||
BOOL LLFileSystem::remove()
|
||||
{
|
||||
FSZoneScoped;
|
||||
FSZoneC(tracy::Color::Gold);
|
||||
;
|
||||
LLFileSystem::removeFile(mFileID, mFileType);
|
||||
|
||||
return TRUE;
|
||||
|
|
|
|||
|
|
@ -282,6 +282,8 @@
|
|||
#include "fsradar.h"
|
||||
#include "fsassetblacklist.h"
|
||||
|
||||
#include "fsprofiler.h" // <FS:Beq> Tracy profiler support
|
||||
|
||||
#if (LL_LINUX || LL_SOLARIS) && LL_GTK
|
||||
#include "glib.h"
|
||||
#endif // (LL_LINUX || LL_SOLARIS) && LL_GTK
|
||||
|
|
@ -1653,17 +1655,19 @@ bool LLAppViewer::doFrame()
|
|||
LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop"));
|
||||
LLSD newFrame;
|
||||
// <FS:Beq> Tracy enabling
|
||||
#ifdef TRACY_ENABLE
|
||||
static bool one_time{false};
|
||||
static LLCachedControl<bool> tracy_enable_when_connected(gSavedSettings, "FSTracyEnableWhenConnected");
|
||||
if( !one_time && (gFrameCount % 10 == 0) )
|
||||
{
|
||||
if(!LLTrace::active && tracy_enable_when_connected && TracyIsConnected)
|
||||
if(!FSProfiler::active && tracy_enable_when_connected && TracyIsConnected)
|
||||
{
|
||||
LLTrace::active = true;
|
||||
FSProfiler::active = true;
|
||||
one_time=true; // prevent reset race if we disable manually.
|
||||
LL_INFOS() << "Tracy profiler or collector connected" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// </FS:Beq>
|
||||
// <FS:Ansariel> MaxFPS Viewer-Chui merge error
|
||||
LLTimer periodicRenderingTimer;
|
||||
|
|
@ -1965,7 +1969,7 @@ bool LLAppViewer::doFrame()
|
|||
|
||||
LL_INFOS() << "Exiting main_loop" << LL_ENDL;
|
||||
}
|
||||
FrameMark; // <FS:Beq> Tracy support delineate Frame
|
||||
FSFrameMark; // <FS:Beq> Tracy support delineate Frame
|
||||
return ! LLApp::isRunning();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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.
|
||||
|
||||
|
||||
|
|
@ -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>
|
||||
Binary file not shown.
|
|
@ -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
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<configuration>
|
||||
<startup><supportedRuntime version="v2.0.50727"/></startup></configuration>
|
||||
|
|
@ -1,733 +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 = "VC150";
|
||||
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;
|
||||
|
||||
case "VC150":
|
||||
progid = "VisualStudio.DTE.15.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue