2013-06-26 78 views
0

我一直在嘗試從Windows CE 5.0設備發送短信。我在網上獲得了一些樣本,全部使用「sms.dll」,但他們似乎沒有工作。我開始認爲他們只能在6.0下工作。有沒有我可以用來從5.0發送的API?如何從Windows CE 5.0發送短信?

+0

我已經爲我的C#代碼提供了一個SMS例程,但是我從來沒有能夠得到它的工作。我所得到的是我的自定義例外,說「短信失敗」。如果你願意,我可以發佈我是如何做到的,但就像我說的 - 我的版本也失敗了。 – jp2code

+0

請發佈。在這一點上值得一看。謝謝。 – Yves

回答

0

不能說我明白我在下面做了什麼,就像我說的 - 我從來沒有得到這個爲我工作。

這就是說,這是我使用的類,從上到下分解了一些解釋。

首先,命名空間包括:

using System; 
using System.Linq; 
using System.Collections.Generic; 
using System.Text; 
using Microsoft.WindowsMobile.PocketOutlook.MessageInterception; 
using Microsoft.Win32; 
using Microsoft.WindowsMobile.PocketOutlook; 
using System.Runtime.InteropServices; 

我把這個在它自己的命名空間,以便它不與我的其他東西干擾,然後聲明一些常量:

namespace MobileSMS { 

    class SmsClass { 

    private const Int32 FILE_DEVICE_HAL = 0x00000101; 
    private const Int32 FILE_ANY_ACCESS = 0x0; 
    private const Int32 METHOD_BUFFERED = 0x0; 
    private static readonly Int32 IOCTL_HAL_GET_DEVICEID = 
     ((FILE_DEVICE_HAL) << 16) | 
     ((FILE_ANY_ACCESS) << 14) | 
     ((21) << 2) | (METHOD_BUFFERED); 
    private const string NO_NAME = "[Unnamed]"; 
    private const string COREDLL = "coredll.dll"; 

    [DllImport(COREDLL)] 
    private static extern bool KernelIoControl(Int32 IoControlCode, IntPtr InputBuffer, Int32 InputBufferSize, byte[] OutputBuffer, Int32 OutputBufferSize, ref Int32 BytesReturned); 

    } 

} 

這些都是我上面所有的常量。

private string m_name; 
    private MessageInterceptor m_sms; 

    public SmsClass() { 
     m_name = null; 
     Exception error = null; 
     try { 
     m_sms = new MessageInterceptor(DeviceName, false); 
     m_sms.InterceptionAction = InterceptionAction.NotifyAndDelete; 
     m_sms.MessageCondition = new MessageCondition(MessageProperty.Body, MessagePropertyComparisonType.StartsWith, DeviceName); 
     m_sms.MessageReceived += new MessageInterceptorEventHandler(Intercept_MessageReceived); 
     m_sms.EnableApplicationLauncher(DeviceName); 
     } catch (Exception err) { 
     error = err; // just because there was an error doesn't mean it might not have been enabled. 
     } 
     if (!MessageInterceptor.IsApplicationLauncherEnabled(DeviceName)) { 
     Console.WriteLine("Unable to load SMS Tool: " + error.Message); 
     } 
    } 

我的構造函數總是失敗。 不要在構造函數中拋出錯誤(如果你不知道的話),或者該類錯誤。

由於我對IOCTL_HAL_GET_DEVICEID的定義,我的班級有可能失敗 - 我可以誠實地說我不理解所有這些。我只是把它複製下來。

DeviceName需要是唯一的,以便一個設備可以在發送消息時區分對方(所以我聽到)。這裏是我如何得到一個DeviceName:它首先在註冊表中搜索條目,如果它找不到任何東西,我使用我在Microsoft上找到的一些東西來獲取唯一的序列號(但它實際上看起來更像是一個GUI)。

public string DeviceName { 
     get { 
     if (String.IsNullOrEmpty(m_name)) { 
      m_name = getName(); 
     } 
     return m_name; 
     } 
     set { 
     if (m_name != value) { 
      m_name = value; 
     } 
     } 
    } 

這是我試圖從註冊表中讀取我的價值:

private static string getDeviceID() { 
     // Reference: http://msdn.microsoft.com/en-us/library/aa446562.aspx 
     byte[] data = new byte[256]; 
     Int32 OutputBufferSize = data.Length; 
     Int32 BytesReturned = 0; 
     // Call KernelIoControl passing the previously defined IOCTL_HAL_GET_DEVICEID parameter 
     // We don’t need to pass any input buffers to this call 
     // so InputBuffer and InputBufferSize are set to their null values 
     bool retVal = KernelIoControl(IOCTL_HAL_GET_DEVICEID, IntPtr.Zero, 0, data, OutputBufferSize, ref BytesReturned); 
     // If the request failed, exit the method now 
     if (retVal) { 
     // Examine the OutputBuffer byte array to find the start of the 
     // Preset ID and Platform ID, as well as the size of the PlatformID. 
     // PresetIDOffset – The number of bytes the preset ID is offset from the beginning of the structure 
     // PlatformIDOffset - The number of bytes the platform ID is offset from the beginning of the structure 
     // PlatformIDSize - The number of bytes used to store the platform ID 
     // Use BitConverter.ToInt32() to convert from byte[] to int 
     Int32 PresetIDOffset = BitConverter.ToInt32(data, 4); 
     Int32 PlatformIDOffset = BitConverter.ToInt32(data, 0xc); 
     Int32 PlatformIDSize = BitConverter.ToInt32(data, 0x10); 

     // Convert the Preset ID segments into a string so they can be 
     // displayed easily. 
     StringBuilder sb = new StringBuilder(); 
     sb.Append(String.Format("{0:X8}-{1:X4}-{2:X4}-{3:X4}-", 
      BitConverter.ToInt32(data, PresetIDOffset), 
      BitConverter.ToInt16(data, PresetIDOffset + 4), 
      BitConverter.ToInt16(data, PresetIDOffset + 6), 
      BitConverter.ToInt16(data, PresetIDOffset + 8))); 
     // Break the Platform ID down into 2-digit hexadecimal numbers 
     // and append them to the Preset ID. This will result in a 
     // string-formatted Device ID 
     for (int i = PlatformIDOffset; i < PlatformIDOffset + PlatformIDSize; i++) { 
      sb.Append(String.Format("{0:X2}", data[i])); 
     } 
     // return the Device ID string 
     return sb.ToString(); 
     } 
     return null; 
    } 

private static string getName() { 
     string name = null; 
     using (var key = Registry.LocalMachine.OpenSubKey("Ident", true)) { 
     name = key.GetValue("Name", NO_NAME) as string; 
     } 
     if (String.IsNullOrEmpty(name)) { 
     name = getDeviceID(); 
     } 
     return name; 
    } 

如果拉什麼,我用這個代碼,我在MSDN上找到獲取設備ID

如果收到短信,它應該被這個攔截「攔截」。我認爲你應該在command中加入一些獨特的東西,這樣你就可以將其識別爲來自其他設備之一的消息,而不是隨意嘗試發送任何內容給任何聽的東西。雖然我從來沒有那麼遠,因爲我的例程總是在構造函數中失敗。

private static void Intercept_MessageReceived(object sender, MessageInterceptorEventArgs e) { 
     var newMessage = (SmsMessage)e.Message; 
     if (newMessage != null) { 
     Console.WriteLine("From: {0}", newMessage.From.Address); 
     Console.WriteLine("Body: {0}", newMessage.Body); 
     string[] command = newMessage.Body.Split(new char[] { '.' }); 
     string line = command[1]; 
     if (line == "helo") { 
      /*do some Stuff*/ 
     } 
     } 
    } 

好吧,就是這樣!我希望它有幫助。