I need to take an existing winforms application and drop into an event tracing mode, with hopefully as little friction as possible.
我需要使用现有的winforms应用程序并进入事件跟踪模式,希望尽可能少的摩擦。
I would like to see every action the user takes as a simple stack trace-looking thing:
我希望看到用户采取的每个操作都是一个简单的堆栈跟踪外观:
MainForm.LaunchThing_Click
ThingWindow.NameInput_Focus
ThingWindow.NameInput_TextChanged
ThingWindow.AddressInput_Focus
ThingWindow.OKButton_Click
and so on.
等等。
- If this was a WPF application, I would do something like filter all events of type WClientInputMessage in ETW.
- I can't simply dump a stack trace, because that doesn't capture the user's prior actions.
- I could add logging to every single event [with the recommended practices from this discussion], but this is an extant application with far too many events. Plus, I'm lazy. Gotta be a better way.
- I can't attach a debugger, I want to get this information automatically attached to bug reports from testing users in the field because [it turns out...] nobody can accurately remember exactly what the sequence of things they clicked on was.
如果这是一个WPF应用程序,我会做一些事情,比如在ETW中过滤WClientInputMessage类型的所有事件。
我不能简单地转储堆栈跟踪,因为这不会捕获用户的先前操作。
我可以为每个事件添加日志记录[使用本讨论中推荐的做法],但这是一个现存的应用程序,其中包含太多事件。另外,我很懒。必须是一个更好的方式。
我无法附加调试器,我希望自动将这些信息附加到测试用户的bug报告中,因为[事实证明......]没有人能够准确地记住他们点击的内容序列是什么。
So I'm wondering if anyone has any good tricks, using subclassing or reflection perhaps, to latch on to the UI events.
所以我想知道是否有人有任何好的技巧,或许使用子类或反射来锁定UI事件。
Performance is not really a concern. And if I can get a hook into every event, that's good enough; I can filter them down to the relevant set fairly easily.
性能并不是真正的问题。如果我能在每个事件中得到一个钩子,那就足够了;我可以很容易地将它们过滤到相关的集合。
2 个解决方案
#1
How about an observer pattern? Create an EventLogger class with a bunch of overloaded Log methods (one for each event method signature) that do the logging. Instantiate it on application start and subscribe it to each of the UI events.
观察者模式怎么样?创建一个EventLogger类,其中包含一组执行日志记录的重载Log方法(每个事件方法签名一个)。在应用程序启动时实例化它并将其订阅到每个UI事件。
It should even be possible to do the subscribing automatically with reflection - though I would think it is more effort to set that up than to do it manually for any reasonably sized application. Also you would still have to ensure that your EventLogger class has a Log method for every possible event handler method signature.
甚至可以通过反射自动进行订阅 - 尽管我认为设置它比为任何合理大小的应用程序手动执行更加努力。此外,您仍然必须确保您的EventLogger类具有每个可能的事件处理程序方法签名的Log方法。
#2
How many different control types do you have? If you only have a handful of control types that you are looking to trace with, it may be worthwhile to subclass them and do a find and replace on your project to change them to your subclass. This should only take a minute or two.
你有多少种不同的控制类型?如果您只想要跟踪一些控件类型,那么将它们子类化并在项目上执行查找和替换以将它们更改为子类可能是值得的。这应该只需要一两分钟。
In your subclassed controls, you could override a small section of the methods, adding tracing before calling the base method.
在子类控件中,您可以覆盖方法的一小部分,在调用基本方法之前添加跟踪。
#1
How about an observer pattern? Create an EventLogger class with a bunch of overloaded Log methods (one for each event method signature) that do the logging. Instantiate it on application start and subscribe it to each of the UI events.
观察者模式怎么样?创建一个EventLogger类,其中包含一组执行日志记录的重载Log方法(每个事件方法签名一个)。在应用程序启动时实例化它并将其订阅到每个UI事件。
It should even be possible to do the subscribing automatically with reflection - though I would think it is more effort to set that up than to do it manually for any reasonably sized application. Also you would still have to ensure that your EventLogger class has a Log method for every possible event handler method signature.
甚至可以通过反射自动进行订阅 - 尽管我认为设置它比为任何合理大小的应用程序手动执行更加努力。此外,您仍然必须确保您的EventLogger类具有每个可能的事件处理程序方法签名的Log方法。
#2
How many different control types do you have? If you only have a handful of control types that you are looking to trace with, it may be worthwhile to subclass them and do a find and replace on your project to change them to your subclass. This should only take a minute or two.
你有多少种不同的控制类型?如果您只想要跟踪一些控件类型,那么将它们子类化并在项目上执行查找和替换以将它们更改为子类可能是值得的。这应该只需要一两分钟。
In your subclassed controls, you could override a small section of the methods, adding tracing before calling the base method.
在子类控件中,您可以覆盖方法的一小部分,在调用基本方法之前添加跟踪。