Python.
, Хотя странный путь Python имеет дело с объемом, был упомянут, худшее последствие его, я чувствую, то, что это допустимо:
import random
def myFunction():
if random.choice(True, False):
myString = "blah blah blah"
print myString
таким образом, в, если блок является тем же объемом как остальная часть функции, означая, что объявление переменной может произойти внутри condional ответвления и быть получено доступ за пределами них. Большинство языков или предотвратит Вас делающий это или по крайней мере предложит Вам некоторый строгий режим.
Эта функция будет иногда успешно выполняться и иногда выдавать исключение. Хотя это - изобретенный пример, это могло привести к некоторым тонким проблемам.
Да, можно программно перечислять и удалять элементы из кэша ядра IIS.
Предостережения:
Перечисление:
Единственный известный мне способ перечисления кэша ядра IIS - это приложение командной строки, доступное в IIS7 и более поздних версиях (хотя вы могли бы скопировать вспомогательную DLL NETSH из V7 в систему V6 - не пробовали).
netsh http show cachestate
См. Документация MSDN по команде show cachestate для получения более подробной информации. Вы можете превратить это в «API» путем выполнения процесса и анализа результатов текста.
Важное предупреждение: я никогда не видел, чтобы это приложение командной строки действительно возвращало что-либо на моем сервере, даже для приложений, работающих в классическом режиме. Не знаю почему, но приложение действительно работает, как я могу видеть из других сообщений в Интернете. (например, http://chrison.net/ViewingTheKernelCache.aspx )
Если у вас ужасная аллергия на создание процесса и вы чувствуете себя амбициозно, команды NETSH реализуются библиотеками DLL с документированным интерфейсом Win32, поэтому вы может написать код, который притворяется NETSH.exe и напрямую вызывает вспомогательную DLL-библиотеку IIS NETSH. Вы можете использовать документацию в MSDN в качестве отправной точки для этого подхода. Предупреждение: олицетворение NETSH нетривиально сложно, поскольку интерфейс двусторонний: NETSH вызывает DLL, а DLL - обратно в NETSH. И вам все равно придется анализировать вывод текста, поскольку интерфейс NETSH основан на тексте, а не на объектах, как PowerShell или WMI. Если бы это был я, я бы просто создал процесс NETSH. ; -)
Возможно, что оснастка IIS7 PowerShell может поддерживать эту функцию в будущем (что означает более легкий программный доступ, чем описанные выше взломы), но AFAIK только NETSH поддерживает эту функцию сегодня.
Недействительность :
У меня для вас хорошие и плохие новости.
Хорошие новости: как только вы узнаете URL-адрес элемента, который хотите извлечь из кеша ядра IIS, для его удаления в IIS6 и выше доступен Win32 API. Это можно вызвать из C # через P / Invoke (сложнее) или путем помещения вызова в управляемую DLL-оболочку C ++. Подробнее см. HSE_REQ_GET_CACHE_INVALIDATION_CALLBACK в MSDN.
Я попытался ввести требуемый код (прилагается ниже). Предупреждение: это уродливо и непроверено - это не приводит к сбою моего IIS, но (см. Выше) я не могу понять, как заставить работать перечисление кеша, поэтому я не могу на самом деле вызвать его с действительным URL-адресом для извлечения из кеша. Если вы можете заставить работать перечисление, то подключение действительного URL (и, следовательно, тестирование этого кода) должно быть простым.
Плохая новость:
Вот код:
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");
}
}
}
Из предоставленной вами ссылки на обсуждение видно, что метод или свойство кеша существует, но является защищенным или частным, поэтому вы не можете получить к нему доступ.
Обычно вам следует избегать использования методов, которые не являются частью общедоступного API, но если вы хотите получить к ним доступ, используйте Reflection. С помощью отражения вы можете вызывать частные методы и получать или устанавливать частные свойства и поля.