DEV-16502 - Cleaned up error messages, better error handling in vstool/main.cs

Reviewed by Richard
master
Mark Palange 2008-06-25 17:56:53 +00:00
parent 580f9088b4
commit 6dd125d375
2 changed files with 188 additions and 61 deletions

Binary file not shown.

View File

@ -5,6 +5,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
@ -12,6 +13,95 @@ 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)
@ -111,86 +201,62 @@ namespace VSTool
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
static int Main(string[] args)
{
int retVal = 0;
bool need_save = false;
try
{
parse_command_line(args);
Console.WriteLine("Opening solution: {0}", solution_name);
Console.WriteLine("Editing solution: {0}", solution_name);
bool found_open_solution = GetDTEAndSolution();
// Walk through all of the projects in the solution
// and list the type of each project.
foreach (DictionaryEntry p in projectDict)
if (dte == null || solution == null)
{
string project_name = (string)p.Key;
string working_dir = (string)p.Value;
if (SetProjectWorkingDir(solution, project_name, working_dir))
{
need_save = true;
}
retVal = 1;
}
if (config != null)
else
{
try
{
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);
need_save = true;
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
MessageFilter.Register();
if (startup_project != null)
{
try
// Walk through all of the projects in the solution
// and list the type of each project.
foreach (DictionaryEntry p in projectDict)
{
// You need the 'unique name of the project to set StartupProjects.
// find the project by generic name.
object prjs = ViaCOM.GetProperty(solution, "Projects");
object count = ViaCOM.GetProperty(prjs, "Count");
for (int i = 1; i <= (int)count; ++i)
string project_name = (string)p.Key;
string working_dir = (string)p.Value;
if (SetProjectWorkingDir(solution, project_name, working_dir))
{
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"));
need_save = true;
break;
}
need_save = true;
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
if (need_save)
{
if (found_open_solution == false)
if (config != null)
{
ViaCOM.CallMethod(solution, "Close", 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
{
@ -205,8 +271,10 @@ namespace VSTool
Marshal.ReleaseComObject(dte);
dte = null;
}
MessageFilter.Revoke();
}
Console.WriteLine("Finished!");
return retVal;
}
public static bool parse_command_line(string[] args)
@ -305,17 +373,16 @@ namespace VSTool
{
try
{
Console.WriteLine(" Didn't find open solution, now opening new VisualStudio instance...");
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(" Opening VS version: {0}...", version);
Console.WriteLine(" Using version: {0}...", version);
string progid = GetVSProgID(version);
Type objType = Type.GetTypeFromProgID(progid);
dte = System.Activator.CreateInstance(objType);
Console.WriteLine(" Opening solution...");
Console.WriteLine(" Reading solution: \"{0}\"", full_solution_name);
solution = ViaCOM.GetProperty(dte, "Solution");
object[] openArgs = { full_solution_name };
@ -551,7 +618,7 @@ namespace VSTool
// 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,
// with out the type casting. Its tedious code, but it seems to work.
// 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");
@ -575,10 +642,70 @@ namespace VSTool
catch( Exception e )
{
Console.WriteLine(e.Message);
Console.WriteLine("Failed settings working dir for project, {0}.", project_name);
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;
}
}
}