Создание Windows-приложений на основе Visual C#

         

Завершение работы Windows, перезагрузка, выход пользователя из системы


Использование функций WinAPI позволяет добавлять в свои приложения даже такую функциональность, как завершение работы системы и ее перезагрузка. Создайте новое Windows- приложение и назовите его StartTurnOff. Добавляем на форму пять кнопок и устанавливаем следующие значения формы и кнопок:

Form1, форма, свойствоЗначение
BackgroundImage
Code\Glava5\StartTurnOff\Image\Window.bmp
FormBorderStyleNone
Size314; 400
StartPositionCenterScreen
Button1, свойствоЗначение
NameBtnCancel
Location243; 169
Size61; 19
TextОтмена
Button2, свойствоЗначение
NamebtnCancel2
Location245; 369
Size61; 19
TextОтмена
Button3, свойствоЗначение
NameBtnTurnOff
Image
Code\Glava5\StartTurnOff\Image\TurnOff.bmp
Location140; 80
Size34; 34
Text
Button4, свойствоЗначение
NameBtnRestart
Image
Code\Glava5\StartTurnOff\Image\Restart.bmp
Location238; 81
Size34; 34
Text
Button5, свойствоЗначение
NameBtnUserOut
Image
Code\Glava5\StartTurnOff\Image\UserOut.bmp
Location198; 280
Size34; 34
Text

Добавляем класс WinAPIClass:

Листинг 5.8.

(html, txt)

В коде формы добавляем обработчики кнопок:

Листинг 5.9.

(html, txt)

При запуске приложения появляется совмещенное окно завершения работы и смены пользователя (рис. 5.6). Кнопки "Выключение", "Перезагрузка" и "Выход" лучше всего проверять, завершив работу со средой Visual Studio .NET.


Рис. 5.6.  Приложение StartTurnOff

На диске, прилагаемом к книге, вы найдете приложение StartTurnOff (Code\Glava5\StartTurnOff).


#endregion // Дополнительные переменные public const int SE_PRIVILEGE_ENABLED = 2; public const string SE_SHUTDOWN_NAME = "SeShutdownPrivilege"; public const int ANYSIZE_ARRAY = 1; public const int TOKEN_QUERY = 8; public const int TOKEN_ADJUST_PRIVILEGES = 32;//0x00000020;

// Структура, используемая для передачи в метод AdjustTokenPrivileges // в качестве необходимой привилегии. [StructLayout(LayoutKind.Sequential, Pack=1)] internal struct TokPriv1Luid { // Количество привилегий в наборе. public int Count; public long Luid; // Тип привилегии. public int Attr; }

/// <summary> /// Возвращение указателя на текущий процесс. /// </summary> /// <returns></returns> [DllImport("kernel32.dll", ExactSpelling=true) ] internal static extern IntPtr GetCurrentProcess(); /// <summary> /// Открывание процесса access token, который содержит информацию о ///безопасности текущего пользователя, /// привязанного к заданному процессу. /// </summary> /// <param name="h">Указатель на процесс.</param> /// <param name="acc">Тип access token.</param> /// <param name="phtok">Указатель на access token.</param> /// <returns></returns> [DllImport("advapi32.dll", ExactSpelling=true) ] internal static extern bool OpenProcessToken( IntPtr h, int acc, ref IntPtr phtok ); /// <summary> /// Возвращение значения переменной в текущей сессии ОС. /// </summary> /// <param name="host">Название системы. Если значение null, ///поиск осуществляется /// в локальной системе.</param> /// <param name="name">Название переменной.</param> /// <param name="pluid">Указатель на значение переменной.</param> /// <returns></returns> [DllImport("advapi32.dll") ] internal static extern bool LookupPrivilegeValue( string host, string name, ref long pluid ); /// <summary> /// Включение указанной привилегии. /// </summary> /// <param name="htok">Указатель на access token</param> /// <param name="disall">Необходимость выключения всех привилегий.</param> /// <param name="newst">Новое значение привилегии. Если предыдущее /// значение установлено в true, /// то это значение не учитывается.</param> /// <param name="len">Размер буфера для следующего значения.</param> /// <param name="prev">Предыдущая привилегия.</param> /// <param name="relen">Указатель на размер полученных привилегий.</param> /// <returns></returns> [DllImport("advapi32.dll", ExactSpelling=true) ] internal static extern bool AdjustTokenPrivileges( IntPtr htok, bool disall, ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen ); } }



Листинг 5.8.

В коде формы добавляем обработчики кнопок:

private void btnCancel_Click(object sender, System.EventArgs e) { this.Close(); }

private void btnUserOut_Click(object sender, System.EventArgs e) { WinAPIClass.ExitWindowsEx((uint)WinAPIClass.ShutdownType.LogOf, "Win Api test"); }

private void btnTurnOff_Click(object sender, System.EventArgs e) { RestartOrShotDown(WinAPIClass.ShutdownType.Shutdown); }

private void btnRestart_Click(object sender, System.EventArgs e) { RestartOrShotDown(WinAPIClass.ShutdownType.Reboot); } void RestartOrShotDown(WinAPIClass.ShutdownType type) { WinAPIClass.TokPriv1Luid tp; IntPtr hproc = WinAPIClass.GetCurrentProcess(); IntPtr hToken = IntPtr.Zero; WinAPIClass.OpenProcessToken( hproc, WinAPIClass.TOKEN_ADJUST_PRIVILEGES | WinAPIClass.TOKEN_QUERY, ref hToken ); tp.Count = 1; tp.Luid = 0; tp.Attr = WinAPIClass.SE_PRIVILEGE_ENABLED; WinAPIClass.LookupPrivilegeValue(null, WinAPIClass.SE_SHUTDOWN_NAME, ref tp.Luid ); WinAPIClass.AdjustTokenPrivileges(hToken, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero ); WinAPIClass.ExitWindowsEx((uint)type, "Win Api test");

}

private void btnCancel2_Click(object sender, System.EventArgs e) { this.Close(); }

Листинг 5.9.

При запуске приложения появляется совмещенное окно завершения работы и смены пользователя (рис. 5.6). Кнопки "Выключение", "Перезагрузка" и "Выход" лучше всего проверять, завершив работу со средой Visual Studio .NET.


Рис. 5.6.  Приложение StartTurnOff

На диске, прилагаемом к книге, вы найдете приложение StartTurnOff (Code\Glava5\StartTurnOff).


Содержание раздела