0

我一直在尝试从 Windows CE 5.0 设备发送 SMS。我在网上得到了一些样本,都使用“sms.dll”,但它们似乎不起作用。我开始认为它们仅适用于 6.0。有没有我可以用来从 5.0 发送的 API?

4

1 回答 1

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 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:

    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;
    }

如果曾经收到一条 SMS 消息,它应该被此拦截“捕获”。我认为您应该在其中放置一些独特的东西,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*/
        }
      }
    }

好吧,这就是全部!我希望它有所帮助。

于 2013-06-27T15:57:57.320 回答