C# 使用DirectoryEntry和Reflection在AppPool中的应用程序中执行方法?

C# 使用DirectoryEntry和Reflection在AppPool中的应用程序中执行方法?,c#,reflection,iis-7,C#,Reflection,Iis 7,你好 我正在运行一个带有StateSession缓存的小型web花园。显而易见的问题是,当您想要清除缓存时,缓存只在处理调用的workerprocess上被清除 在特定的应用程序池中,将至少有一个用户界面应用程序和一个Web服务应用程序。Web服务执行大部分缓存,因此它们有清除缓存的方法 我想做的是创建一个方法,该方法将获取输入(AppPool名称),然后它将迭代当前的w3wp进程并获取所需的池。这是可以做到的,我有办法得到这些信息 我陷入困境的地方是,我有AppPool名称以及在工作进程中运行

你好

我正在运行一个带有StateSession缓存的小型web花园。显而易见的问题是,当您想要清除缓存时,缓存只在处理调用的workerprocess上被清除

在特定的应用程序池中,将至少有一个用户界面应用程序和一个Web服务应用程序。Web服务执行大部分缓存,因此它们有清除缓存的方法

我想做的是创建一个方法,该方法将获取输入(AppPool名称),然后它将迭代当前的w3wp进程并获取所需的池。这是可以做到的,我有办法得到这些信息

我陷入困境的地方是,我有AppPool名称以及在工作进程中运行的应用程序,但我不知道如何使用这些信息在特定Web服务应用程序中执行“ClearCache()”方法

我确信这可以通过反思来实现,但我认为我遗漏了一些显而易见的东西

目前我只是使用一个控制台应用程序来获得一些有用的东西。然后可以在适当的时候将其转移到更好的解决方案

请告知是否有方法使用当前信息来执行所需的方法

下面是目前的测试应用程序

多谢各位

杰科

使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用系统诊断;
使用制度管理;
使用System.DirectoryServices;
使用系统集合;
命名空间缓存清理器
{
班级计划
{
常量字符串defaultAppPoolMetabasePath=“IIS://localhost/W3SVC/AppPools/DefaultAppPool”;
静态void Main(字符串[]参数)
{
//显示所有进程的列表。
//getListofProcess();
//杀死所有工作进程
//KillW3WP();
//刷新应用程序池
//RefreshAppPool(defaultAppPoolMetabasePath);
//获取DefaultAppPool中所有应用程序的列表
//GetApplicationPoolFormation(defaultAppPoolMetabasePath);
//获取应用程序池中的应用程序
EnumerateApplicationsInPool(defaultAppPoolMetabasePath);
Console.WriteLine(“\n\n退出进程。按Enter键”);
Console.ReadLine();
}
/// 
///显示当前在系统上运行的所有进程
/// 
静态void getListofProcess()
{
foreach(Process.getprocesss()中的进程p)
{
WriteLine(“{0}{1}”,p.Id,p.ProcessName);
}
}
/// 
///这将杀死所有工作进程。
///差不多是一个iisreset电话。
///不适合生产现场:)
/// 
静态void KillW3WP()
{
foreach(Process.getProcessByName(“w3wp”)中的进程p)
{
Console.WriteLine(“关闭”+p.ProcessName);
p、 杀死();
p、 WaitForExit();
如果(p.已退出)
{
控制台写入线(“关闭”);
}
其他的
{
控制台写入线(“未终止”);
}
}
}
/// 
///刷新特定的应用程序池
/// 
/// 
静态无效RefreshAppPool(字符串元数据库路径)
{
使用(DirectoryEntry应用程序池=新的DirectoryEntry(metabasePath))
{
applicationPool.Invoke(“回收”);
}
}
/// 
///获取工作进程的名称(AppPool名称)
/// 
/// 
静态void GetApplicationPoolFormation(字符串元数据库路径)
{
var scope=newmanagementscope(String.Format(@“\\{0}\root\cimv2”,Environment.MachineName));
var query=new SelectQuery(“从Win32_进程中选择*,其中Name='w3wp.exe'”);
使用(var searcher=newmanagementobjectsearcher(范围,查询))
{
foreach(searcher.Get()中的ManagementObject进程)
{
//只获取应用程序的名称
var startIndex=process[“CommandLine”].ToString().IndexOf(“-ap”)+5;//删除-ap以及空格和
var endIndex=process[“CommandLine”].ToString().IndexOf(“-”,startIndex)-2;//删除关闭
var appPoolName=process[“CommandLine”].ToString().Substring(startIndex,endIndex-startIndex);
var pid=process[“ProcessId”].ToString();
WriteLine(“{0}-{1}”,pid,appPoolName);
}
}
}
/// 
///获取池中的应用程序
///从http://msdn.microsoft.com/en-us/library/ms524452%28v=vs.90%29.aspx
/// 
/// 
静态无效枚举ApplicationInPool(字符串元数据库路径)
{
WriteLine(“\n{0}池的计算应用程序:”,metabasePath);
尝试
{
DirectoryEntry=新的DirectoryEntry(metabasePath);
if(entry.SchemaClassName==“IIsApplicationPool”)
{
对象[]参数;
param=(object[])entry.Invoke(“EnumAppsInPool”,null);
foreach(参数中的字符串s)
{
Console.WriteLine(“{0}”,s);
//我确信我应该能够使用此应用程序名称
//通过反射可以执行一个方法。。。
}
控制台。WriteLine(“完成”);
}
其他的
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Management;
using System.DirectoryServices;
using System.Collections;

namespace CacheCleaner
{
    class Program
    {
        const string defaultAppPoolMetabasePath = "IIS://localhost/W3SVC/AppPools/DefaultAppPool";

        static void Main(string[] args)
        {
            //show a list of all the processes.
            //GetListOfProcesses();

            //Kill all the worker processes
            //KillW3WP();

            //Refresh the application pool
            //RefreshAppPool(defaultAppPoolMetabasePath);

            //get a list of all the Applications in the DefaultAppPool
            //GetApplicationPoolInformation(defaultAppPoolMetabasePath);

            //get the apps in the apppool
            EnumerateApplicationsInPool(defaultAppPoolMetabasePath);

            Console.WriteLine("\n\nEnd of process. Press Enter.");

            Console.ReadLine();

        }

        /// <summary>
        /// Show all the processes that are currently running on the system
        /// </summary>
        static void GetListOfProcesses()
        {
            foreach (Process p in Process.GetProcesses())
            {
                Console.WriteLine("{0} {1}", p.Id, p.ProcessName);
            }
        }

        /// <summary>
        /// This will kill ALL the worker processes.
        /// Pretty much an iisreset call.
        /// Not good for Production sites :)
        /// </summary>
        static void KillW3WP()
        {
            foreach (Process p in Process.GetProcessesByName("w3wp"))
            {
                Console.WriteLine("Closing " + p.ProcessName);

                p.Kill();
                p.WaitForExit();

                if (p.HasExited)
                {
                    Console.WriteLine("Closed");
                }
                else
                {
                    Console.WriteLine("NOT Terminated");
                }
            }
        }

        /// <summary>
        /// Refresh a specific application pool
        /// </summary>
        /// <param name="metabasePath"></param>
        static void RefreshAppPool(string metabasePath)
        {
            using (DirectoryEntry applicationPool = new DirectoryEntry(metabasePath))
            {
                applicationPool.Invoke("Recycle");
            }
        }

        /// <summary>
        /// Get the Name of the worker process (AppPool Name)
        /// </summary>
        /// <param name="metabasePath"></param>
        static void GetApplicationPoolInformation(string metabasePath)
        {
            var scope = new ManagementScope(String.Format(@"\\{0}\root\cimv2", Environment.MachineName));
            var query = new SelectQuery("SELECT * FROM Win32_Process where Name = 'w3wp.exe'");
            using (var searcher = new ManagementObjectSearcher(scope, query))
            {
                foreach (ManagementObject process in searcher.Get())
                {
                    //get just the name of the application
                    var startIndex = process["CommandLine"].ToString().IndexOf("-ap ") + 5; //remove the -ap as well as the space and the "
                    var endIndex = process["CommandLine"].ToString().IndexOf("-", startIndex) - 2; //remove the closing "
                    var appPoolName = process["CommandLine"].ToString().Substring(startIndex, endIndex - startIndex);

                    var pid = process["ProcessId"].ToString();

                    Console.WriteLine("{0} - {1}", pid, appPoolName);
                }
            }
        }

        /// <summary>
        /// Get the applications in the pool
        /// From http://msdn.microsoft.com/en-us/library/ms524452%28v=vs.90%29.aspx
        /// </summary>
        /// <param name="metabasePath"></param>
        static void EnumerateApplicationsInPool(string metabasePath)
        {
            Console.WriteLine("\nEnumerating applications for the {0} pool:", metabasePath);

            try
            {
                DirectoryEntry entry = new DirectoryEntry(metabasePath);

                if (entry.SchemaClassName == "IIsApplicationPool")
                {
                    object[] param;
                    param = (object[])entry.Invoke("EnumAppsInPool", null);
                    foreach (string s in param)
                    {
                        Console.WriteLine("{0}", s);

                        //I am sure that I should be able to use this application name 
                        //with Reflection to be able to execute a method...

                    }
                    Console.WriteLine("Done.");
                }
                else
                    Console.WriteLine("Failed in EnumerateApplicationsInPool; {0} is not an app pool", metabasePath);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Failed in EnumerateApplicationsInPool with the following exception: \n{0}", ex);
            }
        }
    }
}