看了些关于拦截短信的帖子,下面说说我的理解,不对之处请指正。
在下面链接的帖子中提到了有3种方法去注册Mailrule.dll。我觉得还是在程序中去注册比较好。我是这样做的:
第一步: 编辑好sdk中的Mailrule的程序,生成dll文件。其中我们关心的主要就是ProcessMessage函数中的内容
SizedSPropTagArray(1, sptaSubject) = { 1, PR_SUBJECT};
SizedSPropTagArray(1, sptaEmail) = { 1, PR_SENDER_EMAIL_ADDRESS};
hr = pMsg->GetProps((SPropTagArray *) &sptaSubject, MAPI_UNICODE, &cValues, &pspvSubject);
hr = pMsg->GetProps((SPropTagArray *) &sptaEmail, MAPI_UNICODE, &cValues, &pspvEmail);
其中pspvSubject得到短信正文,pspvEmail得到发件人电话号码。只要在此处进行判断处理就可以了。
if (wcsstr(pspvSubject->Value.lpszW, L"zzz") != NULL)
{
MessageBeep(MB_ICONASTERISK);
MessageBox(NULL, pspvSubject->Value.lpszW, pspvEmail->Value.lpszW, MB_OK);
// Delete the message and mark it as handled so it won't show up in Inbox
hr = DeleteMessage(pMsgStore, pMsg, cbMsg, lpMsg, cbDestFolder, lpDestFolder, pulEventType, pHandled);
}
从这里我们就可以看出来,它是收到含有"zzz"的短信就把它删除。我们可以进行自己的操作,比如把它保存下来等等。
第二步: 把生成的dll文件拷到手机上(考到手机上任何位置都可以,比如可以自己在设备里新建个文件夹mailrule,把它拷到这个文件里),。下面进入我们自己的程序。
第三步:当你在程序中想进行拦截时调用MailRule.dll的导出函数DllRegisterServer。如果tmail.exe进程已经启动了,我们必须关闭它,重新启动。所以要先查找tmail.exe进程是否已经存在,如果已存在则关闭,然后调用导出函数DllRegisterServer,调用成功后再启动tmail.exe进程。代码如下:
DWORD dwPid=FindProcess(_T("tmail.exe"));
if(0!=dwPid){ //找到进程
HANDLE hHandle=OpenProcess(PROCESS_TERMINATE,FALSE,dwPid); //根据进程ID,获取tmail.exe的句柄
TerminateProcess(hHandle,0); //关闭进程
}
FindProcess函数的实现如下:
DWORD FindProcess(TCHAR* strProcessName)
{
DWORD dwPid = 0; //用于保存tmail.exe的Id
HANDLE hHandle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS| TH32CS_SNAPNOHEAPS, 0); //为当前系统进程建立快照
DWORD dwId = ::GetCurrentProcessId(); //当前进程的Id
if (INVALID_HANDLE_VALUE !=hHandle) //如果快照建立成功
{
PROCESSENTRY32 stEntry;
stEntry.dwSize = sizeof(PROCESSENTRY32);
if(Process32First(hHandle, &stEntry)) //在快照中查找一个进程,stEntry返回进程相关属性和信息
{
do
{
if(wcsstr(stEntry.szExeFile,strProcessName)) //比较该进程名称是否与strProcessName相符
{
if(dwId != stEntry.th32ProcessID) //如果相等,且该进程的Id与当前进程不相等,则找到strProcessName对应的进程。
{
dwPid = stEntry.th32ProcessID;
break;
}
}
}while(Process32Next(hHandle, &stEntry)); //再快照中查找下一个进程。
}
CloseToolhelp32Snapshot(hHandle); //释放快照句柄。
}
return dwPid;
}
//调用导出函数进行注册,由于是dll文件,所以要先把函数导出,代码如下:
LPFDLLREGISTERSERVER lpfUnDllRegisterServer;
hInst = LoadLibrary(L"/mailrule/MapiRule.dll");
if ( NULL == hInst)
{
//异常处理
}
lpfUnDllRegisterServer =(LPFDLLREGISTERSERVER)GetProcAddress(hInst,_T("DllRegisterServer"));
//调用函数
HRESULT hr=lpfUnDllRegisterServer();
//以上都成功后打开tmail.exe进程,当然也可以不打开,如果有短信,或自己进入信箱就会自动打开
CreateProcess(_T("tmail.exe"), _T("-RunInBKG"),NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
这时候你发指定内容或指定号码的短信时就会被拦截
第四步:当你不想拦截的时候再调用dll中的DllUnregisterServer进行卸载,记住这时一定要关闭tmail.exe进程,否则即使你卸载了也会继续拦截,因为这时的tmail.exe进程依旧是加载拦截功能的进程。
LPFDLLREGISTERSERVER lpfUnDllRegisterServer;
lpfUnDllRegisterServer = (LPFDLLREGISTERSERVER)GetProcAddress(hInst,_T("DllUnregisterServer"));
//调用函数
HRESULT hr = lpfUnDllRegisterServer();
if(FAILED(hr))
{
//异常处理
}
DWORD dwPid=FindProcess(_T("tmail.exe"));
if(0!=dwPid){ //找到进程
HANDLE hHandle=OpenProcess(PROCESS_TERMINATE,FALSE,dwPid); //根据进程ID,获取tmail.exe的句柄
TerminateProcess(hHandle,0); //关闭进程
}
OK.这是我的理解,但不一定对,希望能对像我这样的初学者有用。