Dans le cadre d'une application que je développe, je dois bloquer les touches systèmes (Windows, Atl+Tab, ...) afin d'éviter que l'utilisateur ne contourne l'application.
Actuellement, j'ai essayé plusieurs méthodes, mais aucun succès.
J'avais essayé un code similaire (importé et adapté d'un autre projet en VB6), sans succès, mais dès Mercredi (31), j'essayerai ta suggestion. (J'ai pas de Windows à la maison, que du Linux)
J'ai pris le temps de tester le code.
Il est configuré pour bloquer toutes les touches du clavier, tant que l'appli tourne tu ne peux plus rien faire sur le pc, à priori, même pas ctrl alt suppr. Je dis à priori car sur le clavier mac court, y'a pas de touche suppr et j'ai essayé avec le clavier visuel de W7.
Le hic c'est que je n'arrive pas exécuter en pas à pas dans le projet d'origine, y a un problème de configuration de symbole (ça a pourtant l'air correct), et quand je fais un nouveau projet, le hook ne marche pas....
Ah, ça explique peut être pourquoi j'ai des soucis si le hook ne fonctionne pas ...
Merci pour le complément, je garde l'URL en fichier pour tester au boulot.
j'ai trouvé, enfin j'ai bloquéça marche dans une virtual box sur Mac.
A partir de ce code (la version 2)
J'ai modifié la méthode KeyboardHookProc comme suit
private static int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
{
//indicates if any of underlaing events set e.Handled flag
bool handled = false;
if (nCode >= 0)
{
//read structure KeyboardHookStruct at lParam
KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
//Ligne dépacée pour être valable sur tout le if, y'avait la même dans le if (s_KeyUp != null && que j'ai supprimé
Keys keyData = (Keys)MyKeyboardHookStruct.VirtualKeyCode;
//raise KeyDown
if (s_KeyDown != null && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN))
{
KeyEventArgs e = new KeyEventArgs(keyData);
s_KeyDown.Invoke(null, e);
handled = e.Handled;
}
// raise KeyPress
if (s_KeyPress != null && wParam == WM_KEYDOWN)
{
bool isDownShift = ((GetKeyState(VK_SHIFT) & 0x80) == 0x80 ? true : false);
bool isDownCapslock = (GetKeyState(VK_CAPITAL) != 0 ? true : false);
byte[] keyState = new byte[256];
GetKeyboardState(keyState);
byte[] inBuffer = new byte[2];
if (ToAscii(MyKeyboardHookStruct.VirtualKeyCode,
MyKeyboardHookStruct.ScanCode,
keyState,
inBuffer,
MyKeyboardHookStruct.Flags) == 1)
{
char key = (char)inBuffer[0];
if ((isDownCapslock ^ isDownShift) && Char.IsLetter(key)) key = Char.ToUpper(key);
KeyPressEventArgs e = new KeyPressEventArgs(key);
s_KeyPress.Invoke(null, e);
handled = handled || e.Handled;
}
}
// raise KeyUp
if (s_KeyUp != null && (wParam == WM_KEYUP || wParam == WM_SYSKEYUP))
{
KeyEventArgs e = new KeyEventArgs(keyData);
s_KeyUp.Invoke(null, e);
handled = handled || e.Handled;
}
switch (keyData)
{
case Keys.Escape://esc
handled = GetKeyState(VK_CONTROL) != 0;//si Ctrl est enfoncé
break;
case (Keys)92://Windows? sur mon mac c'est la touche "commande" alors je ne suis pas sûr
handled = true;
break;
case Keys.Tab://tab
//handled = wParam == WM_SYSKEYDOWN;//si Alt est enfoncé, option 1
handled = GetKeyState(VK_MENU) != 0;//opion 2
break;
case Keys.Delete://suppr
handled = wParam == WM_SYSKEYDOWN && GetKeyState(VK_CONTROL) != 0;//si Ctrl et Alt sont enfoncés, j'ai pas la touche suppr sur mon clavier, donc pas testé
break;
}
}
//if event handled in application do not handoff to other listeners
if (handled)
return -1;
//forward to other application
return CallNextHookEx(s_KeyboardHookHandle, nCode, wParam, lParam);
}
J'ai déplacé la définition de keyData pour le rendre global à la boucle if(nCode >= 0), j'ai mis un commentaire, et ajouté un swicth à la fin du if.
J'ai tenter d'essayer ce que tu proposes, mais pour le moment, les essais de téléchargement de la source me retourne systématiquement une page d'erreur.
Je retenterai un peu plus tard.
Merci, après quelques essais, j'ai enfin compris ce qui posait problème ...
Quand un site est pas très bien conçu, il regarde le referer pour voir quel fichier il faut télécharger et si tu as configuré ton navigateur pour ne jamais envoyé le Referer (vie privée, traçage & co), ben forcément, ça fonctionne moins bien ...
Finalement, j'ai dl le zip, je vais regarder comment faire.
Cela permet d'avoir les modificateurs(Ctrl, Alt, Shift) sur le KeyDown (je n'ai pas fais les autres car je n'en ai pas besoin).
Afin d'intercepter les Alt+F4, ...
J'ai modifié la gestion de l'event KeyDown de TestFormStatic :
private void HookManager_KeyDown(object sender, KeyEventArgs e)
{
switch (e.KeyCode)
{
case Keys.RWin:
case Keys.LWin:
case Keys.Apps:
e.Handled = true;
break;
case Keys.F4:
if ((e.Modifiers & Keys.Alt) != 0)
e.Handled = true;
break;
case Keys.Delete:
if ((e.Modifiers & (Keys.Alt | Keys.Control)) != 0)
e.Handled = true;
break;
}
textBoxLog.AppendText(string.Format("KeyDown - {0} - {1} - {2}\n", e.KeyCode, e.Modifiers, e.Handled));
textBoxLog.ScrollToCaret();
}
Et pour info, le Ctlr+Alt+Del passe quand même, il n'est pas bloquable (mais on le voit passer).
Je vais mettre tout ça dans mon projet final et je test le tout.
Maintenant, j'ai une erreur 1404 lors de la libération du hook (dans ForceUnsunscribeFromGlobalKeyboardEvents), mais cela ne pose pas trop de souci à Windows, donc, j'ignore cette erreur pour le moment.
23 mai 2017 à 19:48
23 mai 2017 à 19:55
23 mai 2017 à 20:29