zoukankan      html  css  js  c++  java
  • Win Mobile利用mapirule接收短信

    http://hi.baidu.com/zgcat/blog/item/2032cc82f0060a9af603a653.html

    一。在能够使用 MAPI 规则客户端之前,我们需要将其注册为 COM 对象,同时将它的类标识符添加到下面的注册表项中:HKEY_CLASSES_ROOT/CLSID/。为了使收件箱意识到 MAPI 规则客户端的存在,我们还必须将它的类标识符写入下面的注册表项中: HKEY_LOCAL_MACHINE/Software/Microsoft/Inbox/Svc/SMS/Rules。


    //注册为COM对象

        lr = RegCreateKeyEx(HKEY_CLASSES_ROOT, TEXT("//CLSID//{3AB4C10E-673C-494c-98A2-CC2E91A48115}"),
                                   0, NULL, 0, 0, NULL, 
                                   &hKey, &dwDisposition);

        lr = RegCreateKeyEx(hKey, TEXT("InprocServer32"),
                                   0, NULL, 0, 0, NULL, 
                                   &hSubKey, &dwDisposition);

        lstrcpy(wszValue, TEXT("//windows//mapirule.dll"));
        lr = RegSetValueEx(hSubKey, NULL, 0, REG_SZ, (LPBYTE) wszValue, (lstrlen(wszValue) + 1) * sizeof(TCHAR));

       //注册到Inbox:

       lr = RegCreateKeyEx(HKEY_LOCAL_MACHINE, TEXT("//Software//Microsoft//Inbox//Svc//SMS//Rules"),
                                   0, NULL, 0, 0, NULL, 
                                   &hKey, &dwDisposition);

        lr = RegSetValueEx(hKey, TEXT("{3AB4C10E-673C-494c-98A2-CC2E91A48115}"), 0, REG_DWORD, 
                              (LPBYTE) &dwDisposition, sizeof(DWORD));

    二。注册成功后系统会自动调用函数ProcessMessage接收短信,当接收到短信内容是"zzz"时放入内存映射文件中

    (还有其它方法传递给应用程序,比如消息等),然后删除该短信。


    HRESULT CMailRuleClient::ProcessMessage(IMsgStore *pMsgStore, ULONG cbMsg, LPENTRYID lpMsg, 
                ULONG cbDestFolder, LPENTRYID lpDestFolder, ULONG *pulEventType, MRCHANDLED *pHandled)
    {
        HRESULT hr = S_OK;
        SizedSPropTagArray(1, sptaSubject) = { 1, PR_SUBJECT}; 
    SizedSPropTagArray(1, sptaEmail) = { 1, PR_SENDER_EMAIL_ADDRESS}; 
        ULONG cValues = 0;
        SPropValue *pspvSubject = NULL;
    SPropValue *pspvEmail = NULL;
        IMessage *pMsg = NULL;
        HRESULT hrRet = S_OK;

        // Get the message from the entry ID
        hr = pMsgStore->OpenEntry(cbMsg, lpMsg, NULL, 0, NULL, (LPUNKNOWN *) &pMsg);
        if (FAILED(hr))
        {
            
    RETAILMSG(TRUE, (TEXT("Unable to get the message!/r/n")));
           goto Exit;
        }
        
        // For SMS, the subject is also the message body
        hr = pMsg->GetProps((SPropTagArray *) &sptaSubject, MAPI_UNICODE, &cValues, &pspvSubject);
    if (FAILED(hr))
        {
            
    RETAILMSG(TRUE, (TEXT("Unable to get the message body!/r/n")));
           goto Exit;
        }
    // get the sender's address or phone number
    hr = pMsg->GetProps((SPropTagArray *) &sptaEmail, MAPI_UNICODE, &cValues, &pspvEmail);

        if (FAILED(hr))
        {
            
            RETAILMSG(TRUE, (TEXT("Couldn't get the sender's address!/r/n")));

            goto Exit;
        }

    // Here we filter the message on some predetermined string. For sample purposes
    // here we use "zzz". What happens when the filter condition(s) are met is up to
    // you. You can send WM_COPYDATA messages to other app windows for light IPC, send
    // an SMS message in response, or whatever you need to do.

    if (wcsstr(pspvSubject->Value.lpszW, L"zzz") != NULL)
    {
    if (g_hSmsAvailableEvent != NULL) {
       // We have received an SMS message that needs to be send to our client.
       // Since we run in the process space of Inbox, we are using a memory mapped
       // file to pass the message and phone number to our client, that typically
       // runs in another process space (therefor we can not simply copy strings).
       // We protect the memory mapped file with a Mutex to make sure that we are
       // not writing new SMS data while the reading client is still processing
       // a previous SMS message.
       WaitForSingleObject(g_hMutex, INFINITE);
       lstrcpy(g_pSmsBuffer->g_szPhoneNr, pspvEmail->Value.lpszW);
       lstrcpy(g_pSmsBuffer->g_szMessageBody, pspvSubject->Value.lpszW);
       ReleaseMutex(g_hMutex);
       SetEvent(g_hSmsAvailableEvent);
    }

    // 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);
    }
    else 
    {
    // a 'normal' message, pass it on
    *pHandled = MRC_NOT_HANDLED; 
    }

    // Clean up
    Exit:
        if (pspvEmail)
        {
            MAPIFreeBuffer(pspvEmail);
        }
    if (pspvSubject)
        {
            MAPIFreeBuffer(pspvSubject);
        }
        if (pMsg)
        {
            pMsg->Release();
        }

        return hr;
    }

    三。应用程序监听内存映射文件(调用TerminateSMSMessagePassing )

    void TerminateSMSMessagePassing (void)
    {
    // Make sure to have one last empty string available to copy to the client.
    memset(g_pClientSmsBuffer, 0, sizeof(SMS_BUFFER));

    SetEvent(g_hClientEvent);    // optionally allow the calling application to return from GetData.
    CloseHandle(g_hClientEvent);
    CloseHandle(g_hClientMutex);

    if (g_pClientSmsBuffer) {
    UnmapViewOfFile(g_pClientSmsBuffer);
    g_pClientSmsBuffer = NULL;
    }
    if (g_hClientMMObj) {
    CloseHandle(g_hClientMMObj);
    g_hClientMMObj = NULL;
    }
    }

    四。应用得到短信内容和发短信的号(调用SMSMessageAvailable )


    BOOL SMSMessageAvailable (wchar_t *lpDestination, wchar_t *lpPhoneNr)
    {
    WaitForSingleObject(g_hClientEvent, INFINITE);

    if (g_pClientSmsBuffer != NULL) {
    WaitForSingleObject(g_hClientMutex, INFINITE);
    lstrcpy(lpPhoneNr, g_pClientSmsBuffer->g_szPhoneNr);
    lstrcpy(lpDestination, g_pClientSmsBuffer->g_szMessageBody);
    ReleaseMutex(g_hClientMutex);
    } else {
    *lpPhoneNr = '/0';
    *lpDestination = '/0';
    }
    return *lpPhoneNr != '/0';
    }

    五。注销MailRuleClient对象


    STDAPI DllUnregisterServer()
    {
        HKEY hKey = NULL;
        HRESULT hr = E_FAIL;
        LRESULT lr;
        DWORD dwDisposition;

        // Delete registry keys
        RegDeleteKey(HKEY_CLASSES_ROOT, TEXT("//CLSID//{3AB4C10E-673C-494c-98A2-CC2E91A48115}"));
        
        lr = RegCreateKeyEx(HKEY_LOCAL_MACHINE, TEXT("//Software//Microsoft//Inbox//Svc//SMS//Rules"),
                                   0, NULL, 0, 0, NULL, 
                                   &hKey, &dwDisposition);
        if (lr != ERROR_SUCCESS)
        {
            goto Exit;
        }

        lr = RegDeleteValue(hKey, TEXT("{3AB4C10E-673C-494c-98A2-CC2E91A48115}"));

        hr = S_OK;

    Exit:
        if (hKey)
        {
            RegCloseKey(hKey);
        }

        return hr;
    }

    六。在C++中调用过程如下:


    HINSTANCE hInstLibrary = LoadLibrary(_T("//windows//mapirule.dll"));
    if (hInstLibrary == NULL) {
    FreeLibrary(hInstLibrary); 
    return 0; 
    }

    //注册

    if (DllRegisterServer() == 0) 
    {
    MessageBox("Could not initialize the IMailRuleClient DLL");
    FreeLibrary(hInstLibrary);
    return 0;
    }

       CaptureSMSMessages();
       while(true){
         SMSMessageAvailable(lpDestination,lpPhoneNr);
         if(*lpDestination != '/0'){
          OutputDebugString(lpDestination); 
          break;
         }
        }

    TerminateSMSMessagePassing();

    DllUnregisterServer();
    FreeLibrary(hInstLibrary);

    七。在C#中调用
    //导入库文件

    #region P/Invoke helpers
    [DllImport("mapirule.dll")]
    public static extern int DllRegisterServer();
    [DllImport("mapirule.dll")]
    public static extern void DllUnregisterServer();
    [DllImport("coredll.dll")]
    public static extern IntPtr LoadLibrary(string libName);
    [DllImport("coredll.dll")]
    public static extern bool FreeLibrary(IntPtr hLibModule);
    #endregion

    public class UnmanagedAPI
    {
    [DllImport("mapirule.dll")]
    public static extern int SMSMessageAvailable(StringBuilder message, StringBuilder phoneNumber);
    [DllImport("mapirule.dll")] 
    public static extern void CaptureSMSMessages();
    [DllImport("mapirule.dll")] 
    public static extern void TerminateSMSMessagePassing();
    }
    #endregion

    //注册

        hLibModule = LoadLibrary("mapirule.dll");
        if (DllRegisterServer() != 0) 
        {
         MessageBox.Show("Could not initialize the IMailRuleClient DLL");
        }

    //监听并取得消息

    UnmanagedAPI.CaptureSMSMessages();

       while (! bDone) 
       {
        UnmanagedAPI.SMSMessageAvailable(sbSms, sbPhoneNr);

        if (sbSms.Length != 0) 
        {
         parentForm.ReceivedSMSMessage = sbPhoneNr.ToString() + " - " + sbSms.ToString();
         parentForm.Invoke(new EventHandler(parentForm.UpdateListBox));
        }
       }

    //注销

    DllUnregisterServer();

    FreeLibrary(hLibModule);

  • 相关阅读:
    《Effective Java 第三版》——第五章 泛型
    线性代数在数据科学中的十个强大应用(一)
    ​知识图谱里的知识存储:neo4j的介绍和使用
    一份从入门到精通NLP的完整指南 | NLPer
    NeurIPS审稿引发吐槽大会,落选者把荒唐意见怼了个遍:“我谢谢你们了”
    知识图谱与机器学习|KG入门 -- Part2 建立知识图谱
    知识图谱与机器学习 | KG入门 -- Part1-b 图深度学习
    ​知识图谱与机器学习 | KG入门 -- Part1 Data Fabric
    使用特定领域的文档构建知识图谱 | 教程
    ICCV 2019|70 篇论文抢先读,含目标检测/自动驾驶/GCN/等(提供PDF下载)
  • 原文地址:https://www.cnblogs.com/xyzlmn/p/3168260.html
Copyright © 2011-2022 走看看