Starting and Stopping Iis Express Programmatically

Starting and stopping IIS Express programmatically

I was trying to do similar thing. I concluded that the COM library provided by Microsoft is incomplete. I don't use it because the doc mentioned that "Note: This topic is pre-release documentation and is subject to change in future releases".

So, I decided to take a look at what IISExpressTray.exe is doing. It seems to be doing similar things.

I disassemble the IISExpressTray.dll and found that there is no magic in listing out all the IISexpress processes and stoping the IISexpress process.

It doesn't call that COM library. It doesn't lookup anything from registry.

So, the solution I ended up is very simple. To start an IIS express process, I just use Process.Start() and pass in all the parameters I need.

To stop an IIS express process, I copied the code from IISExpressTray.dll using reflector. I saw it simply sends a WM_QUIT message to the target IISExpress process.

Here is the class I wrote to start and stop an IIS express process. Hope this can help somebody else.

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

I don't need to list all the existing IIS express process. If you need that, from what I saw in the reflector, what IISExpressTray.dll does is to call Process.GetProcessByName("iisexpress", ".")

To use the class I provided, here is a sample program I used to test it.

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

This may not be an answer to your question but I think people interesting in your question may find my work useful. Feel free to improve the codes. There are some places that you might want to enhance.

  1. Instead of hardcoding the iisexpress.exe location, you can fix my code to read from the registry.
  2. I didn't include all the arguments supported by iisexpress.exe
  3. I didn't do error handling. So, if the IISExpress process failed to start for some reasons (e.g. port is in used), I don't know. I think the easiest way to fix it is to monitor the StandardError stream and throw exception if I get anything from StandardError stream

Stop IIS express process based on site name

I put together this script in PowerShell:

$site = 'Webapplication' # replace this by your site name (not case sensitive)
$process = Get-CimInstance Win32_Process -Filter "Name = 'iisexpress.exe'" | ? {$_.CommandLine -like "*/site:`"$site`"*" }
if($process -ne $null)
{
Write-Host "Trying to stop $($process.CommandLine)"
Stop-Process -Id $process.ProcessId
Start-Sleep -Seconds 1 # Wait 1 second for good measure
Write-Host "Process was stopped"
} else
{
Write-Host "Website was not running"
}
  • Modify the first line to replace the site name with yours. Save this
    file as stopiis.ps1 on your project folder (not the solution folder).
  • Now, on Solution Explorer, right-click and choose properties
  • On the left side, choose Build Events
  • Put this on 'Pre-Build event command line' so it will run before compiling:

    echo powershell -File "$(ProjectDir)stopiis.ps1"

    powershell -File "$(ProjectDir)stopiis.ps1"

Build Action

  • Note: you do not need to run Visual Studio in Administrative mode because IISExpress.exe run under your account

Stop a web site hosted with IIS Express from command line

Option-1:

If you don't have any other sites running, try

"taskkill /IM iisexpress.exe"

Note: This stops all iisexpress.exe processes

Option-2:

Write some executable utility for doing this. Following link may help you!
Starting and stopping IIS Express programmatically

Starting a ASP.net WebApp using IISExpress from the command line

When using path with IISExpress commandline it should point to root folder of your website not bin folder.

iisexpress /path:c:\myapp\



Related Topics



Leave a reply



Submit