I am trying to control Unity Editor over Mono Debugger Wire Protocol. I want to obtain value of public static
property.
The following is my attempt:
using VirtualMachine = Mono.Debugger.Soft.VirtualMachine;
// vm points to the virtual machine of the Unity Editor
internal void SomeWhat(VirtualMachine vm) {
var hierarchyWindow = vm.GetTypes("UnityEditor.SceneHierarchyWindow", false)!.Single()!;
var prev = hierarchyWindow.GetMethod("SelectPrevious")!;
var latestWindow = hierarchyWindow
.GetProperty("lastInteractedHierarchyWindow")
.GetGetMethod(false)
.Evaluate(null, new Value[] { });
prev.Evaluate(latestWindow, new Value[] {});
}
However, it throws System.NotSupportedException
:
Unhandled exception. System.NotSupportedException: Specified method is not supported.
at Mono.Debugger.Soft.ILInterpreter.Evaluate(Value this_val, Value[] args) in $PROJECT/deps/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/ILInterpreter.cs:line 43
at Mono.Debugger.Soft.MethodMirror.Evaluate(Value this_val, Value[] args) in $PROJECT/deps/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/MethodMirror.cs:line 466
at Blah.SomeWhat(VirtualMachine vm) in $PROJECT/$PROJECT_NAME/SandBox/Lib.cs:line $LINE
where $PROJECT
, $PROJECT_NAME
, and $LINE
are variable.
I am confused because of its poor message, and a static field in Java's reflection do not require valid this_val
object. It turns out that this_val
cannot be null at present.
I am using Unity Editor 2019.4.31f1 and mono/debugger-libs on https://github.com/mono/debugger-libs/tree/6fcc6d78446b1fffac12f597099cc3d78dd74ca6, any ideas?
line 42 in ILInterpreter
does check for
if (method.IsStatic || ... || this_val == null || ...) throw new NotSupportedException ();
so it looks like this - or at least this way - is not made for statics at all.
Since in this specific case the property is actually just pointing to a static field
private static SceneHierarchyWindow s_LastInteractedHierarchy;
you could try to rather go through e.g.
var fieldInfoMirror = hierarchyWindow.GetField("s_LastInteractedHierarchy");
var latestWindow = hierarchyWindow.GetValue(fieldInfoMirror);
Alternatively you could probably also try and go through
var property = hierarchyWindow.GetProperty("lastInteractedHierarchyWindow");
var getterMethod = property.GetGetMethod();
var latestWindow = hierarchyWindow.InvokeMethod(null, getterMethod, new Value[0]);
It depends a lot on your actual use case and purpose of what you are trying to implement.
Usually in a case like yours where you already know exactly what type and members and signatures you are dealing with you would rather use InvokeMethod
instead of Evaluate
. The latter as to my understanding you would use more if you do not know the types, members and signatures beforehand.