-
Notifications
You must be signed in to change notification settings - Fork 3
Description
I have a project where I am patching a bug in the WPF TreeView class by replacing one of its non-public methods with my own implementation. I am installing this "shim" with the following code:
public static void Install()
{
var realMethod = typeof(System.Windows.Controls.TreeView).GetMethod("HandleMouseButtonDown", BindingFlags.Instance | BindingFlags.NonPublic);
var replacementMethod = typeof(TreeViewShim).GetMethod(nameof(TreeView_HandleMouseButtonDown_shim), BindingFlags.Static | BindingFlags.NonPublic);
Redirection.Redirect(realMethod, replacementMethod);
}
This has been working fine on a variety of workstations for several months, but a co-worker's machine just the other day started throwing this exception:
if ((sizeOfPtr == sizeof(long) && difference < 13) || (sizeOfPtr == sizeof(int) && difference < 7))
throw new InvalidOperationException("Unable to redirect methods whose bodies are too close to one another.");
https://github.com/6A/Ryder/blob/master/Ryder.Lightweight/Ryder.Lightweight.cs#L61
To get things working for now, I am going to try a bit of an ugly work-around: I will make two identical copies of my shim method, and if one of them is too close, then in theory it should be impossible for the other one to also be too close (even if it is a trampoline). But, I'm trying to understand why:
a) this works fine on many other machines,
b) it just stopped working on this particular machine where it was working before, and
c) how methods in different classes can have entrypoints less than 13 bytes apart.
What is the correct fix in this situation??