public class NetVersions { public static Collection<Version> InstalledDotNetVersions() { Collection<Version> versions = new Collection<Version>(); RegistryKey NDPKey = Registry.LocalMachine.OpenSubKey( @"SOFTWARE\Microsoft\NET Framework Setup\NDP", true ); if( NDPKey != null ) { string[] subkeys = NDPKey.GetSubKeyNames(); foreach( string subkey in subkeys ) { GetDotNetVersion( NDPKey.OpenSubKey( subkey ), subkey, versions ); GetDotNetVersion( NDPKey.OpenSubKey( subkey ).OpenSubKey( "Client" ), subkey, versions ); GetDotNetVersion( NDPKey.OpenSubKey( subkey ).OpenSubKey( "Full" ), subkey, versions ); } } return versions; } static void GetDotNetVersion( RegistryKey parentKey, string subVersionName, Collection<Version> versions ) { if( parentKey != null ) { string installed = Convert.ToString( parentKey.GetValue( "Install" ) ); if( installed == "1" ) { string version = Convert.ToString( parentKey.GetValue( "Version" ) ); if( string.IsNullOrEmpty( version ) ) { if( subVersionName.StartsWith( "v" ) ) version = subVersionName.Substring( 1 ); else version = subVersionName; } Version ver = new Version( version ); if( !versions.Contains( ver ) ) versions.Add( ver ); } } } }Буду рад, если оно понадобится еще кому-нибудь.
понедельник, 15 июля 2013 г.
Как узнать, какие версии Framework установлены на компьютере
На днях передо мной встала задача определить программно, какие версии .Net Framework установлены на машине клиента. Покопавшись в реестре, я нашел нужную мне информацию в "HKLM\SOFTWARE\Microsoft\NET Framework Setup\NDP". Однако, что бы правильно вытащить ее оттуда, пришлось немного повозиться и вылилось в следующий код:
понедельник, 8 июля 2013 г.
Как проверить, что мы в дизайнере (DesignMode) в Windows Form
Задача
Разрабатывая элементы управления в дизайнере Windows Form, нам часто необходимо проверить в каком режиме открыли наш элемент. Ведь в реальном режиме у нас может быть сложная логика чтения информации из БД, подключения в web-службам, взаимодействия с какими-то сторонними компонентами и т. д.. На момент редактирования визуального представления, вся эта логика должна быть отключена. А, для этого, нам необходим какой-то признак, по которому мы сможем отличить дизайнер от реального запуска программы:if( !DesignMode ) { //... }
Решения
Для начала посмотрим на то, что нам предлагают разработчики от Микрософт. В классе Component имеется свойство DesignMode. "Эврика! Это именно то, что нужно", подумал я. А, прочитав описание, я уж было совсем расслабился и начал писать свой код. Однако, первое же использование моего контроля в дизайнере, ввело меня в недоумение и растерянность - DesignMode был false. Всегда! Покурив форумы, я понял, что это свойство становится true после какого-то там обряда инициализации. Далее шли рассуждения о том, в какой момент времени это свойство показывает правильное значение, а в какой неправильное.. В общем-то рассуждения весьма бредовые, потому что код "иногда работающий правильно" - это как часы которые стоят - показывают правильное время ровно 2 раза в сутки, но толку от этого никакого. Кроме того, как я уже говорил, свойство находится в классе Component, а значит, до него невозможно добраться из вспомогательных классов, не имеющих ссылку на Component, что приводит к ограничениям в рефакторинге. А это значит, что свойство не просто бесполезно, но и вредно.
Продолжая курить форумы, я случайно наткнулся на класс LicenseManager. С его помощью проверку можно осуществить следующим образом:
if( LicenseManager.UsageMode != LicenseUsageMode.Designtime ) { //... }Однако, тут есть один маленький неприятный нюанс - этот класс писали те же "руки", что и предыдущий, а значит, работает все так же "глючно" и, в самый неожиданный момент, свойство UsageMode может выдать Runtime, не смотря на то, что мы находимся в дизайнере.
Еще одно интересное решение - это проверить название процесса:
if( Process.GetCurrentProcess().ProcessName != "devenv" ) { //... }Ограничения такого решения видны сразу - оно будет работать только из-под одной среды разработки - Microsoft Visual Studio. Однако, ничего не мешает расширить проверку, если ваша команда использует другие средства. По крайней мере, тут все прозрачно и предсказуемо.
Так как же сделать проверку правильно? Ок. Есть еще один вариант, который мне кажется самым правильным - завести где-то в общей библиотеке статическую переменную DesignMode, которая по умолчанию будет равна true. А, при запуске программы, сбрасывать ее на false. Это решение стабильно, прозрачно и надежно. Но! Это ужасное решение. Дело в том, что библиотека, содержащая такое решение, накладывает ограничения на свое использование - подключая такую библиотеку к проекту, нам придется вспомнить о нужных строчках и вписать их, а при исключении библиотеки из проекта, строчку придется удалять. Конечно, ничего криминального в этом нет. Однако, стоит нам предположить, что подход со статистическими флажками приемлем, как мы начнем использовать его повсеместно и наши библиотеки приобретут совершенно непредсказуемое поведение - ведь очень скоро уже никто и не вспомнит какие флажки надо прописать, где, когда и сколько их вообще и какие для чего.
Выводы
Я так и не смог найти оптимального решения данной задачи. Сам я использую комбинации приведенных выше подходов, каждый раз вспоминая "добрым словом" авторов свойства DesignMode. Если кто-нибудь нашел решение лучше - буду рад получить обратную связь в комментариях.
Подписаться на:
Сообщения (Atom)