New to compact framework tutorials? Learn to write your first compact framework application here.
Zac Efron - Hairspray star and Mythbusters' Kari Byron at Celebrity Treat. Check out income and career information in Singapore.

Saturday, January 07, 2006

- MSMQ Message Queueing in Compact Framework (part 1)

In this tutorial, we write a simple MSMQ application for a Windows Mobile device. The application automatically installs the MSMQ service if it's not already present. A simple interface is provided to let the user send and receive messages via MSMQ.



MSMQ is a Microsoft message queueing technology that allows disparate applications, not necessarily running in the same machine, to send messages to one another. Part of this store-and-forward technology is a failsafe mechanism to ensure guaranteed delivery (well, to an extent). Message priorities can also be set as well.

One of the strongest competitors to Microsoft, in terms of providing message queueing middleware, remains to be IBM, which offers the product called WebSphere MQ (previously called IBM MQSeries).

This tutorial is based on Mark Ihimoyan's posts in his excellent blog.
  1. As usual, start Visual Studio and create a new smart device project.
  2. In Solution Explorer, right-click on References, and add the reference to System.Messaging component. We need this reference as we are using the Messaging classes later.
  3. Change the form property MinimizeBox to false, so that the use can close the application easily.
  4. Add a TextBox, 2 Buttons and a Label to the form, naming them txtSendMsg, btnSend, btnReceive and lblReceiveMsg respectively. The first button lets the user send the message in the textbox to a message queue. The second button receives a message from the queue. Even if the user closes the application, the stored messages in the queue remain intact and can be received when the application is restarted (however, a soft reset clears the queue).
  5. Next, we want to make the application self-contained, in that it will check for the presence of the MSMQ service and automatically installs it if it is not detected.
  6. Go to Microsoft Mobile Development Center and follow the link "Redistributable Server Components for Windows Mobile 5.0" to download the package. We need the msmq.ARM.CAB file in the package.
  7. After downloading, extract the msmq.ARM.CAB file (under msmq folder in the downloaded package). This is the cab file that installs the MSMQ service in the device.
  8. Back in Visual Studio, right-click on your project in Solution Explorer and add msmq.ARM.CAB to your project (use Add-> Existing Item...). Then click on msmq.ARM.CAB in Solution Explorer and change its "Copy to Output Directory" property to "Copy if newer". This will ensure that the cab file is copied over to the program folder in the device.
  9. In your form code, import the namespaces:
  10. using System.IO;
    using System.Messaging;
    using System.Runtime.InteropServices;
  11. Then within the form partial class, add the following declarations needed to P/Invoke the CreateProcess Win32 function. We need to call CreateProcess to install the cab.
  12. public class ProcessInfo
    {
      public IntPtr hProcess;
      public IntPtr hThread;
      public Int32 ProcessId;
      public Int32 ThreadId;
    }

    [DllImport("CoreDll.DLL", SetLastError = true)]
    private extern static
        int CreateProcess(String imageName,
        String cmdLine,
        IntPtr lpProcessAttributes,
        IntPtr lpThreadAttributes,
        Int32 boolInheritHandles,
        Int32 dwCreationFlags,
        IntPtr lpEnvironment,
        IntPtr lpszCurrentDir,
        IntPtr lpsiStartInfo,
        ProcessInfo pi);
    [DllImport("CoreDll.dll")]
    private extern static  Int32 GetLastError();

    [DllImport("CoreDll.dll")]
    private extern static
        Int32 GetExitCodeProcess(IntPtr hProcess, out Int32 exitcode);

    [DllImport("CoreDll.dll")]
    private extern static
         Int32 CloseHandle(IntPtr hProcess);

    [DllImport("CoreDll.dll")]
    private extern static
        IntPtr ActivateDevice(
          string lpszDevKey,
            Int32 dwClientInfo);

    [DllImport("CoreDll.dll")]
    private extern static
        Int32 WaitForSingleObject(IntPtr Handle,
        Int32 Wait);

    public static bool CreateProcess(String ExeName, String CmdLine)
    {
      Int32 INFINITE;
      unchecked { INFINITE = (int)0xFFFFFFFF; }
      ProcessInfo pi = new ProcessInfo();
      if (CreateProcess(ExeName, CmdLine, IntPtr.Zero, IntPtr.Zero,
          0, 0, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, pi) == 0)
      {
        return false;
      }
      WaitForSingleObject(pi.hProcess, INFINITE);
      Int32 exitCode;
      if (GetExitCodeProcess(pi.hProcess, out exitCode) == 0)
      {
        MessageBox.Show("Failure in GetExitCodeProcess");
        CloseHandle(pi.hThread);
        CloseHandle(pi.hProcess);
        return false;
      }
      CloseHandle(pi.hThread);
      CloseHandle(pi.hProcess);
      if (exitCode != 0)
        return false;
      else
        return true;
    }
  13. In the Form Load event handler (remember to generate the event handler stub by double-clicking on the form in design mode; similarly for the button click event handlers later), enter the following code which checks for and installs the MSMQ service.
  14. string MSMQ_ADM = @"\windows\msmqadm.exe";
    if (!CreateProcess(MSMQ_ADM, "status"))
    {
      if (!File.Exists(MSMQ_ADM) ||
         !File.Exists(@"\windows\msmqd.dll") ||
         !File.Exists(@"\windows\msmqrt.dll"))
      {
        //install msmq
        string _path = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
        string docname = _path + "\\msmq.ARM.CAB";
        CreateProcess("wceload.exe", "/noui \"" + _path + "\\msmq.ARM.CAB\"");
      }
      //check again
      if (!File.Exists(@"\windows\msmqadm.exe"))
      {
        MessageBox.Show("failed to install msmq cab");
        Close();
      }
      else //register, start and activate service
      {
        CreateProcess(MSMQ_ADM, "register cleanup");
        if (CreateProcess(MSMQ_ADM, "register install")
          && CreateProcess(MSMQ_ADM, "register")
          && CreateProcess(MSMQ_ADM, "enable binary"))
        {
          IntPtr handle = ActivateDevice(@"Drivers\BuiltIn\MSMQD", 0);//device registry key
          CloseHandle(handle);
          if (CreateProcess(MSMQ_ADM, "status")) return; //success
        }
        MessageBox.Show("failed to start msmq");
        Close();
      }
    }
  15. In the btnSend click event handler, enter the following code to send a message to the "testq" queue.
  16. if (txtSendMsg.Text.Trim() == "") return;
    string strDestQ = @".\private$\testq"; //queue name
    try
    {
      if (!MessageQueue.Exists(strDestQ))
        MessageQueue.Create(strDestQ);
      MessageQueue mq = new MessageQueue(strDestQ);
      mq.Send(txtSendMsg.Text);
      txtSendMsg.Text = "";
    }
    catch { }
  17. Finally, in the btnReceive click event handler, we will receive the frontmost message in the "testq" queue. Note that we are setting a simple timeout of 1 second (so the UI is not blocked for too long) in case there isn't any message in the queue.
  18. lblReceiveMsg.Text = ""; Refresh();
    MessageQueue mq = new MessageQueue(@".\private$\testq");
    //set formatter for deserializing message
    mq.Formatter = new XmlMessageFormatter(new Type[] { typeof(String) });
    try
    {
      Message messageReceived = mq.Receive(new TimeSpan(0, 0, 1));//timeout in 1s
      lblReceiveMsg.Text = (string)messageReceived.Body;
    }
    catch { lblReceiveMsg.Text = "- timeout -"; }
  19. We are done! Deploy and run. The first time you run, there is quite a long delay on form load, as the application is invoking wceload.exe to install the MSMQ service. When the form is loaded, type something in the textbox and click the Send button. Send a few more messages. Then click the Receive button a few times.
  20. Try closing and reopening the application and test if sent messages are still receivable. What about the effect of doing a soft reset?
In part 2, coming soon, we will send MSMQ messages across the network. Watch this space.

Categories: [MSMQ_] [Networking_] Tags: [] [] [] []
Read more...

Tuesday, January 03, 2006

- Create a SQL Mobile database (part 1)

I recently conducted a small poll and it turns out that SQL Mobile is the most requested topic (see ongoing voting results here). So in this tutorial, we will cover how to create a SQL Mobile database for the PDA or emulator.

Having seen the SQL Server Express (mentioned here), let's now look at SQL Mobile.

Being the successor of SQL Server CE 2.0, SQL Mobile is Microsoft's lightweight database server that has a small enough footprint (~1.5MB) to fit and run smoothly in a Pocket PC device. It is included in Visual Studio .NET 2005, so you don't have to install anything as a developer. For end users, SQL Mobile can be installed on the Pocket PC 2003, Windows Mobile 5.0, Smartphone 5.0 as well as Windows CE 5.0 platforms. Word has it that SQL Mobile will be pre-installed in the ROM of all new Windows Mobile devices, just like Compact Framework 2.0.

In terms of features, SQL Mobile offers transactional support, multi-user access, as well as synchronization and replication with back-end servers. In terms of competition, I'm not too sure if these few players are still fighting close: Sybase SQL Anywhere, Oracle Lite and IBM DB2 Everyplace.

Alright, let's dive in to create our very first SQL Mobile database.

  1. Start Visual Studio and create a new smart device project.
  2. Click Data in the menu and select "Add New Data Source..." to see the following dialog window.



  3. Select the Database icon (to indicate that you are creating a database) and click Next.
  4. In the next screen, click "New Connection..." to create a new database.
  5. In the the pop-up "Add Connection" window, click "Change..." to select a data source type. You should see the following:



  6. Select "Microsoft SQL Server Mobile Edition" as the Data Source and leave the Data provider as ".NET Framework Data Provider for SQL Server Mobile Edition". Click OK.
  7. Back at the "Add Connection" dialog, leave "My Computer" radiobutton selected, and then click "Create" to specify the filename of the SQL Mobile database. Enter "C:\FirstDB.sdf" for the filename and leave the other fields as they are (you can also specify the password here, but we leave it empty for convenience).



  8. Click OK. If prompted on the empty password, click Yes.
  9. You may now click "Test Connection" to check if the database is in order.
  10. Click OK. Back at the first dialog window, click Next, and click Yes to add the database file to your project. In the next screen, click Cancel as we are not using generated DataSets in this tutorial.
  11. You will notice that the FirstDB.sdf has been added to your project. Click on it and press F4 to check that its "Copy to Output Directory" property is "Copy if newer". This means that the file will be copied to the emulator if the emulator does not have a copy or have an older copy.
  12. Now, from the menu, click View-> Server Explorer. And in the Server Explorer pane, click the "Connect to Database" icon (2nd icon from the right; or move your mouse over each icon to see the tooltip).
  13. Click Browse and go to your project folder and select the FirstDB.sdf file. (Note that you can also create a database here, but care must be taken to add the created file to your project.)
  14. Test the connection and click OK.
  15. In the Server Explorer pane, expand the tree, right-click on Tables and select "Create Table". Enter the table name and create 2 columns for it, as shown below. Click on the image below to zoom in. (Note that the custid column has Identity set to true, so that this column's value for each record is auto-generated.)



  16. Click OK.
  17. Finally, run your program.
  18. There's nothing interesting in your form. However, open File Explorer and browse to the folder which contains the deployed files (at \Program Files\yourProjName). You should see a file with the name "FirstDB" there. The .sdf extension is not displayed. Click on this file to open it with Query Analyzer. Query Analyzer allows you to explore and manage SQL Mobile databases from within the PDA environment.
  19. In Query Analyzer, expand the tree under the Objects tab. You should see this:



  20. That's it! You have created a simple SQL Mobile database and transferred it to the emulator/device. Part 2, coming soon, will cover how to create a SQL Mobile database programmatically.
Categories: [Data Access_] Tags: [] [] []
Read more...

- Plasma or LCD TV?

Two years ago, the choice was clear. Just by comparing their response times, Plasma television sets won hands down, never mind the burn-ins. LCD TVs were simply too slow and left streaks of image blurs when viewing action movies. Fast forward to today. Have things changed?



The response time problem for LCD television is no longer an issue, with some models (in particular Sharp Aquos) even boasting a remarkable 4ms in their specifications. Although Plasma TVs still have more vivid colors, LCDs have surpassed them in terms of viewing angles. Some LCD models even have wider viewing angles than the typical 170 degrees that Plasmas offer. The Sony Bravia, for example, offers a 178-degree viewing angle.

LCD models have a longer lifespan of 65,000 hours, almost twice longer than that of Plasmas. To be fair, a few Plasmas also claim to have a 60k-hour lifespan, but these are the exception rather than the norm. Moreover, LCD TVs have replaceable fluorescent tubes, allowing for even longer extended operation. In contrast, there's nothing in Plasmas that can be easily and affordably replaced.



Finally, Plasma TVs are in general a lot heavier than LCD TVs, and Plasmas still suffer from burn-ins (images get permanently etched on the screen when left displayed for too long). Price-wise, both are on par. LCDs have the added advantage of being more energy efficient. So, all other things equal, I will definitely go for an LCD. Won't you?

Categories: [Blogging_] Tags: [] [] []
Read more...