Intro
Прочитав статью «Управляй
компьютером через сотовый!», где web-сервер
был написан на MS VС++, я подумал – а почему бы
не написать то же самое, но с использованием
ASP.NET – самой удобной и функциональной web-технологии
на сегодняшний день (ИМХО, это быстрее и
легче). А чтобы не быть голословным, я покажу
как сделать небольшой пульт управления
твоим компом (чтобы провести аналогии мы
будем реализовывать те же фичи, что и Dinamius в
своей статье), и ты сам все поймешь. Кстати,
чтобы у тебя заработало все нижеописанное у
тебя должен стоять IIS с установленным MS .NET
Framework, и, желательно, MS Mobile Internet Toolkit.
Концепция
Итак, проект у нас будет состоять из трех
файлов: один посылает пользователю меню с
выбором действий (в виде WML1.1 или HTML3.2, в
зависимости от того, какой девайс
использует клиент: будь то мобильник, ПК,
или Palm), а два других реализовывают эти
действия. Код сценариев ASP.NET будет написан
на С#.
Реализация
В начале создадим меню выбора действий (файл
Start.aspx). Здесь ничего программировать не
надо - просто покидаем на страницу нужные
элементы управления. Код этой страницы
приведен ниже:
1:<%@ Page Inherits="System.Web.UI.MobileControls.MobilePage"
Language="C#" %
2:<%@ Register TagPrefix="mobile" Namespace="System.Web.UI.MobileControls"
Assembly="System.Web.Mobile" %
3:<mobile:Form runat="server">
4:Welcome To Remote Control! <br/>
5: <mobile:Link runat="server" NavigateURL="cdControl.aspx?to_do=ejectcd">Open
CD</mobile:Link>
6: <mobile:Link runat="server" NavigateURL="cdControl.aspx?to_do=closecd">Close
CD</mobile:Link>
7: <mobile:Link runat="server" NavigateURL="powerControl.aspx?to_do=off">Shut
Down</mobile:Link>
8: <mobile:Link runat="server" NavigateURL="powerControl.aspx?to_do=reboot">Reboot</mobile:Link>
9: <mobile:Link runat="server" NavigateURL="powerControl.aspx?to_do=logoff">LogOff</mobile:Link>
10:</mobile:Form>
Строчки 1-2 говорят компилятору, что
страница происходит от страницы code-behind System.
Web.UI.MobileControls. MobilePage. Вторая директива
используется для создания префикса
дескриптора mobile с пространством имен
мобильного элемента управления. В строчках
3-10 создается форма, содержащая мобильный
элемент Link (соответствует тегу <a href=…></a>).
Все, остальное среда ASP.NET все сделает сама:
выведет на экран содержимое либо в виде WML,
либо в виде HTML, в зависимости от типа
устройства.
Да, чуть не забыл, код, представленный выше,
будет работать, если у вас установлен MS Mobile
Internet Toolkit, иначе компилятор выдаст нам
ошибку. В этом случае выходом будет
написание кода WML вручную.
Ну а теперь перейдем к реализации файлов
powerControl.aspx и cdControl.aspx. Каждый из них, в
зависимости от входного параметра to_do,
выключит, перезагрузит, либо выйдет из
системы для файла powerControl.aspx, или извлечет
или закроет CD для файла cdControl.aspx .
powerControl.aspx:
<%@ Page Language="C#" %
<%@ import Namespace="System.Runtime.InteropServices" %
<script runat="server">
//описываем константы
public const UInt32 EWX_LOGOFF = 0;
public const UInt32 EWX_SHUTDOWN = 1;
public const UInt32 EWX_REBOOT = 2;
public const UInt32 dwReason = 0;
//импортируем из
библиотеки user32.dll функцию ExitWindowsEx
[DllImport("User32.dll")]
public static extern Boolean ExitWindowsEx(UInt32 flag,UInt32 Reason);
//событие, которое
происходит при загрузке страницы
void Page_Load(object sender, EventArgs e) {
//считываем параметр
to_do
string to_do=Request.QueryString["to_do"];
switch (to_do)
{
case "logoff":
ExitWindowsEx(EWX_LOGOFF,dwReason);
break;
case "off":
ExitWindowsEx(EWX_SHUTDOWN,dwReason);
break;
case "reboot":
ExitWindowsEx(EWX_REBOOT,dwReason);
break;
default:
Response.Redirect("start.aspx");
break;
}
}
</script>
cdControl.aspx:
<%@ Page Language="C#" %
<%@ import Namespace="System.Runtime.InteropServices" %
<script runat="server">
//определяем нужные нам
константы
public const UInt32 INVALID_HANDLE_VALUE = 0xFFFFFFFF;
public const UInt32 OPEN_EXISTING = 3;
public const UInt32 GENERIC_READ = 0x80000000;
public const UInt32 GENERIC_WRITE = 0x40000000;
public const UInt32 IOCTL_STORAGE_EJECT_MEDIA = 2967560;
public const UInt32 IOCTL_STORAGE_LOAD_MEDIA = 2967564;
//импортируем нужные
нам функции WinAPI
[DllImport("kernel32.dll")]
public static extern UInt32 CreateFile(String lpFileName, UInt32 dwDesiredAccess,
UInt32 dwShareMode, IntPtr lpSecurityAttributes, UInt32 dwCreationDisposition,
UInt32 dwFlagsAndAttributes, UInt32 hTemplateFile);
[DllImport("kernel32.dll")]
public static extern Boolean CloseHandle(UInt32 hObject);
[DllImport("kernel32.dll")]
public static extern Boolean DeviceIoControl(UInt32 hDevice, UInt32
dwIoControlCode, IntPtr lpInBuffer, UInt32 nInBufferSize, IntPtr lpOutBuffer,
UInt32 nOutBufferSize, ref UInt32 lpBytesReturned, IntPtr lpOverlapped);
void Page_Load(object sender, EventArgs e) {
string to_do=Request.QueryString["to_do"];
UInt32 hCdRomDrive = CreateFile(@"\\.\E:", GENERIC_READ |
GENERIC_WRITE, 0, IntPtr.Zero, OPEN_EXISTING, 0, 0);
switch (to_do)
{
case "ejectcd":
if (INVALID_HANDLE_VALUE != hCdRomDrive)
{
UInt32 DummyReturnedBytes = 0;
DeviceIoControl(hCdRomDrive, IOCTL_STORAGE_EJECT_MEDIA, IntPtr.Zero, 0,
IntPtr.Zero, 0, ref DummyReturnedBytes, IntPtr.Zero);
CloseHandle(hCdRomDrive);
Response.Redirect("start.aspx");
}
break;
case "closecd":
if (INVALID_HANDLE_VALUE != hCdRomDrive)
{
UInt32 DummyReturnedBytes = 0;
DeviceIoControl(hCdRomDrive, IOCTL_STORAGE_LOAD_MEDIA, IntPtr.Zero, 0,
IntPtr.Zero, 0, ref DummyReturnedBytes, IntPtr.Zero);
CloseHandle(hCdRomDrive);
Response.Redirect("start.aspx");
}
break;
default:
Response.Redirect("start.aspx");
break;
}
}
</script>
Ну вот и все - проект готов к употреблению.
Единственное, чего здесь не хватает – так
это защиты от несанкционированного доступа
– но о ней мы поговорим в следующий раз. А
пока я советую начать учить ASP.NET – в
хозяйстве пригодиться всегда.
Успешного тебе программирования!