处理C# hook程序的SEHException异常
在给Word程序添加hook程序时出现了'System.Runtime.InteropServices.SEHException' 异常,异常详细信息为
'System.Runtime.InteropServices.SEHException' occurred in Unknown Module.
Additional information: External component has thrown an exception.
An exception 'System.NullReferenceException' has occured in...
追踪了很久也找不到问题所在,只是知道异常出现在hook程序中,并切程序一开始并不出现异常,过一段时间之后才会出现异常。
下面是原来的代码:
public void SetUpHookProgram()
{
HookProc windowCallBack = new HookProc(KeyboardProc);
m_intHookPtr = Win32API.SetWindowsHookEx(HookType.WH_KEYBOARD ,windowCallBack,IntPtr.Zero, AppDomain.GetCurrentThreadId());
//If SetWindowsHookEx fails.
if(m_intHookPtr == 0 )
{
Debug.WriteLine("SetWindowsHookEx Failed");
return;
}
}
最后怀疑是垃圾回收器的问题,怀疑他把windowCallback给回收了:
更改代码,把windowCallback作为类成员,在构造函数中初始化
/// <summary>
/// setup hook program to deal with word document
/// </summary>
public void SetUpHookProgram()
{
//m_objHookProc是类的成员,在构造函数中初始化
m_intHookPtr = Win32API.SetWindowsHookEx(HookType.WH_KEYBOARD ,m_objHookProc,IntPtr.Zero, AppDomain.GetCurrentThreadId());
//If SetWindowsHookEx fails.
if(m_intHookPtr == 0 )
{
Debug.WriteLine("SetWindowsHookEx Failed");
return;
}
}
'System.Runtime.InteropServices.SEHException' occurred in Unknown Module.
Additional information: External component has thrown an exception.
An exception 'System.NullReferenceException' has occured in...
追踪了很久也找不到问题所在,只是知道异常出现在hook程序中,并切程序一开始并不出现异常,过一段时间之后才会出现异常。
下面是原来的代码:
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
最后怀疑是垃圾回收器的问题,怀疑他把windowCallback给回收了:
更改代码,把windowCallback作为类成员,在构造函数中初始化
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
问题解决。
结论:使用Window API时,如果需要传入Delegete作为参数,要自己保证Delegete的生命周期足够长,这种情况下最好声明为类成员,因为如果你声明为局部变量,所在作用域执行结束,Delegete会被回收。