При выполнении в лабораторной работе упражнения №1 , а именно при выполнении нижеследующего кода: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using Microsoft.Xna.Framework.Graphics;
namespace Application1 { public partial class MainForm : Form { // Объявим поле графического устройства для видимости в методах GraphicsDevice device;
public MainForm() { InitializeComponent();
// Подпишемся на событие Load формы this.Load += new EventHandler(MainForm_Load);
// Попишемся на событие FormClosed формы this.FormClosed += new FormClosedEventHandler(MainForm_FormClosed); }
void MainForm_FormClosed(object sender, FormClosedEventArgs e) { // Удаляем (освобождаем) устройство device.Dispose(); // На всякий случай присваиваем ссылке на устройство значение null device = null; }
void MainForm_Load(object sender, EventArgs e) { // Создаем объект представления для настройки графического устройства PresentationParameters presentParams = new PresentationParameters(); // Настраиваем объект представления через его свойства presentParams.IsFullScreen = false; // Включаем оконный режим presentParams.BackBufferCount = 1; // Включаем задний буфер // для двойной буферизации // Переключение переднего и заднего буферов // должно осуществляться с максимальной эффективностью presentParams.SwapEffect = SwapEffect.Discard; // Устанавливаем размеры заднего буфера по клиентской области окна формы presentParams.BackBufferWidth = this.ClientSize.Width; presentParams.BackBufferHeight = this.ClientSize.Height;
// Создадим графическое устройство с заданными настройками device = new GraphicsDevice(GraphicsAdapter.DefaultAdapter, DeviceType.Hardware, this.Handle, presentParams); }
protected override void OnPaint(PaintEventArgs e) { device.Clear(Microsoft.Xna.Framework.Graphics.Color.CornflowerBlue);
base.OnPaint(e); } } } Выбрасывается исключение: Невозможно загрузить файл или сборку "Microsoft.Xna.Framework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d" или один из зависимых от них компонентов. Не удается найти указанный файл. Делаю все пунктуально. В чем может быть проблема? |
Работа с файлами и каталогами
Упражнение 4. Получение метаданных из сборок
Иногда может возникнуть необходимость получить дополнительную информацию о файле, включающую в себя авторские права, номер версии, наименование компании-производителя, информацию о торговой марке и т.д. Эта информация вшивается в сборку при компиляции EXE - или DLL -файлов (если укажем). Данные отображаются в диалоговом окне свойств, вызванном в Windows Explorer при выделении исполнимого файла правой кнопкой мыши и выбора опции Свойства, например
Информация о сборке на этапе проектирования размещается в файле AssemblyInfo.cs, который автоматически создается оболочкой в новом проекте в каталоге Properties. Метаданные можно редактировать через этот файл. Такая необходимость чаще всего возникает в том случае, если программа (сборка или библиотека) делается для продажи или передачи другим людям.
- Добавьте к решению командой File/Add/New Project новый проект консольного приложения с именем App4 и назначьте его стартовым
- В панели Solution Explorer откройте на редактирование файл AssemblyInfo.cs и ознакомьтесь с его содержимым, автоматически сгенерированным оболочкой
using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("App4")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("App4")] [assembly: AssemblyCopyright("Copyright © 2010")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("749a9e12-8b91-41d5-942a-e174fe60800f")] // Version information for an assembly consists of the following four values: // // Major Version // Minor Version // Build Number // Revision // // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")]
Мы видим набор атрибутов в глобальном пространстве имен, определяющих для сборки дополнительную информацию, которую называют метаданными (данные о данных). Ее можно редактировать в файле AssemblyInfo.cs напрямую, но лучше это делать через страницу свойств проекта.
- Выполните команду Project/App4 Properties меню оболочки и выделите вкладку Application страницы свойств проекта
- Щелкните на кнопке Assembly Information, чтобы вызвать диалоговое окно редактирования метаданных сборки с текстовыми полями:
- Заполните диалоговое окно свойств как показано на рисунке
- Вновь откройте файл AssemblyInfo.cs и убедитесь, что его содержимое изменилось
Извлечь информацию из сборки можно программно. Для этого предназначен класс System.Diagnostics. FileVersionInfo. Продемонстрируем его использование на примере.
- Заполните файл Program.cs приложения App4 следующим кодом
using System; using System.Collections.Generic; using System.Text; using System.IO; using DEBUG = System.Diagnostics.Debug; // Псевдоним класса using SD = System.Diagnostics; // Создаем alias пространства имен (необязательно!) using System.Diagnostics; // Подключаем пространство имен напрямую namespace App4 { class Program { static void Main(string[] args) { // Локальные (стековые) переменные инициализировать обязательно String currentDirectory = Directory.GetCurrentDirectory(); // Каталог сборки DirectoryInfo directory = new DirectoryInfo(currentDirectory); FileInfo[] files = directory.GetFiles("*.exe"); // Список файлов по шаблону // Создаем массив для информации обо всех файлах SD.FileVersionInfo[] info = new System.Diagnostics.FileVersionInfo[files.Length]; // Извлекаем из всех файлов дополнительную информацию for (int i = 0; i < files.Length; i++) { info[i] = FileVersionInfo.GetVersionInfo(files[i].FullName);// Просто 'Name' мало! } // Накапливаем результат для печати String message = String.Empty; for (int i = 0; i < info.Length; i++) { // Используем отражение для сокращения кода (и куража!) System.Reflection.PropertyInfo[] props = // Общедоступные свойства info[i].GetType().GetProperties(); for (int j = 0; j < props.Length; j++) { message += props[j].Name + ":\t"; // Имя свойства, ':' и отступ // Выполняем свойство, чтобы извлечь его значение Object prop = props[j].GetGetMethod().Invoke(info[i], null); if (prop is String) // Динамическая идентификация типа (необязательно) message += prop.ToString(); else if (prop != null) message += String.Format("{0}", prop); message += Environment.NewLine; // Новая строка } message += "\r\n"; // Новая строка } Console.Write(message + "\n"); // Печатаем на консоль (Write и новая строка) DEBUG.WriteLine(message); // Печатаем в панель Output оболочки Console.ReadLine(); // Задержка консоли } } }
В приведенном коде мы применили методику отражения типов ( Reflection - рефлексию), чтобы не перебирать все свойства явно. Кроме того, использовали разные способы новой строки, для разнообразия.
- Запустите приложение - вывод информации для файлов каталога исполнимой сборки данного проекта будет таким
Comments: Читает метаданные (Description) CompanyName: Рога и копыта (Company) FileBuildPart: 0 FileDescription: Приложение App4 (Title) FileMajorPart: 1 FileMinorPart: 0 FileName: E:\Tmp\FilesAndDirectory\App4\bin\Debug\App4.exe FilePrivatePart: 5678 FileVersion: 1.0.0.5678 InternalName: App4.exe IsDebug: False IsPatched: False IsPrivateBuild: False IsPreRelease: False IsSpecialBuild: False Language: Независимо от языка LegalCopyright: Copyright © 2010 (Copyright) LegalTrademarks: Ни-Бэ-Ни-Мэ (Trademark) OriginalFilename: App4.exe PrivateBuild: ProductBuildPart: 0 ProductMajorPart: 1 ProductMinorPart: 0 ProductName: Суперприложение (Product) ProductPrivatePart: 5678 ProductVersion: 1.0.0.5678 SpecialBuild: Comments: vshost.exe CompanyName: Microsoft Corporation FileBuildPart: 21022 FileDescription: vshost.exe FileMajorPart: 9 FileMinorPart: 0 FileName: E:\Tmp\FilesAndDirectory\App4\bin\Debug\App4.vshost.exe FilePrivatePart: 8 FileVersion: 9.0.21022.8 InternalName: vshost.exe IsDebug: False IsPatched: False IsPrivateBuild: False IsPreRelease: False IsSpecialBuild: False Language: Независимо от языка LegalCopyright: © Microsoft Corporation. All rights reserved. LegalTrademarks: OriginalFilename: vshost.exe PrivateBuild: ProductBuildPart: 21022 ProductMajorPart: 9 ProductMinorPart: 0 ProductName: Microsoft (R) Visual Studio (R) 2008 ProductPrivatePart: 8 ProductVersion: 9.0.21022.8 SpecialBuild:
Здесь, на первый взгляд, казалось бы, наблюдается парадокс - исполнимая сборка проверяет саму себя! Ну и что, порядок ее создания таков: компилятор транслирует код и записывает его в файл. Затем оболочка загружает файл в память и запускает процесс CLR, который анализирует указанный нами файл на диске в соответствии с заложенным алгоритмом. Указали бы другой исполнимый или библиотечный файл, процесс проверял бы его. Конечно, можно было бы сделать и диалог для выбора файла, но не в этом суть данного упражнения.