C#中如果要调用API函数,首先要声明使用下面这个名字空间,否则无法调用API函数:
using System.Runtime.InteropServices;
其次,声明导入库和导入函数,在这里用一个写INI文件的API函数举例如下:
[DllImport("kernel32")]
private static extern long WritePrivateProfileString(string section,
string key,string val,string filePath);
要调用SetUnhandledExceptionFilter,问题还不仅仅是调API那么简单,还牵涉到怎么把一个C#函数做为函数指针传递给API函数,C#的标准方法是使用代理来作为函数指针,例如代理可以这样声明:
public delegate bool EnumThreadWindowsCallback(IntPtr hWnd, IntPtr lParam) ;
我通过做实验写了一个C#小程序,粗略的实现了一个全局异常截获程序,程序还有一些问题,不够完善,程序中是用rtlmovememory函数来人为的制造了一个全局异常,最后一个参数选200就是为了输入一个非法参数,在我的电脑上正好可以引发异常,如果在您的电脑上无法引发异常,可以调整这个参数试试。
全部代码如下:
form1.cs
---------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace SetUnhandledExceptionFilter
{
public partial class Form1 : Form
{
public delegate Int32 CallBack(ref long a);
CallBack mycall;
[DllImport("kernel32")]
private static extern void RtlMoveMemory(ref byte dst,
ref byte src, Int32 len);
[DllImport("kernel32")]
private static extern Int32 SetUnhandledExceptionFilter(CallBack cb);
public static Int32 newexceptionfilter(ref long a)
{
MessageBox.Show("截获了全局异常!");
return 0;
}
public Form1()
{
InitializeComponent();
mycall = new CallBack(newexceptionfilter);
SetUnhandledExceptionFilter(mycall);
}
private void button1_Click(object sender, EventArgs e)
{
byte a=1, b=2;
MessageBox.Show("a=" + a.ToString());
RtlMoveMemory(ref a, ref b, 200);
MessageBox.Show ("a=" + a.ToString());
}
}
}
---------------------------------------------------------------------
联系客服