Архивы рубрики: Ассемблер

Сборки в .NET Framework

Сборки в .NET Framework
Сборка (assembly) — это логическая единица, содержащая скомпилированный код для .NET Framework.
Сборка (assembly) — это полностью самодостаточный и, скорее, логический, нежели физический элемент. Это значит, что он может быть сохранен в более чем одном файле (хотя динамические сборки хранятся в памяти, а вовсе не в файлах). Если сборка хранится в более чем одном файле, то должны быть один главный файл, содержащий точку входа и описывающий остальные файлы.
Следует отметить, что одна и та же структура сборки используется как для исполняемого кода, так и для кода библиотек. Единственное реальное отличие исполняемой сборки заключается в том, что она содержит главную точку входа программ, тогда как библиотечная сборка — нет.
Важное свойство сборок состоит в том, что они содержат метаданные, описывающие типы и методы, определенные в ее коде. Помимо этого сборка хранит в себе метаданные описывающие ее саму. Эти метаданные, хранимые в области манифеста, позволяют выполнить проверку номера версии сборки и ее целостность.
Для инспектирования содержимого сборки, включая манифест и метаданные,
может использоваться Windows-утилита iddasm.

Тот факт, что сборка содержит метаданные программы, означает, что приложение или другие сборки, которые вызывают код данной, не нуждаются в обращении к реестру или любому другому источнику данных, чтобы узнать, как конкретную сборку следует использовать. Это существенный прорыв по сравнению со старым способом работы COM, когда GUID-идентификаторы компонентов и интерфейсов необходимо быть извлекать из реестра, а подробности методов и свойств в некоторых случаях читать из библиотеки типов.
Хранение данных в трех различных места приводило к очевидному риску получить несинхронизированные части, что исключало возможность использования данного компонента другим программным обеспечением. Что касается сборок, то здесь риск подобного рода исключен, потому что все метаданные хранятся вместе с исполняемыми инструкциями программы. Следует отметить, что несмотря на то, что сборки могут храниться в нескольких файлах, не возникает проблемы синхронизации, поскольку в том же файле, где находится точка входа, хранится и информация о содержимом остальных файлов. То есть даже если один из них подменить или испортить, это немедленно будет обнаружено, и всей сборке будет запрещено загружаться на исполнение. Сборки бывают двух видов: разделяемые и приватные.
Приватные сборки
Это простейший тип сборок. Обычно они подставляются с определенным программным обеспечением и предназначены для использования только в его составе. Обычный сценарий получения приватной сборки — это когда вам поставляется приложение в виде исполняемой программы и множества библиотек, кот которых может быть использован только этим приложением.
Система гарантирует, что приватные сборки не будут использоваться другим программным обеспечением, потому что приложение может загружать только приватные сборки, находящиеся в той же папке, в которой находится и главная исполняемая программа, которая их загружает, либо во вложенных папках.
Поскольку обычно можно рассчитывать но то, что коммерческое программное обеспечение всегда инсталлируется в свой собственный каталог, значит нет опасности того, что одни программный пакет перепишет, модифицирует или непреднамеренно загрузит приватные сборки, принадлежащие другому пакету. Поскольку приватные сборки могут быть использованы только тем пакетом программного обеспечения, для которого они предназначены, вы имеете возможность управлять тем программным обеспечением, которое их использует. Отсюда уменьшается необходимость в некоторых предосторожностях для обеспечения безопасности, поскольку нет риска, например того, что какое-то коммерческое программное обеспечение перепишет ваши сборки их новыми версиями (за исключением тех случаев, когда программное обеспечение специально разработано для нанесения определенного вреда).
Не существует также проблемы коллизии имен. Если окажется, что классы в вашей приватной сборке имеют уже имена, что и классы в чьей-то чужой приватной сборке, то это не имеет значения, поскольку каждое приложение будет в состоянии видеть только один набор собственных приватных сборок.
Поскольку приватная сборка полностью самодостаточна, процесс ее развертывания весьма прост. Вы просто помещаете соответствующий файл (или файлы) в соответствующую папку системы (никакие записи в реестр не потребуются). Этот процесс известен как инсталяция с нулевым воздействием.

Разделяемые сборки
Далее рассмотрим разделяемые сборки, которые более универсальны и интересны с точки зрения реализации. Назначение разделяемых сборок — быть библиотеками общего применения, которые могут использоваться любым другим приложением. Так как любое приложение может получить доступ к сборке, то возникает вопрос безопасности, а именно такие вопросы:
Коллизия имен (возможен такой вариант что ваша сборка использует типы с теми же именами, что используются в разделяемой сборке).
Вопрос совместимости.
Решением этих проблем является размещение разделенных сборок в поддереве файловой системе (GAC — global assembly cache) — глобальном кеше сборок. В глобальный кеш разделяемые сборки нужно инсталировать, а не просто копировать как в случае с файловой системой. Процесс может быть реализован массами утилит.

 

Транслитер на C# (Csharp)

Транслитер на C# (Csharp)
Написать эту статью меня натолкнул вопрос на форуме.
Задача — написать транслитер на C# (Csharp).
Длря решения этой задачи воспользуемся таким чудом C# (Csharp), как словари (Dictionary). Стоит отметить, что словари появились в версии .NET Framework 2.0.. Dictionary представляет собой набор данных связанных как ключ-значение. При обьявлении словаря следует указывать типы с которыми будет работать словарь. Например:
Dictionary dict = new Dictionary();
Обьявляем словарь который будет работать с типами String.
Рассмотрим уже на практике добавление параметров в словарь. Для этого создадим новый проект в Visual Studio 2005 и положим на форму два компонента TextBox: textBox1 и textBox2. В первый будем вводить русский текст, во вротом будем получать текст на транслите.

Обьявляем наш словарь:
Dictionary words = new Dictionary();
Теперь добавим наши значения русских букв, и их аналоги на транслите. Для этого используем метод Add(string, string):
words.Add(«а», «a»);
words.Add(«б», «b»);
..
Этот код можно добавить после InitializeComponent().
Дальше нужно написать код замены букв с использованием Dictionary. Сделаем что б при вводе текста в первое поле ввода, во втором сразу отображался аналог текста, но на транслите. Для этого обрабатываем событие TextChanged нашего textBox1:
string source = textBox1.Text;
foreach (KeyValuePair pair in words)
{
source = source.Replace(pair.Key, pair.Value);
}
textBox2.Text = source;
Код довольно простой, мы получаем строку которую содержит textBox1, проходим по ней циклом и заменяем все что попало в наш словарь как ключ-значение. После цикла присваиваем textBox2 обработанную строку. Это позволяет получать транслит сразу после ввода русских букв в первом поле ввода.
Вот итоговый вариант:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace Transliter
{
public partial class Form1 : Form
{
Dictionary words = new Dictionary();

public Form1()
{
InitializeComponent();
words.Add(«а», «a»);
words.Add(«б», «b»);
words.Add(«в», «v»);
words.Add(«г», «g»);
words.Add(«д», «d»);
words.Add(«е», «e»);
words.Add(«ё», «yo»);
words.Add(«ж», «zh»);
words.Add(«з», «z»);
words.Add(«и», «i»);
words.Add(«й», «j»);
words.Add(«к», «k»);
words.Add(«л», «l»);
words.Add(«м», «m»);
words.Add(«н», «n»);
words.Add(«о», «o»);
words.Add(«п», «p»);
words.Add(«р», «r»);
words.Add(«с», «s»);
words.Add(«т», «t»);
words.Add(«у», «u»);
words.Add(«ф», «f»);
words.Add(«х», «h»);
words.Add(«ц», «c»);
words.Add(«ч», «ch»);
words.Add(«ш», «sh»);
words.Add(«щ», «sch»);
words.Add(«ъ», «j»);
words.Add(«ы», «i»);
words.Add(«ь», «j»);
words.Add(«э», «e»);
words.Add(«ю», «yu»);
words.Add(«я», «ya»);
words.Add(«А», «A»);
words.Add(«Б», «B»);
words.Add(«В», «V»);
words.Add(«Г», «G»);
words.Add(«Д», «D»);
words.Add(«Е», «E»);
words.Add(«Ё», «Yo»);
words.Add(«Ж», «Zh»);
words.Add(«З», «Z»);
words.Add(«И», «I»);
words.Add(«Й», «J»);
words.Add(«К», «K»);
words.Add(«Л», «L»);
words.Add(«М», «M»);
words.Add(«Н», «N»);
words.Add(«О», «O»);
words.Add(«П», «P»);
words.Add(«Р», «R»);
words.Add(«С», «S»);
words.Add(«Т», «T»);
words.Add(«У», «U»);
words.Add(«Ф», «F»);
words.Add(«Х», «H»);
words.Add(«Ц», «C»);
words.Add(«Ч», «Ch»);
words.Add(«Ш», «Sh»);
words.Add(«Щ», «Sch»);
words.Add(«Ъ», «J»);
words.Add(«Ы», «I»);
words.Add(«Ь», «J»);
words.Add(«Э», «E»);
words.Add(«Ю», «Yu»);
words.Add(«Я», «Ya»);
}

private void textBox1_TextChanged(object sender, EventArgs e)
{
string source = textBox1.Text;
foreach (KeyValuePair pair in words)
{
source = source.Replace(pair.Key, pair.Value);
}
textBox2.Text = source;
}
}
}
В итоге мы получили транслитер, который динамически обрабатывает введенный пользователем текст.

 

Работа с Managed DirectX 9 в C# (Csharp)

В этой статье я продемонстрирую вам как создавать с помощью Csharp (C#) приложения Managed DirectX. В последнее время, где речь заходит о Managed DirectX, упоминается книга Том Миллер «Managed DirectX 9», прочитав которую и написав первый пример, я не получил рабочую программу. Эта статья призвана внести ясность и прочитав которую вы сможете написать приложение, которое будет выводить вот такую вот картинку:

Это своеобразное «Hello World!» в мире разработок игр. Для того чтобы создать такое приложение нам понадобится Managed DirectX , который можно скачать на www.microsoft.com.
Приступим к программированию. Запускаем по привычке Visual Studio 2005 и создаем новый проект на Visual C# (Csharp). далее, подключаем в пространства имен Managed DirectX:

using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
Любые действия в Direct3D выполняются спомощью класса устройства. Устройство является первостепенным, относительно всех других графических обьектов в сценарии.
Рассмотрим конструктор устройства:
public Device (System.Int32 adapter, Microsoft.DirectX.Direct3D.DeviceType
devicetype, System.Windows.Forms.Control renderwindow,
Microsoft.DirectX.Direct3D.CreateFlags behaviorFlags,
Microsoft.DirectX.Direct3D.PresentParameters presentationParameters)
adapter относится к физическому устройству, которое мы классифицируем. (нулевое значение классифицирует адаптер по-умолчанию). Опция DeviceType.Reference, позволяет использовать дополнительное или эмулированное устройство растеризации (rasterizer). Параметр renderWindow (окно рендеринга) связывает окно с созданным устройством. behaviorFlags (флажки режимов) используется для управления режимами устройства после его создания. Последний параметр presentationParameters управляет представлением данных на экране.
Зная теперь что нужно для создания адаптера, приступаем к написанию функции, которая будет инициализировать наше графическое устройство:
private Device device = null;

public void InitializeGraphics()
{
try
{
this.SetStyle(ControlStyles.Opaque | ControlStyles.AllPaintingInWmPaint, true);
this.UpdateStyles();
// Устанавливаем параметры презентации
PresentParameters presentParams = new PresentParameters();
presentParams.Windowed = true;
presentParams.SwapEffect = SwapEffect.Discard;
// Создаем устройство
device = new Device(0,DeviceType.Hardware,this,CreateFlags.SoftwareVertexProcessing,presentParams);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Эту функцию следует вставить в метод Main() файла Program.cs:
[STAThread]
static void Main()
{
using (directXform dirX = new directXform())
{
dirX.Show();
dirX.InitializeGraphics();
Application.Run(dirX);
}
}
Это позволит инициализировать графическое устройство при создании формы. Следует сказать, что все действия по перерисовке окна в WinForms производятся в методе OnPaint формы. Потому весь следующий код нужно поместить именно туда:
try
{
device.Clear(ClearFlags.Target, Color.Black, 1.0f, 0);

CustomVertex.TransformedColored[] verts = new CustomVertex.TransformedColored[3];
verts[0].Position = (new Vector4(this.Width/2.0f,50.0f,0.5f,1.0f));
verts[0].Color = System.Drawing.Color.Red.ToArgb();
verts[1].Position = (new Vector4(this.Width-(this.Width/5.0f),this.Height-(this.Height/5.0f),0.5f,1.0f));
verts[1].Color = System.Drawing.Color.Yellow.ToArgb();
verts[2].Position = (new Vector4(this.Width/5.0f,this.Height-(this.Height/5.0f),0.5f,1.0f));
verts[2].Color = System.Drawing.Color.Green.ToArgb();

device.BeginScene();
device.VertexFormat = CustomVertex.TransformedColored.Format;
device.DrawUserPrimitives(PrimitiveType.TriangleList, 1, verts);
device.EndScene();
device.Present();
this.Invalidate();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
Рассмотрим этот код более подробно, чтобы стало понятнее.
device.Clear(ClearFlags.Target, Color.Black, 1.0f, 0); — очищает окно черным цветом. Первый параметр — определяет что мы хотим очистить, второй параметр — цвет, которым нужно заполнить окно.
Так как треугольник является самой простой фигурой, то рассмотрим именно его создание. В Managed DirectX есть конструкции для работы с треугольниками.
CustomVertex.TransformedColored — говорит о том что наш треугольник не требует никаких преобразований цветов. Эта структура указывает также цветовые параметры каждой из вершин.
Каждый элемент массива verts является вершиной нашего треугольника. При создании мы указывали координаты точки, а потом присваивали цвет.
Когда мы определили все вершини треугольника, можно начинать вызывать метод BeginScene.
Далее идет метод DrawUserPrimitives, в качестве параметров которому передается тип отрисовываемого примитива, количество треугольников, и массив вершин.
EndScene сообщает о том что мы закончили рисование.
Present(); — обновляет наше окно. Чтобы не возникало мерцаня при изменениях размеров окна, вызываем метод Invalidate(). Вот и все, наш треугольник отрисован. Если возникли какие-то проблемы с компиляцией, пример работы C# (Csharp) с Managed DirectX 9 всегда можно скачать отсюда.

 

Свой RssReader на C# (Csharp). Работа с RSS (XML)

Уже несколько лет очень популярной технологией является RSS. Почти на каждом сайте мы можем встретить RSS-ленты в которых содержатся новости сайта, статьи, последние топики форумов, и т.д. Для того чтобы написать свою программу чтения RSS сначала нужно прочитать спецификацию RSS. Краткие сведения о RSS можно почитать в моей статье «Создание собственной RSS-ленты».
Если говорить в общих чертах, то RSS представляет собой диалект XML. Обязательными элементами которого являются channel, item, title, description, link, pubDate.
Наша программа будет запрашивать RSS-ленту сайта devoid.com.ua, которая находится здесь и содержит 10 новых статей портала.
Приступим к программированию. Запускаем Visual Studio 2005 и создаем новый проект под названием, скажем RssReader. На форме кнопка (Button) и Веб-браузер (WebBrowser). Форма выглядит примерно так:

Как видно из дизайнера формы, загружать наш RSS-поток мы будем по нажатию кнопки «Загрузить». Все возможные элементы RSS-ленты мы парсить не будем, ограничимся лишь channel, item и img.
Следующим шагом и будет написание классов, которые будут отвечать за отпарсенную информацию из RSS-потока.
Класс, который отвечает за настройки канала (channel) будет выглядеть так:
// Класс который отвечает за настройки канала

public class ChannelClass
{
public string title;
public string description;
public string link;
public string copyright;

public ChannelClass()
{
title = «»;
description = «»;
link = «»;
copyright = «»;
}
}
Как видно класс Канала содержит в себе четыре поля, которые говорят сами за себя. Название канала, Описание канала, ссылка, и копирайт (является необязательным).
Следующим классом который мы создадим будет класс, который будет отвечать за рисунок канала (рисунок является необязательным элементом канала, но в целях получения опыта научимся работать и с ним):
// Класс рисунка канала
public class ImageOfChanel
{
public string imgTitle;
public string imgLink;
public string imgURL;

public ImageOfChanel()
{
imgTitle = «»;
imgLink = «»;
imgURL = «»;
}
}
Класс довольно простой, и содержит в себе 3 обязательных элемента: Название канала, URL-рисунка, и URL-сайта.
Далее пишем класс, который отвечает за элементы канала:
// Класс статей
public class Items
{
public string title;
public string link;
public string description;
public string pubDate;

public Items()
{
title = «»;
link = «»;
description = «»;
pubDate = «»;
}
}
Здесь тоже ничего нового мы не увидели, названия говорят всё за себя.
Отметим что основным методом нашего RssReadera будет метод считывания данных из RSS-ленты и заполнение данными соответствующих обьектов классов, которые нужно обьявить перед телом метода:
ImageOfChanel imageChanel = new ImageOfChanel(); // обьект класса рисунка
Items[] articles; // создаем массив элементов item канала
ChannelClass channel = new ChannelClass(); // создаем обьект класса ChannelClass
Для ясности я сначала приведу код метода получения данных, а далее подробно распишу:
bool getNewArticles(string fileSource)
{
try
{
XmlDocument doc = new XmlDocument();
doc.Load(fileSource);

XmlNodeList nodeList;
XmlNode root = doc.DocumentElement;
articles = new Items[root.SelectNodes(«channel/item»).Count];
nodeList = root.ChildNodes;
int count = 0;

foreach (XmlNode chanel in nodeList)
{
foreach (XmlNode chanel_item in chanel)
{
if (chanel_item.Name == «title»)
{
channel.title = chanel_item.InnerText;
}
if (chanel_item.Name == «description»)
{
channel.description = chanel_item.InnerText;
}
if (chanel_item.Name == «copyright»)
{
channel.copyright = chanel_item.InnerText;
}
if (chanel_item.Name == «link»)
{
channel.link = chanel_item.InnerText;
}

if (chanel_item.Name == «img»)
{
XmlNodeList imgList = chanel_item.ChildNodes;
foreach (XmlNode img_item in imgList)
{
if (img_item.Name == «url»)
{
imageChanel.imgURL = img_item.InnerText;
}
if (img_item.Name == «link»)
{
imageChanel.imgLink = img_item.InnerText;
}
if (img_item.Name == «title»)
{
imageChanel.imgTitle = img_item.InnerText;
}
}
}

if (chanel_item.Name == «item»)
{
XmlNodeList itemsList = chanel_item.ChildNodes;
articles[count] = new Items();

foreach (XmlNode item in itemsList)
{
if (item.Name == «title»)
{
articles[count].title = item.InnerText;
}
if (item.Name == «link»)
{
articles[count].link = item.InnerText;
}
if (item.Name == «description»)
{
articles[count].description = item.InnerText;
}
if (item.Name == «pubDate»)
{
articles[count].pubDate = item.InnerText;
}
}
count += 1;
}

}
}
return true;
}
catch (Exception ex)
{
return false;
}
}
Не стоит пугаться столь большого обьема кода, на самом деле он довольно прост. Следует отметить также, что так как RSS является диалектом XML, то и работать мы будем с ним как с XML-документом. Для этого нужно в uses добавить XML:
using System.Xml;
using System.IO;
using System.IO; — тоже добавьте, это нам понадобится позже.
Итак, функция getNewArticles(string fileSource) принимает в качестве параметра ссылку на RSS-поток, и возвращает либо true при успешной работе, либо false при неудачной попытке. Весь код помещен в try…catch для отслеживания исключительных ситуаций.
Далее идем по коду:
XmlDocument doc = new XmlDocument();
doc.Load(fileSource);
Создаем обьект класса doc и загружаем в него наш RSS-поток методом Load(fileSource).
XmlNodeList nodeList;
XmlNode root = doc.DocumentElement;
articles = new Items[root.SelectNodes(«channel/item»).Count];
nodeList = root.ChildNodes;
int count = 0;
Создаем XmlNode root — который будет содержать корневой элемент XML.
Далее получаем количество элементов item в нашем RSS-потоке, используя SelectNodes() и выражение XPath, которое позволяет это сделать.
nodeList получает все элементы channel.
count — используется как индексатор массива articles[].
foreach (XmlNode chanel in nodeList)
{

}
Этим циклом мы проходим по всем элементам cnannel. Обрабатывая название канала, описание, ссылку — этими строками:
foreach (XmlNode chanel_item in chanel)
{
if (chanel_item.Name == «title»)
{
channel.title = chanel_item.InnerText;
}
if (chanel_item.Name == «description»)
{
channel.description = chanel_item.InnerText;
}
if (chanel_item.Name == «copyright»)
{
channel.copyright = chanel_item.InnerText;
}
if (chanel_item.Name == «link»)
{
channel.link = chanel_item.InnerText;
}

Когда мы находим элемент или , который содержит тоже элементы, мы просто запускаем еще один цикл, который обрабатывает их:
if (chanel_item.Name == «img»)
{
XmlNodeList imgList = chanel_item.ChildNodes;
foreach (XmlNode img_item in imgList)
{
if (img_item.Name == «url»)
{
imageChanel.imgURL = img_item.InnerText;
}
if (img_item.Name == «link»)
{
imageChanel.imgLink = img_item.InnerText;
}
if (img_item.Name == «title»)
{
imageChanel.imgTitle = img_item.InnerText;
}
}
}

if (chanel_item.Name == «item»)
{
XmlNodeList itemsList = chanel_item.ChildNodes;
articles[count] = new Items();

foreach (XmlNode item in itemsList)
{
if (item.Name == «title»)
{
articles[count].title = item.InnerText;
}
if (item.Name == «link»)
{
articles[count].link = item.InnerText;
}
if (item.Name == «description»)
{
articles[count].description = item.InnerText;
}
if (item.Name == «pubDate»)
{
articles[count].pubDate = item.InnerText;
}
}
count += 1;
}
После выполнения этой функции, мы имеем обьекты классов, заполненные данными. в imageChanel содержатся все данные о рисунке (если он есть), в channel — все параметры канала, а массив articles — содержит все статьи портала devoid.com.ua (или элементы item в случае парсинга другой RSS-ленты). Для отображения отпарсенных данных нам и пригодится WebBrowser. Все данные из RSS-потока мы сохраним в виде *.html файла, и потом отобразим его. Для этого напишем простую функцию:
bool generateHtml()
{
try
{
using (StreamWriter writer = new StreamWriter(«last_articles.html»))
{
writer.WriteLine(«»);
writer.WriteLine(«»);
writer.WriteLine(«»);
writer.WriteLine(«»);
writer.WriteLine(channel.title);
writer.WriteLine(«»);
writer.WriteLine(«»);
writer.WriteLine(«A{color:#483D8B; text-decoration:none; font:Verdana;}»);
writer.WriteLine(«pre{font-family:courier;color:#000000;»);
writer.WriteLine(«background-color:#dfe2e5;padding-top:5pt;padding-left:5pt;»);
writer.WriteLine(«padding-bottom:5pt;border-top:1pt solid #87A5C3;»);
writer.WriteLine(«border-bottom:1pt solid #87A5C3;border-left:1pt solid #87A5C3;»);
writer.WriteLine(«border-right : 1pt solid #87A5C3; text-align : left;}»);
writer.WriteLine(«»);
writer.WriteLine(«»);
writer.WriteLine(«»);

writer.WriteLine(««);
writer.WriteLine(««);
writer.WriteLine(«
«);
writer.WriteLine(»

» + channel.title + «

«);

writer.WriteLine(«»);
foreach (Items article in articles)
{
writer.WriteLine(«»);
writer.WriteLine(«»);
writer.WriteLine(«»);
}
writer.WriteLine(«

«);
writer.WriteLine(«
» + article.title + ««);
writer.WriteLine(«& (» + article.pubDate + «)

«);
writer.WriteLine(«»);
writer.WriteLine(»

«);
writer.WriteLine(article.description);
writer.WriteLine(«

«);
writer.WriteLine(«
«);
writer.WriteLine(«читать дальше

«);
writer.WriteLine(«


«);

writer.WriteLine(»

«);
writer.WriteLine(«» + channel.copyright + «

«);

writer.WriteLine(««);
writer.WriteLine(«»);
writer.WriteLine(«»);
return true;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
return false;
}
}
Функция не сложная и не требует глубоких пояснений, стоит только отметить что мы создаем StreamWriter, который записывает все данные в файл last_articles.html Теперь осталось лишь добавить обработчик нажатия кнопки, который выглядит вот так:
if (getNewArticles(«http://devoid.com.ua/rss.php») == true && generateHtml() == true)
{
Browser.Navigate(Environment.CurrentDirectory + «\\last_articles.html»);
}
После всего вышесказанного, осталось только нажать F5 и получить новые статьи сайта www.devoid.com.ua.
Стоит заметить также что наш парсер является уникальным, и сможет работать со всеми RSS-лентами стандарта 2.0.

 

Автозапуск программы в C#

Автозапуск программы в C#
В этой статье мы напишем программу, которая будет добавлять себя в автозапуск Windows, с помощью реестра. Для этого нам понадобятся минимальные умения работы с реестром в C# и утилита regedit (Пуск->Выполнить->regedit), которая позволяет просматривать древовидную структуру реестра Windows.
Чтобы программа запускалась при загрузке Windows, необходимо создать ключ реестра в ветке реестра «HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run\» названием ключа будет имя нашей программы, а значением — путь к исполняемому файлу программы.
В C# за работу с реестром отвечает класс Microsoft.Win32.Registry, а за работу с ключами — Microsoft.Win32.RegistryKey. Перед тем как писать код, давайте создадим новый проект и положим на него 2 кнопки «Добавить» (будет создавать ключ в реестре) и «Удалить» (удаляет ключ). В обработчике для кнопки «Добавить» пишем:

Microsoft.Win32.RegistryKey myKey =
Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@»SOFTWARE\Microsoft\Windows\CurrentVersion\Run\», true);
myKey.SetValue(«MyProgram», Application.ExecutablePath);
Теперь нажимаем кнопку «Добавить», запускаем regedit, добираемся до ветки Run и проверяем — если ключ создан, то можем перезагружать компьютер и наша программа запустится при загрузке Windows. Следует отметить что в качестве параметров функции SetValue первым является название ключа. А вот второй параметр — это путь к исполняемому файлу нашей программы.
Часто возникает вопрос «Откуда запущена программа?», ответ довольно прост:
Application.ExecutablePath — возвращает путь и имя исполняемого файла.
Application.StartupPath — возвращает путь к исполняемому файлу.
Вот в качестве второго параметра мы и передаем ExecutablePath, который сохраняет путь и имя нашей программы в реестре.
Для удаления ключа, в обработчике нажатия кнопки, пишем такой несложный код:
Microsoft.Win32.RegistryKey myKey =
Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@»SOFTWARE\Microsoft\Windows\CurrentVersion\Run\», true);
myKey.DeleteValue(«MyProgram»);
Код достаточно прост. Стоит отметить что мы указываем наименование ключа, который нужно удалить из текущей ветки реестра. Опять-таки запускаем regedit и проверяем — ключ удалился. Для того чтобы обновить список ключей в regedit нажимаем F5.
Вот такие несложные строки кода, позволяют программистам добавлять свои программы в автозапуск 🙂
После прочтения этой статьи, вы знаете как сделать автозапуск программы.

 

Поля readonly в C# (Csharp)

Использование константы, как переменной, которая содержит значение, которое нельзя изменить — это то, что C# (Csharp) разделяет с другими языками программирования. Хотя константы не всегда соответствуют всем требованиям. Часто случается так, что переменную нужно получить в результате расчетов, а потом сделать ее «только для чтения». В C# (Csharp) именно для таких случаев предусмотрен тип переменных readonly.
Переменные поля readonly имеют большую гибкость, нежели const, потому что позволяют перед присваиванием производить различные вычисления значения, которое должно быть «только для чтения». Правило использования таких полей говорит, что вы можете присваивать им значение только в конструкторе, и нигде более. Одной из основных особенностей таких полей, является то, что они могут пренадлежать и экземплярам класса, а не быть статическими. Это позволяет получать различные значения полей только для чтения в разных экземплярах классов. Это значит, что в отличие от полей const, если вы хотите сделать поле readonly статическим, то должны явно обьявить его таковым.
В качестве примера можно рассмотреть случай, когда в зависимости от купленной лицензии — меняется функциональная часть программы. При более дорогой лицензии — программа позволяет работать с большим количеством документов (если у нас MDI-приложение). Тогда в конструкторе мы определяем по какой лицензии работает пользователь, и в зависимости от ее типа, присваиваем обявленной переменной, с типом readonly, значение количества допустимых документов.
В описанном выше примере, примерный код будет выглядеть так:

public class MdiEditor
{
public static readonly uint MaxDocuments;
static MdiEditor()
{
MaxDocuments = CheckMaxNumDocs();
}
}
В данном конкретном примере, мы обьявляем нашу переменную как статическую, и используем ее в экземпляре класса при каждом запуске программы. Функция CheckMaxNumDocs какраз должна проверить тип лицензии по которой работает пользователь, и венрнуть количество максимально допустимых документов, с которыми может работать пользователь с данной лицензией.
Полями readonly могут быть обьявлены различные типы данных, в подтверждение этому покажу и такой код:
public class NextSample
{
public readonly DateTime CurrentDate;
public NextSample()
{
CurrentDate = new DateTime(2008, 2, 6);
}
}
В итоге получаем текущую дату CurrentDate, которую изменить дальше по коду — нельзя.
Поля readonly представляют собой куда более гибкий инструмент, нежели const, потому что это вычисляемое поле. Удачного применения и спасибо за внимание.