Estaba tratando de hacer algo similar. Llegué a la conclusión de que la biblioteca COM proporcionada por Microsoft está incompleta. No lo uso porque el documento menciona que "Nota: este tema es una documentación preliminar y está sujeto a cambios en versiones futuras".
Por lo tanto, decidí echar un vistazo a lo que está haciendo IISExpressTray.exe. Parece estar haciendo cosas similares.
Desmonte el IISExpressTray.dll y descubrí que no es mágico enumerar todos los procesos de IISexpress y detener el proceso de IISexpress.
No llama a esa biblioteca COM. No busca nada desde el registro.
Entonces, la solución que terminé es muy simple. Para iniciar un proceso express de IIS, solo uso Process.Start() y paso todos los parámetros que necesito.
Para detener un proceso de IIS express, copié el código de IISExpressTray.dll usando el reflector. Vi que simplemente envía un mensaje WM_QUIT al proceso IISExpress de destino.
Aquí está la clase que escribí para iniciar y detener un proceso de IIS express. Espero que esto pueda ayudar a alguien más.
class IISExpress
{
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);
}
public static void SendStopMessageToProcess(int PID)
{
try
{
for (IntPtr ptr = NativeMethods.GetTopWindow(IntPtr.Zero); ptr != IntPtr.Zero; ptr = NativeMethods.GetWindow(ptr, 2))
{
uint num;
NativeMethods.GetWindowThreadProcessId(ptr, out num);
if (PID == num)
{
HandleRef hWnd = new HandleRef(null, ptr);
NativeMethods.PostMessage(hWnd, 0x12, IntPtr.Zero, IntPtr.Zero);
return;
}
}
}
catch (ArgumentException)
{
}
}
const string IIS_EXPRESS = @"C:\Program Files\IIS Express\iisexpress.exe";
const string CONFIG = "config";
const string SITE = "site";
const string APP_POOL = "apppool";
Process process;
IISExpress(string config, string site, string apppool)
{
Config = config;
Site = site;
AppPool = apppool;
StringBuilder arguments = new StringBuilder();
if (!string.IsNullOrEmpty(Config))
arguments.AppendFormat("/{0}:{1} ", CONFIG, Config);
if (!string.IsNullOrEmpty(Site))
arguments.AppendFormat("/{0}:{1} ", SITE, Site);
if (!string.IsNullOrEmpty(AppPool))
arguments.AppendFormat("/{0}:{1} ", APP_POOL, AppPool);
process = Process.Start(new ProcessStartInfo()
{
FileName = IIS_EXPRESS,
Arguments = arguments.ToString(),
RedirectStandardOutput = true,
UseShellExecute = false
});
}
public string Config { get; protected set; }
public string Site { get; protected set; }
public string AppPool { get; protected set; }
public static IISExpress Start(string config, string site, string apppool)
{
return new IISExpress(config, site, apppool);
}
public void Stop()
{
SendStopMessageToProcess(process.Id);
process.Close();
}
}
No es necesario que enumere todos los procesos existentes de IIS express. Si lo necesita, por lo que vi en el reflector, lo que hace IISExpressTray.dll es llamar al Process.GetProcessByName("iisexpress", ".")
Para usar la clase que proporcioné, aquí hay un programa de muestra que utilicé para probarlo.
class Program
{
static void Main(string[] args)
{
Console.Out.WriteLine("Launching IIS Express...");
IISExpress iis1 = IISExpress.Start(
@"C:\Users\Administrator\Documents\IISExpress\config\applicationhost.config",
@"WebSite1(1)",
@"Clr4IntegratedAppPool");
IISExpress iis2 = IISExpress.Start(
@"C:\Users\Administrator\Documents\IISExpress\config\applicationhost2.config",
@"WebSite1(1)",
@"Clr4IntegratedAppPool");
Console.Out.WriteLine("Press ENTER to kill");
Console.In.ReadLine();
iis1.Stop();
iis2.Stop();
}
}
Puede que esta no sea una respuesta a su pregunta, pero creo que a las personas interesantes en su pregunta les puede resultar útil. Siéntase libre de mejorar los códigos. Hay algunos lugares que quizás desee mejorar.
- En lugar de codificar en duro la ubicación de iisexpress.exe, puede corregir mi código para leerlo en el registro.
- No incluí todos los argumentos soportados por iisexpress.exe
- No hice el manejo de errores. Por lo tanto, si el proceso de IISExpress no se pudo iniciar por algún motivo (por ejemplo, el puerto está en uso), no lo sé. Creo que la forma más fácil de solucionarlo es monitorear la transmisión StandardError y lanzar una excepción si obtengo algo de la corriente StandardError
¡Guau! ¡Muchas gracias por esta respuesta detallada! Creo que siempre que no haya una documentación COM completa/correcta en MSDN, esta parece ser la solución perfecta. Lo intentaré tan pronto como vuelva a la PC. – Mike
Ok, lo probé, funciona perfectamente.Gracias de nuevo :-) – Mike
Excelente, el mensaje de parada funcionó como un amuleto. Estoy ejecutando IIS Express desde la línea de comandos, pero esta era la pieza que faltaba. ¡Gracias! – jpierson