Elemar DEV

Tecnologia e desenvolvimento

Controlando o IISExpress, no código, através de automação

Olá pessoal. Tudo certo?!

Você conhece o IISExpress? Em caso negativo, recomendo que leia esse post do Scott Guthrie.

IISExpress é uma excelente alternativa para que possamos levantar nossos sites e/ou serviços para realizar testes de aceitação.

Como ele está baseado em um utilitário de linha de comando, mostro aqui um exemplo simples de automação para que possamos controlar o mesmo em nossos códigos.

Esse post será, fundamentalmente, código. Se você deseja entender melhor como funciona automação de interfaces, recomendo ler os outros posts que já escrevi sobre o tema.

Automação para IISExpress

No código que segue, assumo que o IISExpress está instalado na sua pasta padrão. Veja:

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace Automation
{
    internal class NativeMethods
    {
        // Methods
        [DllImport("user32.dll", SetLastError = true)]
        internal static extern IntPtr GetTopWindow(IntPtr hWnd);

        [DllImport("user32.dll", SetLastError = true)]
        internal static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);

        [DllImport("user32.dll", SetLastError = true)]
        internal static extern uint GetWindowThreadProcessId(IntPtr hwnd, out uint lpdwProcessId);

        [DllImport("user32.dll", SetLastError = true)]
        internal static extern bool PostMessage(HandleRef hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
    }

    internal class IISExpressProcessEnvelope : IDisposable
    {
        private readonly Process process;

        public IISExpressProcessEnvelope(Process process)
        {
            this.process = process;
        }

        #region IDisposable Members

        public void Dispose()
        {
            NativeMethods.PostMessage(
                GetHandleRef(), 
                0x12, 
                IntPtr.Zero, 
                IntPtr.Zero
                );
            process.Dispose();
        }

        #endregion

        private HandleRef GetHandleRef()
        {
            IntPtr ptr = NativeMethods.GetTopWindow(IntPtr.Zero);

            while (ptr != IntPtr.Zero)
            {
                uint num;
                NativeMethods.GetWindowThreadProcessId(ptr, out num);
                if (process.Id == num)
                    return new HandleRef(null, ptr);
                ptr = NativeMethods.GetWindow(ptr, 2);
            }

            throw new NullReferenceException("Process window not found.");
        }
    }

    public class IISExpress : IDisposable
    {
        private readonly IISExpressProcessEnvelope process;

        public IISExpress(int port, string path)
        {
            var info = new ProcessStartInfo
            {
                FileName = @"c:\Program Files (x86)\IIS Express\iisexpress.exe",
                Arguments = string.Format("/port:{0} /path:{1}", port, path)
            };

            process = new IISExpressProcessEnvelope(Process.Start(info));
        }

        #region IDisposable Members

        public void Dispose()
        {
            process.Dispose();
        }

        #endregion
    }
}

Destacando:

  • Faço automação através usando a API do Windows;
  • Inicio a execução do IISExpress quando a classe é criada e encerro na chamada do Dispose;
  • Criei um “Envelope” para separar a manipulação do processo da lógica principal.

Trata-se de uma solução muito simples. Além disso, sei que o design desse código poderia ser muito melhor. Por isso, ele está em um Gist. Adoraria ver sugestões de melhoria.

Exemplo de uso

O programa que segue, “levanta” um site na porta 8080. Veja:

using System;

namespace Automation.Demo
{
    class Program
    {
        static void Main()
        {
            using (var iis = new IISExpress(8080, @"c:\git\Garbage\WebDirectory\WebDirectory"))
            {
                Console.WriteLine("Pressione qq tecla para fechar.");
                Console.ReadLine();
            }

        }
    }
}

Bacana, não?! Perceba que não há restrição em quantas aplicações sejam “levantadas” simultaneamente.

Era isso.

Um comentário em “Controlando o IISExpress, no código, através de automação

  1. Pingback: IISExpress Automation agora está disponível no NuGet « Elemar DEV

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

Informação

Publicado às 18/05/2012 por em Post e marcado , .

Estatísticas

  • 677,658 hits
%d blogueiros gostam disto: