Msmq no Compact Framework 2.0

Neste artigo veremos como utilizar um dos novos recursos do .Net Compact Framework 2.0, o uso do MSMQ no Windows Mobile.

Msmq no Compact Framework 2.0

 

Num outro artigo vimos como utilizar o recurso de enfileiramento de mensagens do Windows, o MSMQ ( Microsoft Message Queuing ), no .Net Framework. Neste veremos como utilizar um dos novos recursos do .Net Compact Framework 2.0, o uso do MSMQ no Windows Mobile.

 

Preparando ambiente

Nós utilizaremos o Windows Mobile 2003, e a primeira coisa a fazer é baixar o seu SDK, cujo link se encontra logo abaixo:

http://www.microsoft.com/downloads/details.aspx?FamilyID=9996b314-0364-4623-9ede-

0b5fbb133652&DisplayLang=en

 

Criando o projeto

Agora no Visual Studio 2005 vamos criar nosso projeto ( Visual C# -> Smart Device -> Pocket PC 2003 -> Device Application ), o qual daremos o nome de MsmqCF.

 

Adicionando referências

O SDK que baixamos possui alguns arquivos os quais farão a instalação do Msmq no Windows Mobile. Esses arquivos devem está localizados no diretório “C:\Program Files\Windows CE Tools\wce420\POCKET PC 2003\Support\Msmq\armv4”, ou algo similar, dependendo do idioma do S.O .

 

Para isso vamos adicionar todos os arquivo deste diretório no nosso projeto ( Add->Existing Item..).

 

Em todos eles, a propriedade “Build Action” deve está como Content e a propriedade “Copy to Output Directoy” como Copy if newer.

 

Dividindo o desenvolvimento em duas etapas

Vamos dividir o desenvolvimento em duas etapas: a primeira será em relação ao processo de instalação automática do MSMQ no Pocket PC, e a segunda será a utilização realmente do serviço de enfileiramento de mensagens.

 

1 - Instalação automática do MSMQ no Windows Mobile

 

A seguir veremos o código responsável pela instalação do MSMQ no Pocket. Não entraremos em detalhe pois não é nosso objetivo e sua explicação tornaria o artigo demasiadamente longo.

No FORM ( Form1) criado no projeto, vamos  adicionar o código a seguir:

 

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

   // Liberando handles

CloseHandle(pi.hProcess);

return false;

}

 

CloseHandle(pi.hThread);

            // Liberando handles

CloseHandle(pi.hProcess);

if (exitCode != 0)

return false;

else

return true;

}

 

        //This is the MSMQAdm.exe utility we’ll be using

private const String MSMQ_ADM = @"\windows\msmqadm.exe";

private const String MSMQ_DRIVER_REG = @"Drivers\BuiltIn\MSMQD";

 

private static void CopyFilesRequired()

{

string _path = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().

                      GetName().CodeBase);

if (!File.Exists(@"\windows\msmqadm.exe"))

                File.Copy(_path + "\\msmqadm.exe", @"\windows\msmqadm.exe");

if (!File.Exists(@"\windows\msmqadmext.dll"))

                File.Copy(_path + "\\msmqadmext.dll", @"\windows\msmqadmext.dll");

if (!File.Exists(@"\windows\msmqd.dll"))

                File.Copy(_path + "\\msmqd.dll", @"\windows\msmqd.dll");

if (!File.Exists(@"\windows\msmqrt.dll"))

                File.Copy(_path + "\\msmqrt.dll", @"\windows\msmqrt.dll");

 

            File.Delete(_path + "\\msmqadm.exe");

            File.Delete(_path + "\\msmqadmext.dll");

            File.Delete(_path + "\\msmqd.dll");

            File.Delete(_path + "\\msmqrt.dll");

}

 

Adicionaremos no evento de Load do Form o código que irá verificar a presença do MSMQ no dispositivo, e instalá-lo caso este ainda não esteja presente .

 

//We need to move the MSMQ components deployed to the system folder

CopyFilesRequired();

//Check status of MSMQ (is it installed and running yet?

 

if (!(CreateProcess(MSMQ_ADM, "status")))

{

//Deletes the MSMQ registry key and store directory.

//All messages are lost.

 

CreateProcess(MSMQ_ADM, "register cleanup");

       //Installs MSMQ as device drivcers.

  if (CreateProcess(MSMQ_ADM, "register install"))  

{

  MessageBox.Show("Registered Drivers Successfully");

 }

else

{

          MessageBox.Show("Failed to install MSMQ! System Error = " + GetLastError().ToString());

  return;

}

 

//Creates the MSMQ Configuration in Registry

        if (CreateProcess(MSMQ_ADM, "register"))

{

           MessageBox.Show("Registered MSMQ Successfully");

}

        else

{

           MessageBox.Show("Failed to Register MSMQ! System Error = " + GetLastError().ToString());

//  return;

 }

 

//Enables the native MSMQ protocol

        if (CreateProcess(MSMQ_ADM, "enable binary"))

{

           MessageBox.Show("Enable Binary Successfully");

}

        else

{

        MessageBox.Show("Failed to enable Binary! System Error = " + GetLastError().ToString());

        return;

}

 

//Starts the MSMQ service

        if (CreateProcess(MSMQ_ADM, "start"))

{

           MessageBox.Show("Started MSMQ Successfully");

}

        else

{

 

//This is one additional step that is needed for PocketPCs

//The Device Drivers have to be loaded before the service

//can be started

//ActivateDevice will load the device drivers

 

        IntPtr handle = ActivateDevice(MSMQ_DRIVER_REG, 0);

CloseHandle(handle);

 

//Let us check if MSMQ is running

 

        if (CreateProcess(MSMQ_ADM, "status"))

{

MessageBox.Show("MSMQ is up and running");

}

        else

{

   MessageBox.Show("Failed to start MSMQ! System Error = " + GetLastError().ToString());

   }

}

}

else

MessageBox.Show("MSMQ is already up and running");

 

2 – Utilização do MSMQ no dispositivo

 

Finalmente vamos adicionar o código para a utilização propriamente dita do MSMQ no dispositivo, pois até agora tudo que vimos foi em relação à instalação automática do serviço.

 

Adicionando os controles do Form

Adicione os controles a seguir (verificar o layout na figura ao lado):

 

 

Controle

ID

TextBox

txtSendMsg

TextBox

txtRecMsg

Button

btnSendMsg

Button

btnReceiveMsg

 

 

Agora vamos inserir o código do button (btnSendMsg) responsável por enviar a mensagem para a fila do MSMQ. Para isso dê um duplo-clique no Button e insira o seguinte código:

 

if (txtSendMsg.Text.Trim() == "") return;

string strDestQ = @".\private$\testq"; //nome da fila

try

{

    if (!MessageQueue.Exists(strDestQ))

{

       MessageQueue.Create(strDestQ);

}

 

    MessageQueue mq = new MessageQueue(strDestQ);

mq.Send(txtSendMsg.Text);

txtSendMsg.Text = "";

}

Catch

{

 

}

 

E por último vamos inserir o código do button (btnReceiveMsg) responsável por ler da fila do MSMQ as mensagens disponíveis. Para isso dê um duplo-clique no Button e insira o seguinte código:

 

lblReceiveMsg.Text = ""; Refresh();

            MessageQueue mq = new MessageQueue(@".\private$\testq");

            //especifica o formatter para des-serializar a mensagem

mq.Formatter = new XmlMessageFormatter(new Type[] { typeof(String) });

            try

{

                Message messageReceived = mq.Receive(new TimeSpan(0, 0, 1));//timeout em 1s

txtRecMsg.Text = (string)messageReceived.Body;

}

            catch { txtRecMsg.Text = "- timeout -"; }

 

Pronto, isso é tudo. Observe que código para utilização do MSMQ é muito pequeno, apenas algumas poucas linhas, lembrando que grande parte do código neste artigo foi para a instalação do MSMQ no dispositivo.

 

Agora é só executar e testar a aplicação. Vale ressaltar que ao rodar a aplicação pela  primeira, o MSMQ será instalado no dispositivo, o que resultará em um tempo maior no deploy.

 

É isso ai pessoal, até a próxima.

 

Gustavo Barros

 

OBS: Este artigo foi baseado no blog do Mark Ihimoyan´s:

http://blogs.msdn.com/ihimmar/archive/2004/06/14/154911.aspx

Ebook exclusivo
Dê um upgrade no início da sua jornada. Crie sua conta grátis e baixe o e-book

Artigos relacionados