J'essayais de faire une chose similaire. J'ai conclu que la bibliothèque COM fournie par Microsoft est incomplète. Je ne l'utilise pas car la documentation mentionne que "Note : Ce sujet est une documentation préliminaire et est susceptible d'être modifiée dans les versions futures".
Alors, j'ai décidé de jeter un œil à ce que fait IISExpressTray.exe. Il semble faire des choses similaires.
Je désassemble le IISExpressTray.dll et j'ai trouvé qu'il n'y a pas de magie dans la liste de tous les processus IISexpress et d'arrêter le processus IISexpress.
Il n'appelle pas cette bibliothèque COM. Il ne recherche rien dans le registre.
Donc, la solution à laquelle j'ai abouti est très simple. Pour démarrer un processus IIS Express, j'utilise simplement Process.Start() et je passe tous les paramètres dont j'ai besoin.
Pour arrêter un processus IIS Express, j'ai copié le code du IISExpressTray.dll en utilisant un réflecteur. J'ai vu qu'il envoie simplement un message WM_QUIT au processus IISExpress cible.
Voici la classe que j'ai écrite pour démarrer et arrêter un processus IIS Express. J'espère que cela pourra aider quelqu'un d'autre.
class IISExpress
{
internal class NativeMethods
{
// Méthodes
[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();
}
}
Je n'ai pas besoin de lister tous les processus IIS Express existants. Si vous en avez besoin, d'après ce que j'ai vu dans le réflecteur, ce que fait IISExpressTray.dll est d'appeler Process.GetProcessByName("iisexpress", ".")
Pour utiliser la classe que j'ai fournie, voici un programme d'exemple que j'ai utilisé pour le tester.
class Program
{
static void Main(string[] args)
{
Console.Out.WriteLine("Lancement d'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("Appuyez sur ENTRÉE pour arrêter");
Console.In.ReadLine();
iis1.Stop();
iis2.Stop();
}
}
Cela peut ne pas répondre à votre question mais je pense que les personnes intéressées par votre question pourraient trouver mon travail utile. N'hésitez pas à améliorer les codes. Il y a des endroits que vous voudrez peut-être améliorer.
- Au lieu de coder en dur l'emplacement de iisexpress.exe, vous pouvez corriger mon code pour lire à partir du registre.
- Je n'ai pas inclus tous les arguments pris en charge par iisexpress.exe
- Je n'ai pas fait de gestion des erreurs. Donc, si le processus IISExpress échoue à démarrer pour certaines raisons (par exemple, le port est utilisé), je ne le sais pas. Je pense que le moyen le plus simple de le corriger est de surveiller le flux StandardError et de lever une exception si je reçois quelque chose du flux StandardError