ToX: 4CDC7CC794ACD0CC9848F68EC7292D4F80A469FB468C49F9C73CCE5588055861B60807127EE6
E-mail: hexxladen[inu]inbox.lv
Telegram: @eternalsavage
Monthly Archives: Ноябрь 2018
C#, DataSet, пользовательские типы данных, и хинтик при использовании Dataset Designer.
Известно, что DataSet
может хранить пользовательские типы данных в таблицах. Для нетипизированного DataSet
, т.е. экземпляра класса DataSet
, достаточно, чтобы нужные типы данных были видны из того места кода, в котором будем проводить операции с DataSet
. Например, сделаем тестовый enum
:
public enum testenum { val0=0, val1=1 }
и подключим какое-нибудь дополнительное пространство имен, например:
using System.Diagnostics;
Теперь, в таблицу DataSet
можно добавить поля типов testenum
и, например, ProcessWindowStyle
(из System.Diagnostics
)
//...
DataSet dsTest = new DataSet();
//...
dsTest.Tables.Add("Test");
dsTest.Tables["Test"].Columns.Add("Text", typeof(string));
dsTest.Tables["Test"].Columns.Add("Enum", typeof(testenum));
dsTest.Tables["Test"].Columns.Add("Enum2", typeof(ProcessWindowStyle));
Если же делать типизированный DataSet
, т.е. добавить в проект DataSet
, как отдельный класс (наследник обычного DataSet
), и создать нужные таблицы в конструкторе (Dataset Designer), то при попытке просто прописать пользовательский тип DataType
в конструкторе, получится ошибка:
На самом деле, имена типов данных нужно вводить полностью, вместе с их пространствами имен. Т.е., при условии, что пространство имен программы, например tmpDataSet
, то тип testenum
нужно указывать как tmpDataSet.testenum
(а тип ProcessWindowStyle
, соответственно, как System.Diagnostics.ProcessWindowStyle
)
Вещь, вроде бы довольно очевидная, если приглядеться (стандартные типы из списка прописываются точно также):
Но почему-то прямо нигде не озвученная, что странно.
C#, Регулярное выражение для IP-адреса (v4)
Искать айпишники, например, в логах.
Для десятичной (полной) записи:
(25[0-5]|2[0-4]\d|[01]?\d\d?)(\.(25[0-5]|2[0-4]\d|[01]?\d\d?)){3}
Второе, должно поддерживать восьмеричную, шестнадцатеричную, десятичную и смешанную запись:
(0[0-7]{10,11}|0(x|X)[0-9a-fA-F]{8}|(\b4\d{8}[0-5]\b|\b[1-3]?\d{8}\d?\b)|((2[0-5][0-5]|1\d{2}|[1-9]\d?)|(0(x|X)[0-9a-fA-F]{2})|(0[0-7]{3}))(\.((2[0-5][0-5]|1\d{2}|\d\d?)|(0(x|X)[0-9a-fA-F]{2})|(0[0-7]{3}))){3})
Второй мопед не мой, оставляю на всякий случай, чтоб два раза не вставать.
Протестировать можно здесь
Ну и тесты на C# (от Лехи)
Отсев 3: Росгвардия
Смотрю тут фильм, и внезапно замечаю.
Голосовать здесь: https://likeness.ru/blog/topic/190249/viktor_zolotov_pokhozh_na_nachalnika_okhrani_iz_filma_otsev.php#
Фразочка
Российская Инферния
Сходства: Первому игроку приготовиться!
ЛЛео Каганов vs Джеймс Холидей (персонаж фильма)
Голосовать здесь: https://likeness.ru/blog/topic/190205/lleo_protiv_gollivuda.php
Element PNK-000 Конь-пилятор с бензопилой
Автор rex_weblen@ljr
Он, кстати, еще переводит милый комикс Forest Hill, единственный, кстати, в рунете переводит, и поэтому не пропиарить просто не могу. А мне вот такого элемента (см. «Межлокальную контрабанду») сделал, по моему межлокальному эсхатологическому мутанту. За что ему почет и уважение. И знал бы он какую бурю породил в местном сообществе… Теперь у меня стадо коней-пиляторов, только отсканировать всех надо, рано или поздно покажу.
C#, Об анализе exceptions при вызове внешнего процесса.
Или отлавливаем нажатие клавиши «Отмена» в окне запроса UAC.
Вот однажды я писал небольшую утилиту, которая запускает любое приложение или командный файл (bat/cmd) от имени администратора. И мне в комментариях правильно намекнули, что я слишком грубо обрабатываю exceptions, которые могут случиться во время запуска внешнего процесса. Но вообще это хороший пример не только для конкретного случая, но и для подхода к обработке ошибок вообще. Кратко говоря — если вы предполагаете, что где-то может возникнуть ошибка, то есть два метода:
1. Предотвратить и обезвредить. К таким ошибкам, например, относится возможная недоступность файла для чтения/записи, или вообще его отсутствие, когда он нужен. Тогда лучше проверить, например, наличие файла, с помощью File.Exist()
перед операцией с файлом.
2. Отловить на этапе времени выполнения. Для этого в C# существуют try/catch
.
Нам нужен именно способ #2, поскольку мы не знаем и проверить заранее никак не можем, нажмет пользователь «Отмену» в окне запроса, или нет.
Изначально было сделано так, т.е. тут мы полагались на какой-то внутренний флаг, и от его состояния принимали решение, реагировать на ошибку или нет.
3. Но на самом деле нам нужно отследить конкретную ошибку, для соответствующей нашему случаю реакции на нее, а изначально, мы этого не сделали, полагаясь на авось (внутренний флаг).
Как известно, в .NET ошибки времени выполнения распределены по классам. Есть общий класс — Exception
, в который попадают все ошибки времени выполнения, и есть конкретные классы для обработки определенных ошибок. Иерархия обработки следующая: «от конкретных к общему». Т.е. сначала (если мы хотим их обработать), указываются конкретные ошибки, а потом можно, но не обязательно указать общий обработчик.
Конкретно при запуске внешних процессов могут возникнуть следующие виды ошибок:
ArgumentNullException
(на самом деле в зависимости от OS но может не сработать, сработает следующий)
ObjectDisposedException
FileNotFoundException
— он нам и нужен
Win32Exception
PlatformNotSupportedException
На самом деле, практически всегда срабатывает класс ошибок Win32Exception
, остальные или очень редки, или их можно охарактеризовать одним словом — случился ой, дальше работать не будем.
Win32Exception
Для начала подключим нужный namespace
:
using System.ComponentModel;
А теперь примемся за анализ. На самом деле, у каждой Win32-ошибки имеется внутренний код. В C#-exceptions он сохраняется в переменной NativeErrorCode
. Т.е для решения нашей задачи, нам в конструкции try/catch
достаточно отловить конкретный код ошибки. Для нажатия клавиши «Отмена» в окне UAC, это будет код 1223
, «Операция отменена пользователем».
1. Сначала надо отловить ошибку типа Win32Exception
и проанализировать значение NativeErrorCode
.
2. Если NativeErrorCode == 1223
, то не предпринимаем никаких действий.
3. Если NativeErrorCode
другой, оповещаем пользователя об ошибке.
4. Если сработало исключение другого типа (не Win32Exception
), то аналогично предыдущему пункту — оповещаем пользователя об ошибке.
//... try { Process.Start(psi); } catch (Win32Exception wex) { if (wex.NativeErrorCode == 1223) //нажали "Отмену" в окне UAC { return true; } else //какой-то другой Win32 Error { ErrorMessage = wex.NativeErrorCode.ToString() + " " + wex.Message; return false; } } catch (Exception ex) //какой-то другой Exception { ErrorMessage = ex.Message; return false; } //...
Код полностью здесь
1. Коды ошибок Win32 (Краткое пояснение и полный список кодов, англ., MSDN)
2. Нужный код ошибки (Отменено пользователем)
1. Репозиторий на GitHub
2. Скачать
3. Заметка об утилите Копия