Был недавно вопрос по поводу функции Directory.EnumerateFiles(), которая ведёт себя не очень понятно при вызове. Т.е. возвращает не то, что требуется, а совсем иной результат. Впрочем сегодняшняя статья не о ней, а о такой мощной возможности плаформы .Net, как вход в исходный код во время отладки.
Думаю, если не большинство, то многие не знают и не догадываются о такой возможности. С января 2008 года компания Microsoft открыла
сервер символов, который содержит исходный код большинства библиотек платформы. Данную возможность можно использовать начиная с Visual Studio 2008 SP1, и до текущей - Visual Studio 2012. Я продемонстрирую пример в среде Visual Studio 2010 SP1, для других версий всё почти так же. И так приступим. Проблема в том, что при указании в качестве шаблона, например "*.log" в результаты выборки попадают и файлы с "*.logs". Получается результат не соответствует описанию. Создадим простое консольное приложение с нижеприведённым кодом, чтобы проверить, что там происходит на самом деле.
namespace StepInCode
{
class Program
{
static void Main(string[] args)
{
var p = Directory.EnumerateFiles("e:\\temp\\", "*log", SearchOption.TopDirectoryOnly);
}
}
}
Дальше заходим в настройки меню Debug (Tools –> Options –> Debugging –> General).
Ставим галочку в чекбокс “Enable .NET Framework source stepping” .
При этом "Enable Just My Code" отключится автоматически. Далее идём и настраиваем источник символов.
Хотя тут и настраивать нечего, просто нужно указать директорию где символы будут загружены и сохранены. Если интернет быстрый, то их загрузка (естественно не всех, а только используемых в настоящий момент сборок) во время отладки не займёт много времени. Можно ещё и пойти другим путём. Идём и загрожаем готовые установочные пакеты
отсюда.
Ждём пока загрузка завершится.
Запускаем установку пакета.
Выбираем каталог установки.
Ждём завершения.
Установка завершена. Настраиваем источник символов, как показано ниже.
Да, и обязательно галочка "Require source files to exactly match the original version" должна быть снята.
Второй вариант более длинный, поэтому если у Вас быстрый интернет то лучше выбрать первый. Поскольку всё готово, запускаем отладку.
Загружаем нужные символы для сборки. И продвигаемся по вызовам (клавиша F11)
пока не достигаем места вызова нужной нам функции. Видно, что вызывается функция Win API "
HANDLE WINAPI FindFirstFile", и судя по документации в ней символ '*' означает местозаполнитель и строки вида:
e:\\temp\\*.log
e:\\temp\\*.logs
попадают под шаблон. Поэтому и возвращается не то, что нам нужно было. Тем самым объясняется странное поведение функции. Как выход, можно сделать так:
namespace StepInCode
{
class Program
{
static void Main(string[] args)
{
var files = DirectoryExtender.GetFiles("e:\\temp\\", SearchOption.TopDirectoryOnly);
}
}
public static class DirectoryExtender
{
public static IEnumerable<string> GetFiles(string path,
SearchOption searchOption = SearchOption.TopDirectoryOnly)
{
Regex reSearchPattern = new Regex(@".log$");
return Directory.EnumerateFiles(path, "*", searchOption)
.Where(file => reSearchPattern.IsMatch(Path.GetExtension(file)));
}
}
}
Для входа в исходный код .Net Framework 4.5 с помощью Visual Studio 2012, последовательность шагов аналогична.