我想创建一个应用程序来截取我的应用程序的所有形式的所有UI事件,并将它们写入日志.这些数据可以用于查看哪些控件使用最多,顺序是什么等.问题是我希望这是自动发生的,而不需要修改现有的类.
我制作了一个原型,将一个方法附加到表单中所有控件的click事件,但是如何对所有表单执行此操作?在操作事件时,Reflection需要一个目标对象,但只能轻松访问启动表单.
有没有办法挂钩对象的构造函数?然后我可以在新表格的所有事件中"注入"我的方法.或许还有另一种方法可以做到这一点.
提前致谢!
我们考虑一下我有以下代码
/*...*/
var _fun = fun;
fun = function() {
/*...*/
_fun.apply(this, arguments);
}
Run Code Online (Sandbox Code Playgroud)
我刚刚丢失了.length
数据_fun
因为我试图用一些拦截逻辑包装它.
以下不起作用
var f = function(a,b) { };
console.log(f.length); // 2
f.length = 4;
console.log(f.length); // 2
Run Code Online (Sandbox Code Playgroud)
该注释的ES5.1规范规定的是.length
定义如下
Object.defineProperty(fun, "length", {
value: /*...*/,
writable: false,
configurable: false,
enumerable: false
}
Run Code Online (Sandbox Code Playgroud)
鉴于内部逻辑fun
需要.length
准确,如何在不破坏.length
数据的情况下拦截和覆盖此功能?
我有一种感觉,我将需要使用eval
和狡猾Function.prototype.toString
的构造一个具有相同数量的参数的新字符串.我想避免这种情况.
伙计们
我正在尝试将LogCallHandler用于拦截,如下所示:
<interception>
<policy name="policyLogCallHandler">
<matchingRule name="LogsMachingRule" type="NamespaceMatchingRule">
<constructor>
<param name="namespaceName" value="NetTcpContracts" />
</constructor>
</matchingRule>
<callHandler type="Microsoft.Practices.EnterpriseLibrary.Logging.PolicyInjection.LogCallHandler, Microsoft.Practices.EnterpriseLibrary.PolicyInjection, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" name="callHandlerLog">
<constructor>
<param name="eventId" value="9002"/>
<param name="logBeforeCall" value="true"/>
<param name="logAfterCall" value="true"/>
<param name="beforeMessage" value="--- begin"/>
<param name="afterMessage" value="--- end"/>
<param name="includeParameters" value="true"/>
<param name="includeCallStack" value="true"/>
<param name="includeCallTime" value="true"/>
<param name="priority" value="1"/>
<param name="order" value="1"/>
</constructor>
</callHandler>
</policy>
</interception>
Run Code Online (Sandbox Code Playgroud)
此配置引发异常:"尚未为Logger静态类设置LogWriter.设置它调用Logger.SetLogWriter方法."
我使用运行时配置找到了解决此问题的方法:
IConfigurationSource configurationSource = ConfigurationSourceFactory.Create();
LogWriterFactory logWriterFactory = new LogWriterFactory(configurationSource);
Logger.SetLogWriter(logWriterFactory.Create());
LogEntry entry = new LogEntry();
entry.Message = "I am …
Run Code Online (Sandbox Code Playgroud) 对于我的log4net解决方案,我有一个使用CallerInfo属性的API包装器,例如
public void Write(string message,
[CallerMemberName] string memberName = "",
[CallerFilePath] string filePath = "",
[CallerLineNumber] int lineNumber = 0)
Run Code Online (Sandbox Code Playgroud)
但是,我也使用Unity Interception,以便我可以执行前/后响应的跟踪日志记录,例如在Invoke方法中使用如下所示的ICallHandler.
public class TraceCallHandler : ICallHandler
{
...
public IMethodReturn Invoke(IMethodInvocation input,
GetNextHandlerDelegate getNext)
{
//---- Trace method inputs
this.LogInfoBeforeInvoke(input);
//---- invoking the target method
InvokeHandlerDelegate next = getNext();
IMethodReturn methodReturn = next(input, getNext);
//---- invoking the target method
this.LogInfoAfterInvoke(methodReturn.ReturnValue);
}
}
Run Code Online (Sandbox Code Playgroud)
注意:上面的代码绝不是完整/正确的...但只是想告诉你我为Unity Interception做了些什么.
我的问题/挑战是这样的:当我最终调用log.Write(...)时,我想要目标的调用者信息,而不是我的TraceCallHandler信息.
例如,对于方法名称,我可以这样做:
string methodName = input.MethodBase.Name;
Run Code Online (Sandbox Code Playgroud)
如何获取来电者的文件路径和来电者的线路号码?甚至可以通过反思来做吗?
谢谢!
虽然我可以并且确实将Burp
代理Firefox
用于远程 Web 服务器,没有任何问题,但我似乎无法让它在本地网络上与我在本地服务器上托管的测试 Web 应用程序一起工作。
Burp
无法看到来自这些请求的流量。我缺少什么?这里相关问题中建议的一些解决方案根本没有帮助我。
我正在使用LD_PRELOAD来捕获linux中的write()系统调用.我成功地能够为写入系统调用执行此操作并使其工作.
但是,当我调用printf()时,它不起作用.如果我们使用strace观察printf堆栈跟踪,我发现,最后printf调用write()系统调用写入控制台,但那时我的write()系统调用在实际调用write()系统调用之前没有被调用.
任何人都知道为什么会这样?
当JUnit中的断言失败时,我想做一些"自己的东西".我想要这个:
public class MyAssert extends org.junit.Assert {
// @Override
static public void fail(String message) {
System.err.println("I am intercepting here!");
org.junit.Assert.fail(message);
}
}
Run Code Online (Sandbox Code Playgroud)
当然,这不起作用,因为你不能覆盖静态方法.但如果它会这样,这将是很好的,因为每个断言函数都会assertTrue()
调用该fail()
方法.因此,我可以轻松拦截每一个断言.
在没有实现所有不同风格的情况下,有没有办法做我想做的事情assert...
?
有没有一种简单的方法来拦截java中的方法.我需要为所需的方法添加一个注释,以便在通过该方法之前调用一段逻辑.
public void verifyActivity() {
// Asset if you are on a wrong page
}
@VerifyActivity
public void testLogin() {
// Login for my automate test
}
@VerifyActivity
public void testSomethingElse() {
// Test some other UI Automation stuff
}
Run Code Online (Sandbox Code Playgroud)
编辑:
Android应用程序推荐的guice库不包含AOP.是否可以在不添加任何库的情况下使用反射实现此目的?
我像这样注册依赖项:
this.Container.RegisterType<IFoo, Foo>(
new ContainerControlledLifetimeManager(),
new InterceptionBehavior<PolicyInjectionBehavior>(), new Interceptor<InterfaceInterceptor>());
Run Code Online (Sandbox Code Playgroud)
这很好用。但是,当我解决Foo
而不是IFoo
出现错误时:
ArgumentException - 传递的类型必须是接口。
看来 Unity 仍在尝试应用InterfaceInterceptor
此依赖项。但为什么?
我正在使用 Castle DynamicProxy 和 Autofac。我有一个为其创建代理的对象,并且有两个作用于代理的拦截器,一个用于记录异常,第二个用于更改方法的返回值。注册代码如下所示:
var builder = new ContainerBuilder();
builder.Register(c => c.Resolve<ProxyGenerator>()
.CreateClassProxy<Foo>(
c.Resolve<ResultProcessorInterceptor>(),
c.Resolve<ExceptionLoggingInterceptor>()))
.As<Foo>();
Run Code Online (Sandbox Code Playgroud)
通过按此顺序提供参数,我发现我得到了我想要的结果,即记录了异常并处理了结果。如果我颠倒参数的顺序,则不会发生日志记录。
那么我的问题是:这样注册后,拦截器是否能保证每次都按照相同的顺序执行?或者有没有更好的方法来确保订单每次都是我想要的?
FWIW,我查看了 IInterceptorSelector 接口。也许我遗漏了一些东西——这并非不可能——但看起来这与本例无关。但如果我错了,我很乐意得到纠正。
如果需要,我可以提供更长的代码示例。
音乐学家
interception ×10
c# ×3
.net ×2
android ×1
annotations ×1
aop ×1
autofac ×1
burp ×1
call ×1
events ×1
firefox ×1
function ×1
interceptor ×1
java ×1
javascript ×1
junit ×1
linux ×1
log4net ×1
logging ×1
overwrite ×1
proxy ×1
reflection ×1
system ×1
winforms ×1