在給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;
}
}
問題解決。
結論:使用Window API時,如果需要傳入Delegete作為參數,要自己保證Delegete的生命週期足夠長,這種情況下最好聲明為類成員,因為如果你聲明為局部變數,所在範圍執行結束,Delegete會被回收。