不迎不送,来去自便,无茶无酒,谈笑随缘

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

CEMAPI实战攻略(四)——发送短消息

By 吴春雷

QQ:819543772

EMail:wuchunlei@163.com

四.发送短消息

发送短信是一个相对比较简单的过程,之所以拿出来一节来讨论,是因为我们不仅仅要讨论如何发送短信,还要讨论一个重要的进程,也就是tmail.exe进程。简单的讲,这个进程在后台控制着短信和邮件的接收和发送过程,在前台提供一个显示UI,供大家对短信进行操作。本文短信发送部分,就是利用tmail的短信发送功能实现的,不需要直接使用AT命令,这使得我们发送短信部分的代码变得异常简单。

1.       tmail.exe进程

a)         什么是tmail.exe进程

tmail.exe是微软处理消息的核心模块,处理包括短信,outlook等邮件消息,也包括第三方定制的MMS功能模块。为了方便第三方开发,微软定义了一些列的COM接口,可以将很多第三方开发的模块集成到tmail.exe中,从而扩展了tmail.exe的功能。WM5.0版本以前的彩信功能,多半是第三方开发者通过实现该COM接口提供的。最后我们提到的短信拦截的程序MapiRule,本质也是实现了IMapiClient接口的ProcessMessage方法,然后注册到系统中,tmail在启动时加载了这个COM组件,从而拥有了短信截获的功能。

b)         判断tmail.exe进程是否正在运行

                  很多时候,我们希望能够知道目前tmail.exe是否在运行,从而进行后续的操作。比如,发送短信的时候我们要确保tmail.exe已经在运行中,否则即便成功发送短信的程序,短信也只会被存在发件箱中,等待tmail.exe启动以后才能被发送出去。也有些时候,我们不希望tmail.exe运行,比如后面为tmail.exe注册MapiRule的时候。所以,要想继续本文的内容,首先需要解决tmail.exe进程的查找问题,也就是判断tmail.exe进程是否正在运行。这部分内容虽然不属于cemapi的范畴,但却是必须的基础。

判断tmail.exe进程是否在运行的思路是,首先对系统进程、堆、线程做一个快照,然后在快照中遍历所有进程,查找进程名为tmail.exe的进程,如果存在则认为tmail.exe进程正在运行,否则tmail.exe进程不再运行。我直接给出了这部分的源程序,并在上面增加了注释和说明,程序很简单,非常容易理解,您也可以直接复制过去使用,毕竟这不是本文关注的重点。

                             //参数为要查找的进程全名,如:tmail.exe

                             //返回0则进程不存在,否则返回进程Id

DWORD FindProcess(CString strProcessName)

{

DWORD dwPid = 0;          //用于保存tmail.exeId

HANDLE hHandle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);  //为当前系统进程建立快照

DWORD dwId = ::GetCurrentProcessId();     //当前进程的Id

      if (INVALUE_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;

}

 

程序很好理解,需要提醒一下读者的是,使用CreateToolhelp32Snapshot函数需要包含tlhelp32.h这个头文件,并且需要添加toolhelp.lib库文件。

c)         杀掉tmail.exe进程

获取到了进程ID以后,杀掉这个进程就变得很简单了。代码如下:

DWORD dwPid=FindProcess(_T(tmail.exe));

if(0!=dwPid){      //找到进程

HANDLE   hHandle=OpenProcess(PROCESS_TERMINATE,FALSE,dwPid);     //根据进程ID,获取tmail.exe的句柄

TerminateProcess(hHandle,0);        //关闭进程

}

d)         启动tmail.exe进程

直接调用CreateProcess函数就可以启动进程,代码如下:

//启动tmail.exe进程

CreateProcess(_T("tmail.exe"), _T("-RunInBKG"),NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);

命令行参数 RunInBKG,表示tmail.exe后直接在后台运行,避免短信邮件浏览器的出现。另外tmail.exe还有很多很有用的命令行参数,下面一一列举出来。(这部分内容虽然很多网站都有有介绍,但由于我是在无聊客的文章中最先看到的,所以这里就只注明引用自无聊客的《MAPI的一些问题解答(by 无聊客)》)

-service: 调用类型, MMSSMS

    -attach: 添加附件

    -subject: 添加subject

    -to: 添加目标地址

2.       利用tmail.exe发送一条短消息

前面部分已经详细的讨论过,如何在具体信箱中建立一条短信息了,其实建立了一条短信,就已经完成了短信发送功能中95%内容了。这里只介绍一个方法,IMessage::SubmitMessage方法,用于像tmail.exe提交已经创建的短信息,并由tmail完成短信发送过程。该方法的定义如下:

HRESULT IMesssage::SubmitMessage(ULONG ulFlag);

                    返回只用于判断方法是否正确执行。参数列表:

ulFlag:发送标志,可选择的值有FORCE_SUBMIT0,短信应用中一般选择0,我加上了FORCE_SUBMIT标志,感觉没什么不同,估计是要用在特定环境中的吧,具体作用大家补充吧。

        发送短信的代码与建立消息基本上完全一样,大家可以参考,唯一不同的是要将最后m_pMsg->SaveChange(0)这句替换成m_pMsg->SubjectMessage(0)即可。

4.       如何屏蔽掉短信发送后的系统提示信息

                每次消息发送后,系统都会出现一个提示框,提示消息已经发送。如果开发我们自己的应用程序,当然不希望每发一次消息,提示框就出来露次脸了,那么如果屏蔽掉短信发送后的系统提示信息呢?其实,这部分也跟cemapi没啥关系,但为了文章尽量系统,也把它写在这里吧。

      Windows(是PC端哈)菜单上选择“开始”——“程序”——“Microsoft Visual Studio 2005”——“Visual Studio Remote Tools”启动“远程注册表编辑器”,在HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Inbox目录下创建一个Settings目录,在其中添加一个名为SMSNoSentMsgDWORD类型的键,值为1。然后重启设备或者仿真器即可。

5.       源程序

还是等文章写完后,整理好再发吧。

 

posted on 2009-03-11 15:23  wude  阅读(259)  评论(0编辑  收藏  举报