2009-08-14 19 views
6

यह केवल उपयोगकर्ता कैश में आइटम को साफ करता है:एएसपी.NET से आईआईएस कर्नेल कैश तक पहुंचने का कोई तरीका?

public static void ClearCache() 
    { 
     foreach (DictionaryEntry entry in HttpRuntime.Cache) 
     { 
      HttpRuntime.Cache.Remove(entry.Key.ToString()); 
     } 
    } 

वहाँ रूप में अच्छी तरह गिरी कैश का उपयोग करने की कोई तरीका है?

स्पष्टीकरण: मैं कर्नेल कैश में सभी वस्तुओं की चाबियाँ मुद्रित करना चाहता हूं, और एक बोनस के रूप में मैं कर्नेल कैश को सी # विधि से भी साफ़ करने में सक्षम होना चाहता हूं।

+1

यहां इस मुद्दे की और चर्चा है: http://www.west-wind.com/weblog/posts/11379.aspx#121596 (टिप्पणियां देखें)। क्या किसी के पास उल्लेख किया गया है उससे बेहतर समाधान है? –

उत्तर

11

हां, प्रोग्रामिंग रूप से गणना करना और आईआईएस के कर्नेल कैश से आइटम को निकालना संभव है।

चेतावनियां:

  • गैर तुच्छ पाठ पार्स गणन के लिए requred
  • बदसूरत पी के
  • बहुत सारे/आह्वान हटाने
  • इसके अलावा के लिए आवश्यक है, तो आप की आवश्यकता होगी कम से कम मध्यम ट्रस्ट (और शायद पूर्ण ट्रस्ट) नीचे की चीजें करने के लिए।
  • निष्कासन आईआईएस के एकीकृत पाइपलाइन मोड में काम नहीं करेगा।
  • गणन शायद IIS6 पर काम नहीं करेगा

गणन:

केवल प्रलेखित तरह से मैं आईआईएस गिरी कैश की गणना करने में पता IIS7 में उपलब्ध है और इसके बाद के संस्करण एक कमांड लाइन अनुप्रयोग है (हालांकि आप V7 से NETSH सहायक डीएलएल को V6 सिस्टम पर कॉपी करने में सक्षम हो सकते हैं - इसे आजमाया नहीं है)।

netsh http show cachestate 

अधिक जानकारी के लिए MSDN Documentation of the show cachestate command देखें। प्रक्रिया को निष्पादित करके और पाठ परिणामों को पार्स करके आप इसे "एपीआई" में बदल सकते हैं।

बिग कैविट: मैंने क्लासिक मोड में चल रहे ऐप्स के लिए भी इस सर्वर-लाइन ऐप को वास्तव में कुछ भी नहीं देखा है। यकीन नहीं क्यों - लेकिन ऐप काम करता है क्योंकि मैं ऑनलाइन अन्य पोस्टिंग से देख सकता हूं। (जैसे http://chrison.net/ViewingTheKernelCache.aspx)

आप, बुरी तरह निर्माण और महत्वाकांक्षी, netsh आदेश महसूस कर रही एक प्रलेखित Win32 इंटरफेस के साथ DLL के द्वारा लागू किया जाता है की प्रक्रिया से एलर्जी हो, तो आप कोड जो यह Netsh.exe है दिखावा और आईआईएस के netsh सहायक कॉल लिख सकता है तो डीएलएल सीधे। आप इस दृष्टिकोण के लिए शुरुआती बिंदु के रूप में documentation on MSDN का उपयोग कर सकते हैं। चेतावनी: एनईटीएसएच का प्रतिरूपण गैर-मामूली मुश्किल है क्योंकि इंटरफ़ेस 2-तरफा है: एनईटीएसएच डीएलएल में कॉल करता है और डीएलएल वापस नेट्सएच में कॉल करता है। और आपको अभी भी टेक्स्ट आउटपुट का विश्लेषण करना होगा क्योंकि नेटस्एच इंटरफ़ेस टेक्स्ट-आधारित है, न कि ऑब्जेक्ट-आधारित PowerShell या WMI। अगर यह मैं था, तो मैं इसके बजाय एक नेटस्एच प्रक्रिया उत्पन्न करूँगा। ;-)

यह संभव है कि IIS7 PowerShell snapin भविष्य में इस कार्यक्षमता का समर्थन कर सकता है (अर्थात् ऊपर हैक्स की तुलना में आसान प्रोग्रामेटिक पहुंच), लेकिन AFAIK केवल नेटस्के इस सुविधा का समर्थन करता है।

शक्ति कम:

मैं अच्छी खबर यह है और आप के लिए बुरी खबर मिल गया है।

अच्छी खबर यह है: एक बार जब आप आइटम आप आईआईएस के कर्नेल कैश से झटका करना चाहते हैं के URL को जानने, वहाँ एक Win32 एपीआई IIS6 और इसके बाद के संस्करण पर इसे हटाने के लिए उपलब्ध है। इसे सी # से पी/इनवॉक (कड़ी) के माध्यम से या कॉल को एक प्रबंधित सी ++ रैपर डीएलएल में डालकर कहा जा सकता है। विवरण के लिए एमएसडीएन पर HSE_REQ_GET_CACHE_INVALIDATION_CALLBACK देखें।

मैं कोड की आवश्यकता (नीचे संलग्न) में चाकू ले लिया। चेतावनी: यह बदसूरत और अवांछित है - यह मेरे आईआईएस को क्रैश नहीं करता है लेकिन (ऊपर देखें) मैं यह नहीं समझ सकता कि कैश गणना कैसे प्राप्त करें ताकि मैं इसे कैश से खींचने के लिए वास्तव में एक वैध यूआरएल के साथ नहीं बुला सकूं। यदि आप गणना काम कर सकते हैं, तो एक वैध यूआरएल (और इसलिए इस कोड का परीक्षण) में प्लगिंग आसान होना चाहिए।

बुरी खबर:

  • के रूप में आप कोड नमूने से अनुमान लगा सकते हैं, यह IIS7 के एकीकृत पाइप लाइन मोड पर, केवल क्लासिक मोड में (या IIS6 ज़ाहिर है,) काम नहीं करेगा जहां ASP.NET चलाता है
  • निजी क्षेत्रों के साथ खिलवाड़ एक बड़ा हैक है और एक नए संस्करण में टूट सकता है एक ISAPI के रूप में और ISAPI कार्यों की पहुंच है
  • पी/आह्वान से निपटने के लिए कठिन है और आवश्यकता है (मेरा मानना ​​है कि) पूर्ण विश्वास

यहां कुछ कोड दिया गया है:

using System; 
using System.Web; 
using System.Reflection; 
using System.Runtime.InteropServices; 

public partial class Test : System.Web.UI.Page 
{ 
    /// Return Type: BOOL->int 
    public delegate int GetServerVariable(); 

    /// Return Type: BOOL->int 
    public delegate int WriteClient(); 

    /// Return Type: BOOL->int 
    public delegate int ReadClient(); 

    /// Return Type: BOOL->int 
    public delegate int ServerSupportFunction(); 

    /// Return Type: BOOL->int 
    public delegate int EXTENSION_CONTROL_BLOCK_GetServerVariable(); 

    /// Return Type: BOOL->int 
    public delegate int EXTENSION_CONTROL_BLOCK_WriteClient(); 

    /// Return Type: BOOL->int 
    public delegate int EXTENSION_CONTROL_BLOCK_ReadClient(); 

    /// Return Type: BOOL->int 
    public delegate int EXTENSION_CONTROL_BLOCK_ServerSupportFunction(); 

    public static readonly int HSE_LOG_BUFFER_LEN = 80; 

    [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, CharSet = System.Runtime.InteropServices.CharSet.Ansi)] 
    public struct EXTENSION_CONTROL_BLOCK 
    { 
     /// DWORD->unsigned int 
     public uint cbSize; 

     /// DWORD->unsigned int 
     public uint dwVersion; 

     /// DWORD->unsigned int 
     public uint connID; 

     /// DWORD->unsigned int 
     public uint dwHttpStatusCode; 

     /// CHAR[HSE_LOG_BUFFER_LEN] 
     [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = 80 /*HSE_LOG_BUFFER_LEN*/)] 
     public string lpszLogData; 

     /// LPSTR->CHAR* 
     public System.IntPtr lpszMethod; 

     /// LPSTR->CHAR* 
     public System.IntPtr lpszQueryString; 

     /// LPSTR->CHAR* 
     public System.IntPtr lpszPathInfo; 

     /// LPSTR->CHAR* 
     public System.IntPtr lpszPathTranslated; 

     /// DWORD->unsigned int 
     public uint cbTotalBytes; 

     /// DWORD->unsigned int 
     public uint cbAvailable; 

     /// LPBYTE->BYTE* 
     public System.IntPtr lpbData; 

     /// LPSTR->CHAR* 
     public System.IntPtr lpszContentType; 

     /// EXTENSION_CONTROL_BLOCK_GetServerVariable 
     public EXTENSION_CONTROL_BLOCK_GetServerVariable GetServerVariable; 

     /// EXTENSION_CONTROL_BLOCK_WriteClient 
     public EXTENSION_CONTROL_BLOCK_WriteClient WriteClient; 

     /// EXTENSION_CONTROL_BLOCK_ReadClient 
     public EXTENSION_CONTROL_BLOCK_ReadClient ReadClient; 

     /// EXTENSION_CONTROL_BLOCK_ServerSupportFunction 
     // changed to specific signiature for invalidation callback 
     public ServerSupportFunction_HSE_REQ_GET_CACHE_INVALIDATION_CALLBACK ServerSupportFunction; 
    } 
    /// Return Type: BOOL->int 
    ///ConnID: DWORD->unsigned int 
    ///dwServerSupportFunction: DWORD->unsigned int 
    ///lpvBuffer: LPVOID->void* 
    ///lpdwSize: LPDWORD->DWORD* 
    ///lpdwDataType: LPDWORD->DWORD* 
    [return: System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)] 
    public delegate bool ServerSupportFunction_HSE_REQ_GET_CACHE_INVALIDATION_CALLBACK(
     uint ConnID, 
     uint dwServerSupportFunction, // must be HSE_REQ_GET_CACHE_INVALIDATION_CALLBACK 
     out Callback_HSE_REQ_GET_CACHE_INVALIDATION_CALLBACK lpvBuffer, 
     out uint lpdwSize, 
     out uint lpdwDataType); 

    public readonly uint HSE_REQ_GET_CACHE_INVALIDATION_CALLBACK = 1040; 

    // typedef HRESULT (WINAPI * PFN_HSE_CACHE_INVALIDATION_CALLBACK)(WCHAR *pszUrl); 
    [return: System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)] 
    public delegate bool Callback_HSE_REQ_GET_CACHE_INVALIDATION_CALLBACK(
     [MarshalAs(UnmanagedType.LPWStr)]string url); 

    object GetField (Type t, object o, string fieldName) 
    { 
     FieldInfo fld = t.GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic); 
     return fld == null ? null : fld.GetValue(o); 
    } 

    protected void Page_Load(object sender, EventArgs e) 
    { 
     // first, get the ECB from the ISAPIWorkerRequest 
     var ctx = HttpContext.Current; 
     HttpWorkerRequest wr = (HttpWorkerRequest) GetField(typeof(HttpContext), ctx, "_wr"); 
     IntPtr ecbPtr = IntPtr.Zero; 
     for (var t = wr.GetType(); t != null && t != typeof(object); t = t.BaseType) 
     { 
      object o = GetField(t, wr, "_ecb"); 
      if (o != null) 
      { 
       ecbPtr = (IntPtr)o; 
       break; 
      } 
     } 

     // now call the ECB callback function to remove the item from cache 
     if (ecbPtr != IntPtr.Zero) 
     { 
      EXTENSION_CONTROL_BLOCK ecb = (EXTENSION_CONTROL_BLOCK)Marshal.PtrToStructure(
       ecbPtr, typeof(EXTENSION_CONTROL_BLOCK)); 
      uint dummy1, dummy2; 

      Callback_HSE_REQ_GET_CACHE_INVALIDATION_CALLBACK invalidationCallback; 
      ecb.ServerSupportFunction(ecb.connID, 
        HSE_REQ_GET_CACHE_INVALIDATION_CALLBACK, 
        out invalidationCallback, 
        out dummy1, 
        out dummy2); 

      bool success = invalidationCallback("/this/is/a/test"); 
     } 
    } 
} 
+0

महान प्रतिक्रिया! धन्यवाद। –

0

आपके द्वारा प्रदत्त चर्चा लिंक से, ऐसा प्रतीत होता है कि कैश विधि या संपत्ति मौजूद है लेकिन संरक्षित या निजी है ताकि आप इसे एक्सेस न कर सकें।

आम तौर पर, आपको उन विधियों का उपयोग करने से दूर रहना चाहिए जो सार्वजनिक एपीआई का हिस्सा नहीं हैं, लेकिन यदि आप उन्हें एक्सेस करना चाहते हैं, तो प्रतिबिंब का उपयोग करें। प्रतिबिंब के साथ, आप निजी तरीकों को कॉल कर सकते हैं और निजी संपत्तियों और क्षेत्रों को प्राप्त या सेट कर सकते हैं।

संबंधित मुद्दे