Я пытался сделать подобное. Я пришел к выводу, что библиотека COM, предоставленная Microsoft, является неполной. Я не использую его, потому что в документе упоминалось, что «Примечание: этот раздел является предварительной версией документации и может быть изменен в будущих выпусках».
Итак, я решил посмотреть, что делает IISExpressTray.exe. Кажется, он делает похожие вещи.
Я разобрал IISExpressTray.dll и обнаружил, что нет магии при перечислении всех процессов IISexpress и остановке процесса IISexpress.
Это не называется COM-библиотекой. Он не ищет ничего из реестра.
Итак, решение, которое я закончил, очень простое. Чтобы запустить процесс IIS express, я просто использую Process.Start() и передаю все необходимые мне параметры.
Чтобы остановить процесс экспресс-доставки IIS, я скопировал код из IISExpressTray.dll с помощью отражателя. Я видел, что он просто отправляет сообщение WM_QUIT в целевой процесс IISExpress.
Вот класс, который я написал, чтобы начать и остановить процесс IIS express. Надеюсь, это поможет кому-то другому.
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();
}
}
Мне не нужно перечислять весь существующий процесс IIS. Если вам это нужно, то, что я видел в рефлекторе, то, что IISExpressTray.dll делает, это позвонить Process.GetProcessByName("iisexpress", ".")
Чтобы использовать предоставленный мной класс, вот пример программы, которую я использовал для ее проверки.
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();
}
}
Возможно, это не ответ на ваш вопрос, но я думаю, что люди, интересующиеся вашим вопросом, могут найти мою работу полезной. Не стесняйтесь улучшать коды. Есть некоторые места, которые вы, возможно, захотите улучшить.
- Вместо жесткого кодирования iisexpress.exe вы можете исправить мой код для чтения из реестра.
- Я не включил все аргументы, поддерживаемые iisexpress.exe
- Я не занимался обработкой ошибок. Итак, если процесс IISExpress не запускался по некоторым причинам (например, порт используется), я не знаю. Я думаю, что самый простой способ исправить это - контролировать поток StandardError и исключать исключение, если я получу что-либо из потока StandardError.
Вау! Большое спасибо за этот подробный ответ! Я думаю, что до тех пор, пока не будет полной/правильной документации COM на MSDN, это, кажется, идеальное решение. Я попробую, как только вернусь на компьютер. – Mike
Хорошо, я пробовал, отлично работает.Еще раз спасибо :-) – Mike
Отлично, сообщение остановки работает как шарм. Я запускаю IIS Express из командной строки, но это был недостающий кусок. Благодаря! – jpierson