|
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.Collections;
using System.Reflection;
namespace Bds.ObjectSpy
{
class ObjectSpyEvaluator
{
private static Regex _indexRegex = new Regex(@"\[\d+\]$"); // Matches e.g. "[123]" in the end of a string
private static Regex _argRexex = new Regex(@"\(\)$"); // Matches "()" in the end of a string
// This method is the entry point for the remote invocation
public static string Evaluate(IntPtr hWnd, string expression)
{
object obj = Control.FromHandle(hWnd);
if (expression != String.Empty)
{
string[] members = expression.Split('.');
foreach (string member in members)
{
try
{
obj = EvaluateMember(obj, member);
}
catch (Exception ex)
{
return "ERROR: Evaluating '" + member + "' failed: " + ex.Message;
}
}
}
return (obj != null ? obj.ToString() : "(null)");
}
private static object EvaluateMember(object obj, string memberName)
{
// Extract index, if any
Match indexMatch = _indexRegex.Match(memberName);
if (indexMatch.Success)
{
memberName = memberName.Substring(0, indexMatch.Index);
}
// Extract arguments, if any (note: we only handle "()" currently)
Match argMatch = _argRexex.Match(memberName);
if (argMatch.Success)
{
memberName = memberName.Substring(0, argMatch.Index);
}
// Invoke the member, i.e. field, property or method (without parameters and parenthesis)
obj = obj.GetType().InvokeMember(memberName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetProperty | BindingFlags.GetField | BindingFlags.InvokeMethod, null, obj, null);
// If we had an index, apply it now
if (indexMatch.Success)
{
string indexStr = indexMatch.Value.Substring(1, indexMatch.Length - 2);
int index = Int32.Parse(indexStr);
obj = GetObjectAtIndex(obj, index);
}
return obj;
}
private static object GetObjectAtIndex(object obj, int index)
{
if (obj is IList)
{
// Use the index directly
return ((IList)obj)[index];
}
else
{
// Assume obj implements IEnumerable, so we have a "pseudo" index
int i = 0;
foreach (object tmpObj in (IEnumerable)obj)
{
if (i == index)
{
return tmpObj;
}
i++;
}
throw new IndexOutOfRangeException("Index was " + index + " but object contained " + i + " items only");
}
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.