html текст
All interests
  • All interests
  • Design
  • Food
  • Gadgets
  • Humor
  • News
  • Photo
  • Travel
  • Video
Click to see the next recommended page
Like it
Don't like
Add to Favorites

Программно выключить/перезагрузить компьютер

Добрый день, сегодняшняя статья будет описывать реализацию класса для выключения или перезагрузки компьютера пользователя. Вы возможно думаете, зачем это нужно. Я вам скажу что в некоторых весьма специфичных моментах нужно, например: после изменения реестра перезагрузить машину, все надо будет сделать это показать сообщение пользователю и по результату ответа, вызвать или не вызвать метод который мы напишем сегодня чуть позже.

Кстати, выполнить эту задачу на C# можно несколькими способами:
  • С помощью WinAPI.
  • WMI -  инструментарий управления Windows. Кто не знает, вам сюда (рассматривать в данной статье не буду).
  • CMD команда.
Я опущу начала о том что надо создать проект типа "Библиотека классов".

WinAPI

Для начала рассмотрим самый объемный вариант - WinAPI.
В наш класс добавим API функции:
//импортируем API функцию InitiateSystemShutdown
        [DllImport("advapi32.dll", EntryPoint = "InitiateSystemShutdownEx")]
        static extern int InitiateSystemShutdown(string lpMachineName, string lpMessage, int dwTimeout, bool bForceAppsClosed, bool bRebootAfterShutdown);
        //импортируем API функцию AdjustTokenPrivileges
        [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
        internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall,
        ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen);
        //импортируем API функцию GetCurrentProcess
        [DllImport("kernel32.dll", ExactSpelling = true)]
        internal static extern IntPtr GetCurrentProcess();
        //импортируем API функцию OpenProcessToken
        [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
        internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok);
        //импортируем API функцию LookupPrivilegeValue
        [DllImport("advapi32.dll", SetLastError = true)]
        internal static extern bool LookupPrivilegeValue(string host, string name, ref long pluid);
        //импортируем API функцию LockWorkStation
        [DllImport("user32.dll", EntryPoint = "LockWorkStation")]
        static extern bool LockWorkStation();
Теперь инициализируем константы для работы API функций в соответствии с MSDN
internal const int SE_PRIVILEGE_ENABLED = 0x00000002;
internal const int TOKEN_QUERY = 0x00000008;
internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
internal const string SE_SHUTDOWN_NAME = "SeShutdownPrivilege";
ОК, все что нужно у нас есть, хотя не хватает одной мелочи - функции повышения привилегий нашего процесса. Давайте ее напишем, но сначала объявим для нее структуру:
[StructLayout(LayoutKind.Sequential, Pack = 1)]
        internal struct TokPriv1Luid
        {
            public int Count;
            public long Luid;
            public int Attr;
        }
Ну и сама функция:
private static void SetPriv()
        {
            TokPriv1Luid tkp; //экземпляр структуры TokPriv1Luid 
            IntPtr htok = IntPtr.Zero;
            //открываем "интерфейс" доступа для своего процесса
            if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok))
            {
                //заполняем поля структуры
                tkp.Count = 1;
                tkp.Attr = SE_PRIVILEGE_ENABLED;
                tkp.Luid = 0;
                //получаем системный идентификатор необходимой нам привилегии
                LookupPrivilegeValue(null, SE_SHUTDOWN_NAME, ref tkp.Luid);
                //повышем привилигеию своему процессу
                AdjustTokenPrivileges(htok, false, ref tkp, 0, IntPtr.Zero, IntPtr.Zero);
            }
        }
Тут много чего не понятного, немного поясню. Этот метод нужен для того чтобы гарантировать выполнения команды включения/выключения. Без нее, может просто ничего не произойти. Для управления конкретными привилегиями в WinAPI существует специальная структура TokPriv1Luid. Заполняя ее поля так:
tkp.Count = 1;
                tkp.Attr = SE_PRIVILEGE_ENABLED;
                tkp.Luid = 0;
Мы указываем на необходимость ВКЛЮЧЕНИЯ привелегии. Какой именно, в данном случае не указывается. Но перед тем как управлять привилегиями процесса, необходимо получить особый указатель на процесс - IntPtr.
В данной строчке мы получаем указатель на наш процесс:
OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok)
Привилегии в системе могут быть самые разнообразные, на нужна одна - позволяющая производить перезагрузку/выключение, ее имя - SeShutdownPrivilege (подробнее о всех привилегиях можно почитать в MSDN). Для того, что бы получить возможность работать с этой привилегией - нужно получить ее идентификатор:
LookupPrivilegeValue(null, SE_SHUTDOWN_NAME, ref tkp.Luid);
Ну и на конец, когда мы заполнили структуру "выключателя", получили идентификатор привилегии - применям все это к уже известному идентификатору процесса:
AdjustTokenPrivileges(htok, false, ref tkp, 0, IntPtr.Zero, IntPtr.Zero);
Ну вот почти все, почти перезагрузились. Добавьте этот простой код:
//публичный метод для перезагрузки/выключения машины
        public static int halt(bool RSh, bool Force)
        {
            SetPriv(); //получаем привилегия
            //вызываем функцию InitiateSystemShutdown, передавая ей необходимые параметры
            return InitiateSystemShutdown(null, null, 0, Force, RSh);
        }
        //публичный метод для блокировки операционной системы
        public static int Lock()
        {
            if (LockWorkStation())
                return 1;
            else
                return 0;
        }
Собственно класс имеет два метода: halt() - для выключения/перезагрузки, и не большим бонусом Lock() - для блокировки ОС (но не выходу из системы!)
Для использования:
halt(true, false) //мягкая перезагрузка
halt(true, true) //жесткая перезагрузка
halt(false, false) //мягкое выключение
halt(false, true) //жесткое выключение
Lock() //блокировка ОС
Ну вот и все с первым способом разобрались :). Готовую библиотеку реализующую данный метод можно скачать на этой странице под названием AReboot. Поехали дальше...

CMD команда:

Это вариант на любителя, по объему работы он гораздо меньше, давай те я покажу как выключить машину:
System.Diagnostics.Process p = new System.Diagnostics.Process();
              p.StartInfo.FileName = "cmd.exe";
              p.StartInfo.Arguments = "/c shutdown -s -t 00";
             p.Start();
Перезагрузка:
System.Diagnostics.Process p = new System.Diagnostics.Process();
              p.StartInfo.FileName = "cmd.exe";
              p.StartInfo.Arguments = "/c reboot-s -t 00";
             p.Start();
Вот и все :) Используйте тот метод который вам больше нравиться, и отвечает вашей идеологии. Существует еще много способов выполнить поставленную задачу, те что были озвучены - основные. Пробуйте, экспериментируйте, успехов вам.

P.S. Озвученный тут метод с WMI я опишу будущей статье, когда будет время. 
Читать дальше
Twitter
Одноклассники
Мой Мир

материал с i-am-a-kernel.blogspot.ru

2

      Add

      You can create thematic collections and keep, for instance, all recipes in one place so you will never lose them.

      No images found
      Previous Next 0 / 0
      500
      • Advertisement
      • Animals
      • Architecture
      • Art
      • Auto
      • Aviation
      • Books
      • Cartoons
      • Celebrities
      • Children
      • Culture
      • Design
      • Economics
      • Education
      • Entertainment
      • Fashion
      • Fitness
      • Food
      • Gadgets
      • Games
      • Health
      • History
      • Hobby
      • Humor
      • Interior
      • Moto
      • Movies
      • Music
      • Nature
      • News
      • Photo
      • Pictures
      • Politics
      • Psychology
      • Science
      • Society
      • Sport
      • Technology
      • Travel
      • Video
      • Weapons
      • Web
      • Work
        Submit
        Valid formats are JPG, PNG, GIF.
        Not more than 5 Мb, please.
        30
        surfingbird.ru/site/
        RSS format guidelines
        500
        • Advertisement
        • Animals
        • Architecture
        • Art
        • Auto
        • Aviation
        • Books
        • Cartoons
        • Celebrities
        • Children
        • Culture
        • Design
        • Economics
        • Education
        • Entertainment
        • Fashion
        • Fitness
        • Food
        • Gadgets
        • Games
        • Health
        • History
        • Hobby
        • Humor
        • Interior
        • Moto
        • Movies
        • Music
        • Nature
        • News
        • Photo
        • Pictures
        • Politics
        • Psychology
        • Science
        • Society
        • Sport
        • Technology
        • Travel
        • Video
        • Weapons
        • Web
        • Work

          Submit

          Thank you! Wait for moderation.

          Тебе это не нравится?

          You can block the domain, tag, user or channel, and we'll stop recommend it to you. You can always unblock them in your settings.

          • mister_arti
          • домен blogspot.ru
          • домен i-am-a-kernel.blogspot.ru

          Get a link

          Спасибо, твоя жалоба принята.

          Log on to Surfingbird

          Recover
          Sign up

          or

          Welcome to Surfingbird.com!

          You'll find thousands of interesting pages, photos, and videos inside.
          Join!

          • Personal
            recommendations

          • Stash
            interesting and useful stuff

          • Anywhere,
            anytime

          Do we already know you? Login or restore the password.

          Close

          Add to collection

             

            Facebook

            Ваш профиль на рассмотрении, обновите страницу через несколько секунд

            Facebook

            К сожалению, вы не попадаете под условия акции