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.
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:
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.
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.
Pingback: IISExpress Automation agora está disponível no NuGet « Elemar DEV