Учебное пособие 800564
.pdfЗадание 1. Разработать консольное приложение для получения системной информации о памяти, используемой процессом.
Пример выполнения задания
Листинг программы: using System;
using System.Collections.Generic; using System.Linq;
using System.Text; using System.Diagnostics;
namespace ConsoleApplicationMemory2
{
class Program
{
static void Main(string[] args)
{
Process proc = Process.GetCurrentProcess(); Console.WriteLine("Process Info: " + Environment.NewLine + "Private Memory Size: {0:N0}" + Environment.NewLine + "Virtual Memory Size: {1:N0}" + Environment.NewLine + "Working Set Size: {2:N0}" + Environment.NewLine + "Paged Memory Size: {3:N0}" + Environment.NewLine +
"Paged System Memory Size: {4:N0}" + Environment.NewLine + "Non-paged System Memory Size: {5:N0}" + Environment.NewLine,
proc.PrivateMemorySize64,
proc.VirtualMemorySize64,
proc.WorkingSet64,
proc.PagedMemorySize64,
proc.PagedSystemMemorySize64,
proc.NonpagedSystemMemorySize64);
Console.ReadKey();
}
}
}
121
Экранная форма результата работы программы представлена на рис. 67.
Рис. 67. Экранная форма с информацией о памяти процесса
Задание 2. Создать приложение, которое будет записывать в проецируемый в память файл строку и спустя некоторое время считывать ее оттуда.
Это пример работы с проекцией файла в рамках одного приложения.
Пример выполнения задания
Листинг программы: using System;
using System.Collections.Generic; using System.ComponentModel; using System.Data;
using System.Drawing; using System.Linq; using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices; //
122
namespace VirtualPamiat2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
[Flags]
internal enum FileMapProtection : uint
{
PageReadonly = 0x02,
PageReadWrite = 0x04,
PageWriteCopy = 0x08,
PageExecuteRead = 0x20, PageExecuteReadWrite = 0x40, SectionCommit = 0x8000000, SectionImage = 0x1000000, SectionNoCache = 0x10000000, SectionReserve = 0x4000000,
}
[Flags]
internal enum FileMapAccess : uint
{
FileMapCopy = 0x0001,
FileMapWrite = 0x0002,
FileMapRead = 0x0004, FileMapAllAccess = 0x001f, FileMapExecute = 0x0020,
}
internal const int INVALID_HANDLE_VALUE = -1; internal const uint BUF_SIZE = 256;
internal const int ERROR_ALREADY_EXISTS = 183;
// Use DllImport to import the Win32 MessageBox function.
123
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern IntPtr CreateFileMapping(IntPtr hFile, IntPtr lpAttributes, FileMapProtection flProtect, uint dwMaximumSizeHigh, uint dwMaximumSizeLow, String lpName);
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
internal static extern IntPtr MapViewOfFile(IntPtr hFileMappingObject, FileMapAccess dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow, uint dwNumberOfBytesToMap);
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
internal static extern Boolean UnmapViewOfFile(IntPtr lpBaseAddress);
[DllImport("kernel32.dll", CharSet =
CharSet.Unicode)]
internal static extern Boolean
CloseHandle(IntPtr hHandle);
IntPtr hFileMapObj;
IntPtr lpBaseAddress;
private void button1_Click(object sender, EventArgs e)
{
hFileMapObj = CreateFileMapping((IntPtr)INVALID_HANDLE_VALUE, IntPtr.Zero, FileMapProtection.PageReadWrite, 0, 4, "FileMemory");
lpBaseAddress = MapViewOfFile(hFileMapObj, FileMapAccess.FileMapAllAccess, 0, 0, 0);
Marshal.WriteInt32(lpBaseAddress,
Convert.ToInt32(textBox1.Text));
timer1.Start(); listBox1.Items.Add("Выполняется");
124
}
private void timer1_Tick(object sender, EventArgs e)
{
timer1.Stop();
}
private void button2_Click(object sender, EventArgs e)
{
listBox1.Items.Add(Convert.ToString(Marshal.ReadInt32(
lpBaseAddress)));
}
private void button3_Click(object sender, EventArgs e)
{
Environment.Exit(1);
}
}
}
Экранная форма результата работы программы представлена на рис. 68.
125
Рис. 68. Экранная форма работы с проекцией файла в рамках одного приложения
Задание 3. Составить постановку задачи и разработать две программы, одна из которых записывает информацию в проецируемый на память файл, а другая считывает из этого файла и отображает пользователю.
Пример выполнения задания
Листинг программы записи в файл:
using System;
using System.Runtime.InteropServices; using System.Windows;
namespace Sem07_SPO_Lab04_1
{
public partial class MainWindow : Window
126
{
// Определение констант для режима открытия
файла
uint FILE_MAP_ALL_ACCESS = 0xF001F; uint PAGE_READWRITE = 0x04;
IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
IntPtr file;
// Создание файла мэппинга
[DllImport("kernel32.dll", SetLastError =
true)]
static extern IntPtr CreateFileMapping( IntPtr hFile,
IntPtr lpFileMappingAttributes, uint flProtect,
uint dwMaximumSizeHigh, uint dwMaximumSizeLow, string lpName);
// Привязка файла к виртуальной памяти
[DllImport("kernel32.dll", SetLastError =
true)]
static extern IntPtr MapViewOfFile( IntPtr hFileMappingObject, uint dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow,
uint dwNumberOfBytesToMap);
// Отвязка
[DllImport("kernel32.dll", SetLastError =
true)]
static extern int UnmapViewOfFile(IntPtr lpBaseAddress);
public MainWindow() { InitializeComponent();
}
127
private void button1_Click(object sender, RoutedEventArgs e) {
// Создаем файл
file = CreateFileMapping( INVALID_HANDLE_VALUE, IntPtr.Zero, PAGE_READWRITE,
0,
200,
textBox1.Text);
// Если указатель нулевой, то прекращаем работу программы
if (file == IntPtr.Zero)
{
MessageBox.Show("File not created"); return;
}
button2.IsEnabled = true; button1.Content = "Файл создан"; textBox1.IsReadOnly = true; textBox2.IsReadOnly = false;
}
private void button2_Click(object sender, RoutedEventArgs e) {
unsafe
{
int length = textBox2.Text.Length; if (length > 99)
{
MessageBox.Show("> 99 chars"); return;
}
uint bytes = Convert.ToUInt32(length) << 1;
// Записываем последовательность символов
в файл
char* vptr = (char*)MapViewOfFile(
128
file, FILE_MAP_ALL_ACCESS, 0, 0,
bytes).ToPointer();
if (vptr == null)
{
MessageBox.Show("Can not get pointer of
file");
return;
}
for (int i = 0; i < length; i++)
{
vptr[i] = textBox2.Text[i];
}
// Отвязываем файл
UnmapViewOfFile((IntPtr)vptr);
}
}
}
}
Листинг программы, считывающей файл:
using System;
using System.Runtime.InteropServices; using System.Windows;
namespace Sem07_SPO_Lab04_2
{
public partial class MainWindow : Window
{
// Права доступа
uint FILE_MAP_ALL_ACCESS = 0xF001F;
IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
IntPtr file;
129
// Функция открытия файла
[DllImport("kernel32.dll", SetLastError =
true)]
static extern IntPtr OpenFileMapping( uint dwDesiredAccess, int bInheritHandle, string lpName);
// Карта файла
[DllImport("kernel32.dll", SetLastError =
true)]
static extern IntPtr MapViewOfFile( IntPtr hFileMappingObject, uint dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow,
uint dwNumberOfBytesToMap);
// Анмэп файла
[DllImport("kernel32.dll", SetLastError =
true)]
static extern int UnmapViewOfFile(IntPtr lpBaseAddress);
public MainWindow() { InitializeComponent();
}
// Открываем файл для чтения
private void button1_Click(object sender, RoutedEventArgs e) {
file = OpenFileMapping( FILE_MAP_ALL_ACCESS, 0,
textBox1.Text); if (file == IntPtr.Zero)
{
MessageBox.Show("Error! File can not
be opened!");
130