• Understanding System.Messaging


    这段是Windows Mobile handbook 中的内容,对其不甚了解。

    Although System.Messaging is a new set of functionality in .NET Compact Framework 2.0, it wraps a technology called Microsoft Message Queuing (MSMQ), which has been available to native code developers for some time and is present in the desktop .NET Framework. MSMQ provides loosely coupled store-and-forward messaging between applications and different computers. Each message contains a packet of raw data that can be up to 4 megabytes (MB) in size, though it is uncommon to create such large messages. As with many APIs, this is a subset of a standard Windows API that is exposed as a set of Component Object Model (COM) interfaces and C functions. The System.Messaging namespace removes all complexities of calling into this native code and provides a subset of the System.Messaging namespace that is present in the full .NET Framework.

    Installing MSMQ

    MSMQ is an optional component of Windows CE: It can be built into a custom platform by the operating system developer, or in the case of Windows Mobile, it is shipped separately to be installed in device memory. The standalone Windows Mobile 2003 software development kit (SDK) includes the required files to be installed manually on the target device. The Windows Mobile 5.0 SDK does not include the MSMQ components, but instead they are deployed separately as part of the Redistributable Server Components Package for Windows Mobile 5.0 on the Microsoft Download Center Web site at http://www.microsoft.com/downloads/details.aspx?FamilyID=&DisplayLang=en. Because this updated version is packaged as a compressed .cab file, it cannot be installed on device versions prior to Windows Mobile 5.0. Another difference in the Windows Mobile 5.0 version is that it supports using HTTP as a transport, rather than just the default binary transport. This can simplify your network configuration because data is sent over TCP port 80. The Windows Mobile 2003 SDK, which is included with Visual Studio 2005, does not include the MSMQ components, so if you are targeting devices that run Pocket PC 2003, you must install the standalone Pocket PC 2003 SDK, which you can download from the Microsoft Download Center Web site at http://www.microsoft.com/downloads/details.aspx?FamilyID=&DisplayLang=en.

    To install these Pocket PC 2003 files on the device, you must copy them all to the Windows directory. For Windows Mobile 5.0, simply copy the .cab file onto the device and install. Some further steps that apply to both versions are required to set up the MSMQ service on the device.

    You can use the Msmqadm.exe application to control the service, and you must issue it with a number of commands to register the service correctly on the device. These can be called from your managed application using the System.Diagnostics.Process.Start method and checking the process ExitCode for status. The following code example shows these called from a method in the sample application.

         //helper function to launch a process and wait for the result code
    private static int ShellWait(string app, string args)
    {
    if (!File.Exists(app))
    {
    return -1;
    }
    Process p = Process.Start(app, args);
    p.WaitForExit();
    return p.ExitCode;
    }

    [DllImport("coredll.dll", SetLastError=true)]
    private extern static int CloseHandle(IntPtr handle);

    [DllImport("coredll.dll", SetLastError = true)]
    private extern static IntPtr ActivateDevice(string lpszDevKey,
    int dwClientInfo);

    private static void InitMsmq()
    {
    string msmqadmPath = "\\Windows\\msmqadm.exe";

    if (ShellWait(msmqadmPath, "status") < 0)
    {
    //failed, msmq isn't present
    string apppath = Path.GetDirectoryName(
    System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);


    if (System.Environment.OSVersion.Version.Major < 5)
    {
    //copy files (PPC2003)
    File.Copy(Path.Combine(apppath, "msmqadm.exe"), "\\Windows\\msmqadm.exe");
    File.Copy(Path.Combine(apppath, "msmqadmext.dll"),
    "\\Windows\\msmqadmext.dll");
    File.Copy(Path.Combine(apppath, "msmqd.dll"),
    "\\Windows\\msmqd.dll");
    File.Copy(Path.Combine(apppath, "msmqrt.dll"),
    "\\Windows\\msmqrt.dll");
    }

    else
    {
    //Install CAB (WM5.0)
    string cabname = Path.Combine(apppath, "msmq.arm.cab");
    ShellWait("\\Windows\\wceload.exe", "\"" + cabname + "\"");
    }
    //initialize
    ShellWait(msmqadmPath, "register cleanup");
    ShellWait(msmqadmPath, "register install");
    ShellWait(msmqadmPath, "register");
    ShellWait(msmqadmPath, "enable binary");

    //Register the service.
    IntPtr handle = ActivateDevice("Drivers\\BuiltIn\\MSMQD", 0);
    CloseHandle(handle);

    //final check on the status
    if (ShellWait(msmqadmPath, "status") < 0)
    {
    throw new ApplicationException("Failed to register MSMQ");
    }

    }

    }

    The Windows CE version of MSMQ doesn't support reading from remote queues, and neither does it support some of the more advanced security features such as encryption and access control lists (ACLs) for queues. It is not possible to search for public queues published in the Microsoft Active Directory directory service. Queues must be created as private queues on the server to be used by Message Queuing on Windows CE.

    Set Up a Private Queue

    The Windows operating system doesn't have MSMQ installed by default, so you must add it by using Add/Remove Programs in Control Panel and selecting Add/Remove Windows Features. After it is installed, you can manage message queuing from Computer Management in Administration Tools in Control Panel, as shown in Figure 8-1.

    Image from book
    Figure 8-1: Microsoft MessageQueue Management Console

    Transaction Support

    Message queuing on Windows CE supports only basic transaction support to ensure once-only delivery in the order the messages were originally sent. It doesn't support multimessage transactions using Microsoft Transaction Coordinator (MTC). You can set transaction support on a server queue simply by selecting the option when creating the queue. You can't change this setting once the queue has been created. Figure 8-2 shows the New Private Queue dialog box you can use to create a new private queue.

    Image from book
    Figure 8-2: New Private Queue dialog box

    Formatters

    Formatters are used to convert your data into a form that can be sent in an MSMQ message. The desktop .NET Framework has three built-in formatters: ActiveXMessageFormatter, BinaryMessageFormatter, and XmlMessageFormatter. Because the Compact Framework includes no support for Microsoft ActiveX or binary serialization, it's no surprise that it supports only XmlMessageFormatter. This uses the Extensible Markup Language (XML) serialization built into the framework to produce an XML fragment that on the receiving computer can be deserialized into the same object type. This does, however, mean that individual messages are quite large in comparison with a binary representation of an object, which can be a concern when run over slow and expensive networks.

    You must make sure you use the same formatter on both ends of the same queue. You are not, however, limited to the single MessageFormatter provided by the Compact Framework because it is possible to implement your own custom MessageFormatter. Nothing is stopping you from implementing your own version of the missing BinaryMessageFormatter or other missing features such as encryption. Writing a custom MessageFormatter is discussed in the article titled "How to create a custom message formatter by using Visual C#" on the Microsoft Help and Support Web site at http://www.support.microsoft.com/default.aspx?scid=kb%3bEN-US%3b310683.

    Queuing Messages from the Device

    After MSMQ is installed on the device and the server queue is created, you can start to queue some messages. You can use the MessageQueue class to do this. You must supply the queue name. Queue names are similar in concept to Uniform Resource Locators (URLs), but the format is different; the target computer can be addressed either by IP address or by machine name. MSMQ uses the Domain Name System (DNS) and Windows Internet Name Service (WINS) as available to determine the target computer. A queue name, therefore, looks like either of the following:

         FormatName:DIRECT=OS:CUBE\Private$\Prospects
    FormatName:DIRECT=TCP:192.168.2.2\Private$\Prospects

    You can also use a local queue. For this, the machine name or IP address is replaced with a single period:

         .\Private$\Prospects

    This can be set in code by using the Path property, or you can drop a MessageQueue onto your form in the designer and set the path in the properties window.

         this.mqRemote.Path = "FormatName:Direct=OS:CUBE\\Private$\\Prospects";

    The MessageQueue can then be used to send messages. For example, this is our sample Prospect class:

         Prospect p = new Prospect();
    p.Name = txtName.Text;
    p.Company = txtCompany.Text;
    p.Number = txtNumber.Text;

    mqRemote.Send(p);

    To send messages to a transactional queue requires two changes to your code. First, you must add the XACTONLY identifier to the queue path, so our previous two examples become the following:

         FormatName:DIRECT=OS:CUBE\Private$\Prospects:XACTONLY
    FormatName:DIRECT=TCP:192.168.2.2\Private$\Prospects:XACTONLY

    Second, you must call the overload of the Send method, which accepts a MessageQueue-TransactionType, for example:

         mqRemote.Send(p, MessageQueueTransactionType.Single);

    If you do not make these changes, your message will not be delivered to the transactional queue.

    The formatter on the receiving queue must have the TargetTypes or TargetTypeNames properties set to tell it into what types to convert the XML. You must do this only once when setting up the queue. The receiving thread to read from a local queue is very simple. No processing of the received object is done in this example; it's simply added to the on-screen list.

         private void ReceiveThread()
    {
    XmlMessageFormatter formatter = new XmlMessageFormatter(
    new Type[] { typeof(Prospect) });
    mqLocal.Formatter = formatter;

    while (listening)
    {
    Message m = mqLocal.Receive();
    Prospect p = (Prospect)m.Body;
    this.Invoke(new AppendToListBoxDelegate(AppendToListBox),
    new object[] { p.ToString() });
    }
    }

    One potential use for a local queue is as an interprocess communication (IPC) method. Because another application could listen on the queue and you could pass messages back and forth. The other application need not be a managed application because MSMQ also has anative API.

  • 相关阅读:
    STM32中管脚利用
    阻抗匹配
    无功功率与补偿
    宏的灵活应用例子
    串口接入检测与串口命令解析
    16 款最流行的JavaScript 框架
    不可错过的10个超棒jQuery表单操作代码片段
    20 个用于处理页面滚动效果的 jQuery 插件
    11 个最佳 jQuery 滚动条插件
    jQuery的搜索关键词自动匹配插件
  • 原文地址:https://www.cnblogs.com/qqhfeng/p/1577837.html
Copyright © 2020-2023  润新知