Слава — Украине,
Вова — России,
Саша — Беларуси.
А Моисей Соломонович Кац, таки Израилю.
C# и автозагрузка из реестра.
Оказывается, несколько моих рабочих софтин тихо отвалились, пока пользователи молчали, как партизаны (обычное дело). Теперь я стал работать в Win 7, где не был вырван с корнем UAC и вся виндовая система безопасности. Мне-то хватало Comodo, а что-то действительно важное крутилось на Linux. Ну зато нашел баги. И приобрел опыт.
Я почему-то, если нужна была автозагрузка из реестра, пытался прописываться в HKEY_LOCAL_MACHINE
(Software\Microsoft\Windows\CurrentVersion\Run
), а для того, чтоб туда прописаться, нужны права администратора.
Чтоб сделать правильно, надо прописываться не в HKEY_LOCAL_MACHINE
, а в HKEY_CURRENT_USER,
т.е. в куст реестра, ответственный за настройки текущего пользователя, что и вообще правильно, и админских прав не надо.
Написал простенький класс, отвечающий за автозагрузку через Реестр. Код достаточно тривиален, исходник маленький, думаю, можно разобраться без дополнительных пояснений.
1. Autorun.Add()
— добавляет программу в автозагрузку Реестра.
2. Autorun.Remove()
— удаляет программу из автозагрузки Реестра.
3. Autorun.Check(bool FixPath)
— проверяет статус, если FixPath установлен в True, то исправляет путь к приложению на новый, если приложение было ранее добавлено в автозагрузку, но местоположение экзешника изменилось.
4. Autorun.Switch ()
— изменяет автозапуск на противоположный (т.е., если программа в автозагрузке — удаляет, если нет — добавляет)
C#, запуск программы от имени администратора
Или как я сделал недо-sudo для Windows 7
У меня для работы понаписана куча батников для всяких мелких задач: перенастройки сетевых соединений, включения/отключения устройств и т.д. Некоторые команды требуют повышения уровня доступа до администратора, потому батники отказались на семерке работать.

Поскольку работаю я в основном в консоли, да и рабочий стол захламлять не охота, то от создания кучи ярлыков на нужные батники я отказался. Про штатный runas
в Windows я знаю, но он меня тоже не устроил. Хотелось, чтоб как в новом Far Manager’е — при необходимости выполнить операцию от имени администратора, выскакивало стандартное окошко виндового UAC, запрашивалось подтверждение и выполнялась нужная команда.
В общем решил я написать быстренько свой недо-sudo на C#, благо действительно получилось быстро и удобно.
Способ, вполне штатный, произвести такое дело с помощью C# есть, но о нем ближе к концу. Пока скажу, что для запуска внешнего процесса нужен будет полный путь к исполняемому файлу, а прописывать его каждый раз очень сильно влом, потому батники пусть лежат в каталоге, доступном в PATH
, а нам придется немного «прикинуться операционкой» и вести себя как она. А операционка действует просто. Если просто введена команда без расширения, то она ищет сначала в текущем каталоге, а потом в каталогах из переменной PATH
файл с расширением .com, .exe, .bat, .cmd
— нашла, значит выполняет.
Так и будем делать.
1. Заводим два массива, со списком расширений и для хранения списка директорий, в которых будем искать файл:
private static string[] FindDirs = null;
private static string[] Extensions = new string[] {"com","exe","bat","cmd"};
2. Функцию для получения списка каталогов из PATH
Копия
3. Функцию, которая будет собирать список каталогов, в которых будет производиться поиск. Не буду здесь ее приводить, она просто добавляет текущую директорию (с помощью Directory.GetCurrentDirectory()
) и список, полученный на предыдущем шаге в массив. См. в классе FindApp
функцию GetFindDirs()
4. Понадобится функция, определяющая по расширению, является ли файл исполняемым. Она тоже довольно проста. См. ссылку выше private static bool IsExecutable(FileInfo fi)
. Структуру FileInfo
сформируем на шаге поиска далее. Она в цикле сравнивает расширение файла, если оно указано, со списком расширений исполняемых файлов.
5. Функцию, которая ищет файл, если расширение не задано private static string FindNoExt(string path, string FileName)
Она проверяет, заканчивается ли путь к директории символом \, в цикле подставляет расширения и проверяет наличие файла по указанному пути с помощью File.Exists()
. Если файл найден — возвращает полный путь, если нет — null
.
Функция Find (string Command)
в классе FindApp
1. Получаем список каталогов, в которых будем искать, с помощью ранее описанной функции GetFindDirs()
2. Создаем класс FileInfo
:
FileInfo fi = new FileInfo(Command);
3. Проверяем, был ли задан путь к исполняемому файлу. Тут надо остановиться немного подробнее. Если в команде Command
путь задан не был, то свойство DirectoryName
класса FileInfo
будет содержать текущий каталог, что никак нам не поможет. Поэтому, надо проверить, был ли задан полный путь. Проще всего это сделать, проверив, содержала ли команда Command символ \:
if (Command.Contains("\\"))
...
4. Если каталог указан, то проверяем, указано ли расширение. Тут можно воспользоваться свойством Extension
структуры FileInfo
. Оно будет пустым, если расширение не задано. Если расширение задано, то проверяем, является ли файл исполняемым, и в случае, если да — возвращаем его полный путь. Если расширение не указано, пытаемся найти в каталоге исполняемый файл с помощью ранее созданной функции FindNoExt
.
5. Если каталог не задан в команде, то выполняем шаг 4 для каждого каталога из списка поиска, пока не найдем файл. Если файл так и не будет найден, значит возвращаем null
.
Выполнение программы организовано в отдельном классе RunApp
Сначала мы должны проверить, а нет ли прав администратора у нас уже. Для этого надо будет подключить пространство имен using System.Security.Principal;
Сама проверка вынесена в отдельную функцию:
public static bool IsAdmin() { WindowsPrincipal pricipal = new WindowsPrincipal( WindowsIdentity.GetCurrent()); return pricipal.IsInRole( WindowsBuiltInRole.Administrator); }
Подключаем пространство имен using System.Diagnostics;
public static bool Excecute(string path, string parameters) { ProcessStartInfo psi = new ProcessStartInfo(); psi.FileName = path; psi.Arguments = parameters; bool admin = IsAdmin(); if (!admin) { psi.Verb = "runas"; } try { Process.Start(psi); } catch (Exception ex) { if (admin) //админские права уже были, что-то испортилось { ErrorMessage = ex.Message; return false; } //иначе может быть просто нажали отмену в UAC } return true; }
Сначала формируем структуру ProcessStartInfo
из пути к программе и параметров. Далее проверяем наличие админских прав, если их нет, то указываем системе, что процесс-программу нужно запустить с правами администратора с помощью psi.Verb = "runas";
Далее запускаем процесс.
Проверки, правда, минимальные. И наверняка, кривые.
Ну тут вообще все элементарно. Это консольное приложение, при запуске которого ему передаются в командной строке параметры. Первый — имя вызываемой команды, остальные — ее параметры. См. здесь
C# Получение списка каталогов из переменной окружения PATH
Простая задачка, решаемая в две строки.
1. Получаем значение переменной окружения PATH
:
string path_var=Environment.GetEnvironmentVariable("PATH");
2. Пути в PATH разделяются символом ; (точка с запятой), соответственно, можно получить массив со списком директорий с помощью функции
Split()
:
string[] dirs = path_var.Split(';');
Единственное что нужно не забыть перед использованием — последний элемент массива может оказаться пустым, если PATH
заканчивается точкой с запятой, и между элементами в переменной PATH
могут быть пробелы, надо не забыть сделать Trim()
перед использованием значения из массива.
C#, динамическая NotifyIcon с наложением изображения.
Спрашивают, а возможно ли совместить пример с динамически обновляемой NotifyIcon Копия с примером про наложение изображения Копия, чтобы получить что-то типа такого же эффекта, который делает иконка сетевого соединения в Windows 7 при разрыве соединения?


Можно, только, на мой взгляд, в Windows это все-таки сделано просто выводом разных иконок в случае отсутствия или присутствия соединения с сетью, просто в первом случае к иконке пририсован восклицательный знак. Вообще динамической генерацией иконок злоупотреблять не стоит, если уж делать, то делать там, где это действительно нужно. Надо помнить, что для корректной работы с динамически генерируемыми иконками, приходится тащить за собой функцию WinAPI, хоть и всего в одном месте.
Но если очень хочется, то можно.
Для разнообразия будем считать, что основное изображение у нас уже в формате ICO:

А накладываемое должно быть PNG с прозрачностью. Накладывать будем желтый треугольник с красным восклицательным знаком:

В данном случае, размеры накладываемого изображения я прикидывал исключительно методом тыка, на 14 пикселях особо не разгуляешься.
— Заводим необходимые переменные:
Icon TargetIcon = Properties.Resources.target;
Bitmap TargetBitmap = null;
Bitmap ResultBitmap = null;
Bitmap OverlayBitmap = null;
IconConverter icconv = null;
И не забываем экспортировать функцию DestroyIcon
из user32.dll
[1]:
[System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)] extern static bool DestroyIcon(IntPtr handle);
— Конвертируем иконку TargetIcon
в Bitmap
. Делается это при помощи класса IconConverter
:
//convert icon to bitmap (target)
icconv = new IconConverter();
TargetBitmap = (Bitmap)icconv.ConvertTo(TargetIcon, typeof(Bitmap));
— Достаем из ресурсов накладываемое изображение и далее поступаем, как в [2]:
//overlay bitmap OverlayBitmap = Properties.Resources.overlay; //create result bitmap ResultBitmap = new Bitmap(TargetBitmap.Width, TargetBitmap.Height, PixelFormat.Format32bppArgb); //create Graphics Graphics graph = Graphics.FromImage(ResultBitmap); graph.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceOver; //Draw overlay images graph.DrawImage(TargetBitmap, 0, 0); graph.DrawImage(OverlayBitmap, 0, TargetBitmap.Height-OverlayBitmap.Height); //result =) pbTarget.Image = TargetBitmap; pbOverlay.Image = OverlayBitmap; pbResult.Image = ResultBitmap;
Когда надо, преобразуем ResultBitmap
, где хранится иконка с наложенным изображением, обратно в Icon
, и присваиваем ее соответствующему свойству компонента NotifyIcon
:
IntPtr hIcon = ResultBitmap.GetHicon();
System.Drawing.Icon niicon = System.Drawing.Icon.FromHandle(hIcon);
niTest.Icon = niicon;
DestroyIcon(niicon.Handle);
Вот что получилось:

1. C#, динамическая NotifyIcon, иконка в области уведомления Копия
2. C#, WindowsForms, наложение изображений, изменение размеров изображения. Копия
Виндоофисные мелочи.
Заметка от склероза.
Команда shutdown
.
Завершение работы:
C:\Windows\System32\shutdown.exe /s /t 10 /c "I am shutdown"
Перезагрузка:
C:\Windows\System32\shutdown.exe /r /t 10 /c "I am reboot"
Отмена:
C:\Windows\System32\shutdown.exe /a
Архив с готовыми ярлыками, чтоб кидать сразу на рабочий стол
Справка по команде
Где-нибудь в PATH должен лежать exiftool.exe
Батник из одной строки:
exiftool -all= -overwrite_original %1
Использовать:
killexif.bat *.jpg
Ссылка на SFX-архив с exiftool и батником
1. Идем в Сервис —> Настройка
2. Жмем кнопку Клавиатура в появившемся окне:

3. В Категории выбираем Макросы
4. В соседнем списке выбираем нужный макрос
5. Жамкаем на поле Новое сочетание клавиш
6. Нажимаем что нужно
7. Все сохраняем

Еще метеошного и ностальгического

А это рабочее место техника-метеоролога (непосредственного наблюдателя) на локальной метеостанции. Два крайних слева прибора не знаю. Нижний видел еще совсем малым, а верхний это уже какой-то новый. Поеду еще раз туда, обязательно спрошу. А два больших шкафчика — это пульты ИВО (измерителя высоты облаков). Что-то типа маломощного радара, определяющего (спасибо, Кэп) высоту облаков. Это «терминалы», правда аналоговые абсолютно. «Сервер» снаружи, несколько напоминает стиральную машинку, поставленную на «спину». Крышка, защищающая линзу, кстати, открывалась с пульта удаленно, что на меня мелкого производило впечатление, сравнимое с посещением Зоны 51!
На заднем плане шкафчик с треугольными створками. Там как раз тот самый ртутный столб живет %)
Метеошное. Ртутный столб.

По клику доступен крупный вариант
Некоторые из сетевых знакомых спрашивают, а существует ли ртутный столб в самом деле, или это некая метафора, отсылка к истории науки. Ну типа да, при динозаврах ртутные столбы были, а в 20-21 веке они уже не существуют. Даже есть парочка, которых я в шутку называю сектой неверующих в ртутный столб, потому что они не верят в него. Один москвич, второй иностранец. Второй хоть мотивирует это как-то, типа «ртуть пиздец пиздец опасно террористы в поваренной книге анархиста написано про ртуть», будто это не ртутный столб, а полониевый ледоруб с ручкой из уранового лома.
Так вот, ОН СУЩЕСТВУЕТ. Фотография сделана в 21 веке мною лично.
фразочка
Червионат Мора
C#, WindowsForms, наложение изображений, изменение размеров изображения.
Задали вопрос, а можно ли в C# программными средствами наложить 2 изображения друг на друга. И даже сами потом предложили какое-то жуткое решение с привлечением WinAPI, и чуть ли не ассемблера со злыми духами.
На самом деле, задача вполне себе решается стандартными средствами.
Итак, предположим, что у нас есть 2 изображения, оба они PNG с прозрачностью, и лежат в ресурсах нашего приложения. Например, флаг:

и герб:

под именами, соответственно Properties.Resources.flag
и Properties.Resources.trizub_small
Сначала сделаем из изображений два объекта Bitmap
:
//Берем целевое изображение
Bitmap TargetBitmap = Properties.Resources.flag;
//Берем накладываемое изображение
Bitmap OverlayBitmap = Properties.Resources.trizub_small;
Теперь надо создать результирующее изображение (оно будет пока пустым) нужного размера:
//Создаем результирующее изображение (пока пустое) Bitmap ResultBitmap = new Bitmap(TargetBitmap.Width, TargetBitmap.Height, PixelFormat.Format32bppArgb);
Откуда взяли высоту и ширину — понятно, третий параметр PixelFormat
берется в зависимости от исходных изображений. Желательно, чтоб они совпадали по глубине цвета, иначе получится некрасиво, может потеряться прозрачность или произойти еще какая-нибудь бяка. Я сделал 2 изображения с прозрачностью (ARGB) и глубиной цвета 32 бита.
Теперь нужно создать объект Graphics
, который и будет заниматься совмещением изображений. Раз мы будем рисовать в пустом Bitmap ResultBitmap
, то и объект Graphics
создаем из него, воспользовавшись методом Graphics.FromImage()
:
//Создаем объект Graphics из результирующего изображения
Graphics graph = Graphics.FromImage(ResultBitmap);
Далее объект graph
надо настроить:
//настраиваем метод совмещения изображений graph.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceOver;
Если вместо SourceOver
установить SourceCopy
, то потеряется вся прозрачность у накладываемого изображения, и будет некрасиво:

Далее, производим отрисовку:
//рисуем основное изображение
graph.DrawImage(TargetBitmap, 0, 0);
//рисуем накладываемое изображение
graph.DrawImage(OverlayBitmap, (TargetBitmap.Width-OverlayBitmap.Width)/2,
(TargetBitmap.Height-OverlayBitmap.Height)/2,
OverlayBitmap.Width,OverlayBitmap.Height);
Думаю, откуда взяты все координаты и размеры, понятно.
Осталось только присвоить Bitmap'ы PictureBox'ам
Тут тоже ничего сложного и сверхъестественного нет.
Чтоб два раза не вставать, возьмем полученное выше изображение и уменьшим его:
//задаем новые размеры
int NewWidth = ResultBitmap.Width / 2;
int NewHeight = ResultBitmap.Height / 2;
//Настраиваем PictureBox для вывода уменьшенного изображения
pbResize.Size = new Size(NewWidth, NewHeight);
Создадим новый Bitmap
для будущего уменьшенного изображения:
//создаем новый Bitmap для измененного изображения
Bitmap ResizeBitmap = new Bitmap(NewWidth,
NewHeight);
Опять создадим объект Graphics
, который будет заниматься отрисовкой:
//создаем объект Graphics, который будет изменять размер
Graphics ResizeGraph = Graphics.FromImage(ResizeBitmap);
Поставим повыше качество изображения:
//ставим высокое качество
ResizeGraph.InterpolationMode =
System.Drawing.Drawing2D.InterpolationMode.High;
И делаем отрисовку:
//рисуем изображение с измененным размером
ResizeGraph.DrawImage(ResultBitmap, 0, 0, NewWidth, NewHeight);
В заметке я пропустил вывод изображений в PictureBox'ы
, но он и так очевиден (в исходнике есть).
Вот, что получилось:

C#, WindowsForms. Автоматическая выгрузка и загрузка содержимого контролов на форме. В объект или запись DataSet.
Решил побороть еще одно узкое место в коде, которое приводит к невероятному количеству ручного кодинга, а именно — загрузка данных из записи DataSet
или произвольного объекта в форму, для изменения/ввода данных пользователем, а потом обратная выгрузка.
Вообще, долго думал и гуглил, как сей неприятный процесс автоматизировать, но почему-то везде предлагали либо встроенные, либо сторонние генераторы кода, т.е. ответ был «генерируй!». Но меня такой ответ не устроил, неужто, никак нельзя все это более-менее автоматизировать, не прибегая к внешним инструментам.
Оказывается, можно. Все инструменты для этого есть — есть System.Reflection
, через инструменты данного пространства имен можно получать имена свойств или полей нужного класса, а также тип данных, и есть методы для поиска нужных контролов на форме, чтобы загрузить или сохранить данные в/из объекта.
Правда, совсем универсальный класс, для загрузки данных из всех возможных контролов, во все возможные поля условного объекта не получился, но на практике это и не надо.
Опять же, тут будет краткое рассуждение, а пример кода в конце.
Основные компоненты это:
— текстовые поля, куда можно ввести либо строку, либо число (фильтрацию ввода оставим форме)
— checkbox’ы, хранящие булево значение
— radiobutton’ы/переключатели — ограниченный выбор из определенного набора вариантов.
От этой печки танцевать и будем, если понадобится что-то еще — это будет уже проще свести к этим трем типам, или, немного изменив код, добавить конкретный случай в класс-прослойку.
Тут уже придумали все за нас, есть прекрасный тип Enum
, который, собственно, для этого и предназначен. Например, нам надо будет хранить тип соединения с сетью. Можно сделать вот такое перечисление:
public enum NetConnectionType { NoProxy = 0, SystemProxy = 1, ManualProxy = 2 }
Это единственный наглый момент во всем примере — контролы придется называть не абы как, а по правилам, впрочем, правила всегда можно переопределить, и сделать удобные вам. Я делал удобно для себя.
Для
TextBox
‘ов и CheckBox
‘ов правила такие: сначала идет префикс txt
или chk
, далее — название поля в записи таблицы DataSet
или название свойства объекта, например chkAutorun
или txtUserName
. В классе, соответственно, должны быть поля bool Autorun
или string UserName
.
Для радиокнопок (переключателей) имя формируется по следующему принципу: префикс rb+НазваниеСвойства+ЗначениеВEnum
, т.е., например, радиокнопка, указывающая на прямое соединение, будет называться rbConnectionNoProxy
Думаете, сложно и длинно? Ну, может быть, только сталкиваешься с этим потом один раз, когда моделируешь форму.
Получение списка радиокнопок и поиск контрола на форме Копия
Получение значения Enum
из состояния RadioButton
:
private string GetEnumValFromRb(string PropName) { string EnumVal = string.Empty; string rbName = "rb"+PropName; foreach (RadioButton rb in RadioButtons) { if (rb.Checked) { if (rb.Name.StartsWith(rbName)) { EnumVal = rb.Name.Substring(rbName.Length); } } } return EnumVal; }
фразочки
Багоспасаемая держава
— За что Нео признали в Матрице экстремистом?
— За антисмитизм!
C#, WindowsForms — найти все переключатели (RadioButtons) на форме.
Если нам нужно найти контрол на форме, зная его имя, то все решается довольно просто — у массива контролов Controls
есть метод Find
, который найдет нам что нужно, если указать правильное имя контрола:
private Control FindControl(string ControlName, Form form) { Control ctrl = null; Control[] buf = form.Controls.Find(ControlName, true); if (buf.Length == 0) return null; if (buf.Length > 1) return null; ctrl = buf[0]; return ctrl; }
Вот тут уже сложнее, особенно с переключателями. Они обычно сидят на форме в контейнерах, например в GroupBox'ах
, и функция Find
тут не поможет. Необходим другой подход, если мы хотим получить список контролов определенного типа. А именно — надо сделать рекурсивную функцию поиска. Кто боится рекурсии и связанных с ней переполнений, скажу, что ничего страшного нет.
Мне удалось уронить студию на 5 000 однотипных компонентов, а подобное число компонентов вряд ли может быть в реальности, только если вы не радиокнопочный маньяк 🙂
Функция такая вот:
private ListFindAllRadiobuttons(Control.ControlCollection collection) { List result = new List (); foreach (Control ctrl in collection) { if (ctrl.HasChildren) { result.AddRange(this.FindAllRadiobuttons(ctrl.Controls)); } if (ctrl is RadioButton) { result.Add((RadioButton)ctrl); } } return result; }
Т.е. если мы просто наткнулись на переключатель, при переборе контролов из массива Controls, то добавляем переключатель в массив, если же, мы наткнулись на контрол-контейнер (ctrl.HasChildren == true
), то вызываем функцию перебора массива уже для массива Controls
контейнера.
C#. О конфигах и сохранении/загрузке свойств объекта, часть 2
В прошлой части Копия я рассказывал, как с помощью инструментов из пространства имен System.Reflection
, можно сохранить свойства объекта, например, в таблицу DataSet
, или наоборот, загрузить из DataSet
данные в свойства соответствующего объекта. Таким образом, решалась проблема автоматизации работы с конфигурационными файлами.
Есть способ еще более уменьшить количество кода, воспользовавшись стандартным механизмом .NET Framework — сериализацией. Сериализация, это, по рабоче-крестьянски говоря, именно что сохранение состояния объекта (он же пафосно называется «экземпляром класса») в некий передаваемый формат. Доскональное объяснение, что это такое, в статью не влезет, потому оставим.
Итак, переходим к сериализации.
В .NET Framework сам себя класс сериализовать не может, точнее, сериализовать-то может, а вот десериализовать — нифига. Класс и его экземпляр, получается, как Штирлиц с раненой радисткой Кэт, передать могут, а обратно нет, без дружественной помощи.
Поэтому, придется изобретать выход, в котором классов будет больше, а кода меньше, чем в предыдущем случае
Выход в том, чтобы создать класс, непосредственно хранящий конфигурацию, и класс-менеджер, который возьмет на себя работу над сериализацией, десериализацией и другим, например, назначением значений по умолчанию.
Итак, создадим класс-хранилище, вот такой вот, например:
[Serializable] public class AppSettings { public string DataUrl { get; set; } public FormatType DataFormat { get; set; } public string IPColumn { get; set; } public string FieldSeparator { get; set; } public string FlagColumn { get; set; } public string TrueValue { get; set; } public string FalseValue { get; set; } public bool LoadUpdate { get; set; } public AppSettings() { } }
Если нужно, чтобы класс сериализовался, то перед описанием класса нужно обязательно установить атрибут «сериализуемый»:
[Serializable]
Далее нам надо выбрать сериализатор, т.е. набор методов, который будет данные нашего класса во что-нибудь преобразовывать, или наоборот, восстанавливать, загружая ранее сохраненные значения.
Ну, раз уж в прошлый раз, мы выбирали XML, то и сейчас я буду сериализовывать класс в XML
Сериализатор XML в .NET пропускает все приватные поля и свойства класса. На мой взгляд, это больше хорошо, чем плохо, если сохранять класс, хранящий набор параметров конфигурации — приватные все равно не нужны.
Если какое-то публичное свойство не надо сериализировать, т.е. в нашем случае, сохранять в конфиг, то такому свойству надо установить атрибут [XmlIgnore]
, для публичных полей устанавливается атрибут [NonSerialized]
.
Например:
[XmlIgnore]
public string DataUrl { get; set; }
Последняя особенность сериализации в XML — сериализируемому классу необходим конструктор без параметров, причем, практически выявлено, в этом конструкторе лучше вообще ничего не делать, особенно того, что может привести к ошибкам времени выполнения. Иначе получите гадскую невыявляемую ошибку, поскольку в отладке у вас будет всякая фигня, кроме того, чего нужно.
Я так понимаю, конструктор без параметров вызывается во время XML-сериализации, и наверняка, в нем что-то можно и нужно делать, но пока я не нашел, как и где это подробно расписать.
Само дерево жужжать не может
Значит, кто-то тут жужжит
(Вини-Пух)
Это самая гадская особенность сериализации в .NET, а именно, если в прошлом случае могли параметры конфига, и функции для их сохранения-загрузки объединить в один класс, то в подходе с использованием сериализации не можем:
this = (Data)readerRr.Deserialize(fileRr);
this - переменная только для чтения, по крайней мере до .NET 4.0 включительно.
И такой подход считается «плохим дизайном», хотя на мой нескромный взгляд, плохой дизайн — это разносить части одного и того же по разным классам.
Но раз уж надо, значит надо. Делаем класс-менеджер:
Далее такой условный класс-менеджер с возможностью сохранения и загрузки:
Читать далее
Киберфорум
Сериализация в XML. XmlSerializer
Навел на мысль steinkrauz@ljr
L.O.S.A.I.G!
Офигенная эмо-панк группа из моего города.
Тащемта, были даже на дребедне нашего города, было холодно и неприятно (от погоды), но вообще парни пиздатые. Особенно вокалист XD
Но они, как и все нормальные люди, уезжают. Жалко, но придется.
Прямая ссылка: кликать сюда
С днем настоящего карельского флага

В этом году совпавшим еще и с летним Солнцестоянием
Я, как всегда немного опаздываю, потому что у меня график в интернетах абсолютно не совпадает с планетой 🙂
Окончательно закрыли сайт Hexproject’а
На сайте был старый движок, бесплатные хостинги какашка, да и весь кодинг (даже с приставками «быдло-» и «около-«) можно выложить на Гитхаб, и не надо что-то отдельное изобретать.
Виртуальная сим-карта для регистрации на сервисах, требующих номер телефона.

Мои друзья делают замечательный проект, способствующий сохранению анонимности в Интернете — virtualsim.net. На этом сайте вам за небольшую сумму зарегистрируют номер телефона на год, на который можно будет регистрироваться на всяких сайтах и сервисах, требующих номер телефона (Telegram, Vkontakte, OK.RU и т.д.)
Мы вот таким образом обзавелись телеграм-каналом и страницей во Vkontakte.
У ребят огромная база данных (на несколько тысяч номеров), есть возможность выбрать страну. В настоящий момент доступны Украина, Россия, Казахстан, Латвия. При офигенно качественном и важном сервисе, избавляющем, наконец, от мобильного рабства, цены вполне демократичны: Минимальный тариф за номер — 5$ в год для некоммерческой деятельности, например, регистрации страницы в VK, для коммерческой деятельности подороже, но вполне терпимо. Если честно, дешевле я не нашел. Постоянным клиентам предоставляются скидки. Впрочем, дублировать весь прайс в данной заметке я не буду. Если вас заинтересовал сервис, пройдите по ссылке ниже
VIRTUALSIM.NET ОСТАВАЙСЯ АНОНИМНЫМ!
DetecTOR, утилита, определяющая, относится ли IP к сети TOR
Написана изначально была аж в 2013 году и довольно кривовато, но по многочисленным просьбам нашего дорогого зрителя, была переделана, с подробными объяснениями по поводу «как», «что», «где» и «куда».
Раз это приняли в качестве курсовой первокурсника, то можно и опубликовать. Тем более, на этой утилите я и сам экспериментировал, и теперь это некий пример для бывших и будущих нескольких заметок из серии «О конфигах» и всяческой там автоамтизации рутинных дел — сбора данных с форм, или сохранения конфигурационных файлов.
Выглядит главное окно вот так:

Чтоб два раза не вставать.
readme.txt
Смотреть исходники (на GitHub)
Скачать программу (Win32) c GitHub
Открытый отчет 2017-2018 обновление
Теперь больше не должны 10 $, нам как-то быстро за день надонатили, после публикации открытого отчета, что мы даже чихнуть не успели.
Благодарим неравнодушных людей. Зала славы и публикации имен, естественно, не будет. Как и открытых реквизитов для доната (до сентября)