Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Отключение ctrl-alt-delete, alt-tab, Пуск и прочих сочетаний

Anna | 17.06.2014 | нет комментариев
Это свободный перевод статьи с сайта tamas.io о программном отключении и включении жгучих клавиш Windows средствами C#. Вовсе незадолго мне самому потребовались сходственные функции в моей программе и я с изумлением нашел, что в рунете ничего об этом нет, да и вообще в сети об этом сказано вовсе немножко. Так что, если увлекательно либо также необходимо, как было мне — благо пожаловать!

Я написал эту статью в 2007 году и она до сих пор ходит по сети и упоминается в разных обсуждениях, включая StackOverflow и DotNetSpider, так что я решил опять опубликовать её. Это было актуально теснее тогда и не было проверено на Windows 7, в силу того, что её на тот момент легко не существовало физически.
Перед тем, как продолжить чтение, умоляю, обратите внимание на то, что эта статья совсем не призывает вас создавать вредные приложения. Вы можете применять приведённый код в целях обучения либо для веселия.

Позже небольшого изыскания по отключению клавиш и их сочетаний я узнал, что есть несколько методов метаморфозы поведения ранее упомянутых ключевых комбо.

Не беспокойтесь, мы не будем рассматривать их тут, но я покажу, как с ними трудиться.

Используем вероятности редактирования реестра C#, Дабы установить / изменить групповую политику для последовательности клавиш CTRL-ALT-DEL. Давайте посмотрим, что дозволено сделать не написав ни строчки кода. Откройте «Пуск -> Исполнить» и наберите gpedig.msc. Перейдите к: Конфигурация пользователя> Административные образцы> Система>Варианты действий позже нажатия CTRL-ALT-DEL (User Configuration > Administrative Templates > System > CTRL ALT DELETE Options). Это то место, где стандартным методом дозволено установить действие, которое будет вызвано нажатием этого комбо. Двукратно щёлкните по «Удалить диспетчер задач» (Remove Task Manager). Метаморфоза этого параметра меняет значение в Software\Microsoft\Windows\CurrentVersion\Policies\System и значение DisableTaskMgr получит значение 1.

Сейчас задача стала яснее.

Значимо, не пропустите эту строку:

using Microsoft.Win32;

Способ, тот, что я написал, выглядит дальнейшим образом:

public void KillCtrlAltDelete()
        {
            RegistryKey regkey;
            string keyValueInt = "1";
            string subKey = @"Software\Microsoft\Windows\CurrentVersion\Policies\System";

            try
            {
                regkey = Registry.CurrentUser.CreateSubKey(subKey);
                regkey.SetValue("DisableTaskMgr", keyValueInt);
                regkey.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

Таким образом, мы позаботились об изменении значения комбинации CTRL-ALT-DEL. Разглядим остальные сочетания. Допустимо, вам могло показаться это трудным, но это проще простого. Как отключить ALT F4? Каждого 5 строк кода:

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            e.Cancel = true;
            base.OnClosing(e);
        }

Отлично. Об остальном пришлось много читать и теперь будет сложно назвать верно те статьи, которые мне помогли разобраться, но из всех было штук 15, которые содержали хоть какую-то пригодную информацию. Я дам вам способ, тот, что именуется хук. Фрагмент кода использует LowLevelKeyboardProc, тот, что:

Процедура LowLevelKeyboardProc — это программно определённая либо библиотечно определённая процедура вызова функции, применяемая коллективно с функцией SetWindowsHookEx. Система вызывает эту функцию всякий раз, когда событие ввода с клавиатуры вот-вот будет помещено в очереди потока ввода. Ввод с клавиатуры может пройти через драйвер либо через вызовы функции keybdevent. Если вызов произошёл через вызов keybdevent, то он был «введён» (injected). Тем не менее, хук WHKEYBOARDLL не внедряется в иной процесс. Взамен этого, контекст переключается на иной процесс, на тот, что установлен хук и вызывается в изначальном виде. После этого, контекст переключается обратно на приложение, которое вызвало это событие.

И вновь, не позабудьте:


using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Diagnostics;

Тут всё остальное, что может ещё вам сгодиться:


[DllImport("user32", EntryPoint = "SetWindowsHookExA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern int SetWindowsHookEx(int idHook, LowLevelKeyboardProcDelegate lpfn, int hMod, int dwThreadId);
        [DllImport("user32", EntryPoint = "UnhookWindowsHookEx", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern int UnhookWindowsHookEx(int hHook);
        public delegate int LowLevelKeyboardProcDelegate(int nCode, int wParam, ref KBDLLHOOKSTRUCT lParam);
        [DllImport("user32", EntryPoint = "CallNextHookEx", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern int CallNextHookEx(int hHook, int nCode, int wParam, ref KBDLLHOOKSTRUCT lParam);
        public const int WH_KEYBOARD_LL = 13;

        /*code needed to disable start menu*/
        [DllImport("user32.dll")]
        private static extern int FindWindow(string className, string windowText);
        [DllImport("user32.dll")]
        private static extern int ShowWindow(int hwnd, int command);

        private const int SW_HIDE = 0;
        private const int SW_SHOW = 1;
public struct KBDLLHOOKSTRUCT
        {
            public int vkCode;
            public int scanCode;
            public int flags;
            public int time;
            public int dwExtraInfo;
        }
        public static int intLLKey;

        public int LowLevelKeyboardProc(int nCode, int wParam, ref KBDLLHOOKSTRUCT lParam)
        {
            bool blnEat = false;

            switch (wParam)
            {
                case 256:
                case 257:
                case 260:
                case 261:
                    //Alt Tab, Alt Esc, Ctrl Esc, Windows Key,
                    blnEat = ((lParam.vkCode == 9) && (lParam.flags == 32)) | ((lParam.vkCode == 27) && (lParam.flags == 32)) | ((lParam.vkCode == 27) && (lParam.flags == 0)) | ((lParam.vkCode == 91) && (lParam.flags == 1)) | ((lParam.vkCode == 92) && (lParam.flags == 1)) | ((lParam.vkCode == 73) && (lParam.flags == 0));
                    break;
            }

            if (blnEat == true)
            {
                return 1;
            }
            else
            {
                return CallNextHookEx(0, nCode, wParam, ref lParam);
            }
        }
public void KillStartMenu()
        {
            int hwnd = FindWindow("Shell_TrayWnd", "");
            ShowWindow(hwnd, SW_HIDE);
        }
private void Form1_Load(object sender, EventArgs e)
        {
            intLLKey = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, System.Runtime.InteropServices.Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0]).ToInt32(), 0);
        }

Абсолютно видимо, что вы можете программно воротить все значения, опять включив все сочетания:


public static void ShowStartMenu()
        {
            int hwnd = FindWindow("Shell_TrayWnd", "");
            ShowWindow(hwnd, SW_SHOW);
        }
public static void EnableCTRLALTDEL()
        {
            try
            {
                string subKey = @"Software\Microsoft\Windows\CurrentVersion\Policies\System";
                RegistryKey rk = Registry.CurrentUser;
                RegistryKey sk1 = rk.OpenSubKey(subKey);
                if (sk1 != null)
                    rk.DeleteSubKeyTree(subKey);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            UnhookWindowsHookEx(intLLKey);
        }

Я верю, вам понравилась статья и вы обнаружили в ней что-то пригодное. Я постарался собрать тут всю информацию, которую только сумел обнаружить по этой теме.

От себя дополню, что в .NET4 код вида:


intLLKey = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, System.Runtime.InteropServices.Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0]).ToInt32(), 0);

Не работает. Необходимо писать что-то типа:


var inst = LoadLibrary("user32.dll").ToInt32();
intLLKey = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, inst, 0);

Ну и в предисловие кода конструкции AddHooks, среди прочего импорта сделать:


LoadLibrary:
[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern IntPtr LoadLibrary(string lpFileName);

Верю, перевод получился не вовсе дрянен и окажется кому — либо пригоден.

 

Источник: programmingmaster.ru

Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB